diff --git a/.devops/intel.Dockerfile b/.devops/intel.Dockerfile index c8839fe027c5a..8cad660523ecc 100644 --- a/.devops/intel.Dockerfile +++ b/.devops/intel.Dockerfile @@ -1,4 +1,4 @@ -ARG ONEAPI_VERSION=2025.0.0-0-devel-ubuntu22.04 +ARG ONEAPI_VERSION=2025.1.1-0-devel-ubuntu24.04 ## Build Image diff --git a/.devops/musa.Dockerfile b/.devops/musa.Dockerfile index e0f1ad9728b09..87ce2393f6bf9 100644 --- a/.devops/musa.Dockerfile +++ b/.devops/musa.Dockerfile @@ -1,10 +1,10 @@ ARG UBUNTU_VERSION=22.04 # This needs to generally match the container host's environment. -ARG MUSA_VERSION=rc3.1.1 +ARG MUSA_VERSION=rc4.0.1 # Target the MUSA build image -ARG BASE_MUSA_DEV_CONTAINER=mthreads/musa:${MUSA_VERSION}-devel-ubuntu${UBUNTU_VERSION} +ARG BASE_MUSA_DEV_CONTAINER=mthreads/musa:${MUSA_VERSION}-mudnn-devel-ubuntu${UBUNTU_VERSION} -ARG BASE_MUSA_RUN_CONTAINER=mthreads/musa:${MUSA_VERSION}-runtime-ubuntu${UBUNTU_VERSION} +ARG BASE_MUSA_RUN_CONTAINER=mthreads/musa:${MUSA_VERSION}-mudnn-runtime-ubuntu${UBUNTU_VERSION} FROM ${BASE_MUSA_DEV_CONTAINER} AS build @@ -21,21 +21,14 @@ RUN apt-get update && \ libcurl4-openssl-dev \ libgomp1 -COPY requirements.txt requirements.txt -COPY requirements requirements - -RUN pip install --upgrade pip setuptools wheel \ - && pip install -r requirements.txt - WORKDIR /app COPY . . -# Use the default MUSA archs if not specified RUN if [ "${MUSA_DOCKER_ARCH}" != "default" ]; then \ export CMAKE_ARGS="-DMUSA_ARCHITECTURES=${MUSA_DOCKER_ARCH}"; \ fi && \ - cmake -B build -DGGML_NATIVE=OFF -DGGML_MUSA=ON -DLLAMA_BUILD_TESTS=OFF -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON ${CMAKE_ARGS} -DCMAKE_EXE_LINKER_FLAGS=-Wl,--allow-shlib-undefined . && \ + cmake -B build -DGGML_NATIVE=OFF -DGGML_MUSA=ON -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON -DLLAMA_BUILD_TESTS=OFF ${CMAKE_ARGS} -DCMAKE_EXE_LINKER_FLAGS=-Wl,--allow-shlib-undefined . && \ cmake --build build --config Release -j$(nproc) RUN mkdir -p /app/lib && \ diff --git a/.editorconfig b/.editorconfig index 1eadda334ae71..c90b171f55676 100644 --- a/.editorconfig +++ b/.editorconfig @@ -48,3 +48,7 @@ end_of_line = unset charset = unset trim_trailing_whitespace = unset insert_final_newline = unset + +[vendor/miniaudio/miniaudio.h] +trim_trailing_whitespace = unset +insert_final_newline = unset diff --git a/.github/workflows/build-linux-cross.yml b/.github/workflows/build-linux-cross.yml index dbd31e589be3e..92dc41f9d729c 100644 --- a/.github/workflows/build-linux-cross.yml +++ b/.github/workflows/build-linux-cross.yml @@ -26,12 +26,12 @@ jobs: sudo apt-get install -y --no-install-recommends \ build-essential \ gcc-14-riscv64-linux-gnu \ - g++-14-riscv64-linux-gnu \ - libcurl4-openssl-dev:riscv64 + g++-14-riscv64-linux-gnu - name: Build run: | - cmake -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -B build -DLLAMA_CURL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ -DGGML_OPENMP=OFF \ -DLLAMA_BUILD_EXAMPLES=ON \ -DLLAMA_BUILD_TOOLS=ON \ @@ -72,12 +72,12 @@ jobs: glslc \ gcc-14-riscv64-linux-gnu \ g++-14-riscv64-linux-gnu \ - libvulkan-dev:riscv64 \ - libcurl4-openssl-dev:riscv64 + libvulkan-dev:riscv64 - name: Build run: | - cmake -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -B build -DLLAMA_CURL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ -DGGML_VULKAN=ON \ -DGGML_OPENMP=OFF \ -DLLAMA_BUILD_EXAMPLES=ON \ @@ -118,12 +118,12 @@ jobs: build-essential \ glslc \ crossbuild-essential-arm64 \ - libvulkan-dev:arm64 \ - libcurl4-openssl-dev:arm64 + libvulkan-dev:arm64 - name: Build run: | - cmake -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -B build -DLLAMA_CURL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ -DGGML_VULKAN=ON \ -DGGML_OPENMP=OFF \ -DLLAMA_BUILD_EXAMPLES=ON \ @@ -163,12 +163,12 @@ jobs: sudo apt-get install -y --no-install-recommends \ build-essential \ gcc-14-powerpc64le-linux-gnu \ - g++-14-powerpc64le-linux-gnu \ - libcurl4-openssl-dev:ppc64el + g++-14-powerpc64le-linux-gnu - name: Build run: | - cmake -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -B build -DLLAMA_CURL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ -DGGML_OPENMP=OFF \ -DLLAMA_BUILD_EXAMPLES=ON \ -DLLAMA_BUILD_TOOLS=ON \ @@ -209,12 +209,12 @@ jobs: glslc \ gcc-14-powerpc64le-linux-gnu \ g++-14-powerpc64le-linux-gnu \ - libvulkan-dev:ppc64el \ - libcurl4-openssl-dev:ppc64el + libvulkan-dev:ppc64el - name: Build run: | - cmake -B build -DCMAKE_BUILD_TYPE=Release \ + cmake -B build -DLLAMA_CURL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ -DGGML_VULKAN=ON \ -DGGML_OPENMP=OFF \ -DLLAMA_BUILD_EXAMPLES=ON \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b62720f308dd7..ee76d1799e6f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -351,7 +351,7 @@ jobs: ubuntu-22-cmake-musa: runs-on: ubuntu-22.04 - container: mthreads/musa:rc3.1.1-devel-ubuntu22.04 + container: mthreads/musa:rc4.0.1-mudnn-devel-ubuntu22.04 steps: - name: Clone @@ -899,7 +899,7 @@ jobs: shell: bash env: - WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/b380d914-366b-4b77-a74a-05e3c38b3514/intel-oneapi-base-toolkit-2025.0.0.882_offline.exe + WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7cd9bba0-7aab-4e30-b3ae-2221006a4a05/intel-oneapi-base-toolkit-2025.1.1.34_offline.exe WINDOWS_DPCPP_MKL: intel.oneapi.win.cpp-dpcpp-common:intel.oneapi.win.mkl.devel:intel.oneapi.win.dnnl:intel.oneapi.win.tbb.devel ONEAPI_ROOT: "C:/Program Files (x86)/Intel/oneAPI" steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 02ff188855d6a..65ed244657e4f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Create Release +name: Release on: workflow_dispatch: # allows manual triggering @@ -227,6 +227,69 @@ jobs: path: llama-${{ steps.tag.outputs.name }}-bin-ubuntu-vulkan-x64.zip name: llama-bin-ubuntu-vulkan-x64.zip + windows-cpu: + runs-on: windows-latest + + strategy: + matrix: + include: + - arch: 'x64' + - arch: 'arm64' + + steps: + - name: Clone + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.16 + with: + key: windows-latest-cmake-cpu-${{ matrix.arch }} + variant: ccache + evict-old-files: 1d + + - name: Install Ninja + run: | + choco install ninja + + - name: libCURL + id: get_libcurl + uses: ./.github/actions/windows-setup-curl + with: + architecture: ${{ matrix.arch == 'x64' && 'win64' || 'win64a' }} + + - name: Build + shell: cmd + env: + CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.arch }} + cmake -S . -B build -G "Ninja Multi-Config" ^ + -D CMAKE_TOOLCHAIN_FILE=cmake/${{ matrix.arch }}-windows-llvm.cmake ^ + -DGGML_NATIVE=OFF ^ + -DGGML_BACKEND_DL=ON ^ + -DGGML_CPU_ALL_VARIANTS=${{ matrix.arch == 'x64' && 'ON' || 'OFF' }} ^ + -DGGML_OPENMP=ON ^ + -DCURL_LIBRARY="%CURL_PATH%/lib/libcurl.dll.a" -DCURL_INCLUDE_DIR="%CURL_PATH%/include" ^ + ${{ env.CMAKE_ARGS }} + cmake --build build --config Release + + - name: Pack artifacts + id: pack_artifacts + env: + CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} + run: | + Copy-Item $env:CURL_PATH\bin\libcurl-${{ matrix.arch }}.dll .\build\bin\Release\ + Copy-Item "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.42.34433\debug_nonredist\${{ matrix.arch }}\Microsoft.VC143.OpenMP.LLVM\libomp140.${{ matrix.arch == 'x64' && 'x86_64' || 'aarch64' }}.dll" .\build\bin\Release\ + 7z a llama-bin-win-cpu-${{ matrix.arch }}.zip .\build\bin\Release\* + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + path: llama-bin-win-cpu-${{ matrix.arch }}.zip + name: llama-bin-win-cpu-${{ matrix.arch }}.zip + windows: runs-on: windows-latest @@ -237,52 +300,30 @@ jobs: strategy: matrix: include: - - build: 'cpu-x64' + - backend: 'vulkan' arch: 'x64' - defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/x64-windows-llvm.cmake -DGGML_NATIVE=OFF -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON -DGGML_OPENMP=OFF' - #- build: 'openblas-x64' - # arch: 'x64' - # defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/x64-windows-llvm.cmake -DGGML_NATIVE=OFF -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON -DGGML_OPENMP=OFF -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS -DBLAS_INCLUDE_DIRS="$env:RUNNER_TEMP/openblas/include" -DBLAS_LIBRARIES="$env:RUNNER_TEMP/openblas/lib/openblas.lib"' - - build: 'vulkan-x64' - arch: 'x64' - defines: '-DGGML_NATIVE=OFF -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON -DGGML_VULKAN=ON' - - build: 'cpu-arm64' - arch: 'arm64' - defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DGGML_NATIVE=OFF' - - build: 'opencl-adreno-arm64' + defines: '-DGGML_VULKAN=ON' + target: 'ggml-vulkan' + - backend: 'opencl-adreno' arch: 'arm64' defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DCMAKE_PREFIX_PATH="$env:RUNNER_TEMP/opencl-arm64-release" -DGGML_OPENCL=ON -DGGML_OPENCL_USE_ADRENO_KERNELS=ON' + target: 'ggml-opencl' steps: - name: Clone id: checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.16 with: - key: windows-latest-cmake-${{ matrix.build }} + key: windows-latest-cmake-${{ matrix.backend }}-${{ matrix.arch }} variant: ccache evict-old-files: 1d - - name: Download OpenBLAS - id: get_openblas - if: ${{ matrix.build == 'openblas-x64' }} - run: | - curl.exe -o $env:RUNNER_TEMP/openblas.zip -L "https://github.com/xianyi/OpenBLAS/releases/download/v${env:OPENBLAS_VERSION}/OpenBLAS-${env:OPENBLAS_VERSION}-x64.zip" - curl.exe -o $env:RUNNER_TEMP/OpenBLAS.LICENSE.txt -L "https://github.com/xianyi/OpenBLAS/raw/v${env:OPENBLAS_VERSION}/LICENSE" - mkdir $env:RUNNER_TEMP/openblas - tar.exe -xvf $env:RUNNER_TEMP/openblas.zip -C $env:RUNNER_TEMP/openblas - $vcdir = $(vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath) - $msvc = $(join-path $vcdir $('VC\Tools\MSVC\'+$(gc -raw $(join-path $vcdir 'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt')).Trim())) - $lib = $(join-path $msvc 'bin\Hostx64\x64\lib.exe') - & $lib /machine:x64 "/def:${env:RUNNER_TEMP}/openblas/lib/libopenblas.def" "/out:${env:RUNNER_TEMP}/openblas/lib/openblas.lib" /name:openblas.dll - - name: Install Vulkan SDK id: get_vulkan - if: ${{ matrix.build == 'vulkan-x64' }} + if: ${{ matrix.backend == 'vulkan' }} run: | curl.exe -o $env:RUNNER_TEMP/VulkanSDK-Installer.exe -L "https://sdk.lunarg.com/sdk/download/${env:VULKAN_VERSION}/windows/VulkanSDK-${env:VULKAN_VERSION}-Installer.exe" & "$env:RUNNER_TEMP\VulkanSDK-Installer.exe" --accept-licenses --default-answer --confirm-command install @@ -296,7 +337,7 @@ jobs: - name: Install OpenCL Headers and Libs id: install_opencl - if: ${{ matrix.build == 'opencl-adreno-arm64' }} + if: ${{ matrix.backend == 'opencl-adreno' && matrix.arch == 'arm64' }} run: | git clone https://github.com/KhronosGroup/OpenCL-Headers cd OpenCL-Headers @@ -314,46 +355,22 @@ jobs: -DCMAKE_INSTALL_PREFIX="$env:RUNNER_TEMP/opencl-arm64-release" cmake --build build-arm64-release --target install --config release - - name: libCURL - id: get_libcurl - uses: ./.github/actions/windows-setup-curl - with: - architecture: ${{ matrix.arch == 'x64' && 'win64' || 'win64a' }} - - name: Build id: cmake_build - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} - run: | - cmake -S . -B build ${{ matrix.defines }} ` - -DCURL_LIBRARY="$env:CURL_PATH/lib/libcurl.dll.a" -DCURL_INCLUDE_DIR="$env:CURL_PATH/include" ` - ${{ env.CMAKE_ARGS }} - cmake --build build --config Release -j ${env:NUMBER_OF_PROCESSORS} - - - name: Add libopenblas.dll - id: add_libopenblas_dll - if: ${{ matrix.build == 'openblas-x64' }} run: | - cp $env:RUNNER_TEMP/openblas/bin/libopenblas.dll ./build/bin/Release/openblas.dll - cp $env:RUNNER_TEMP/OpenBLAS.LICENSE.txt ./build/bin/Release/OpenBLAS-${env:OPENBLAS_VERSION}.txt - - - name: Determine tag name - id: tag - uses: ./.github/actions/get-tag-name + cmake -S . -B build ${{ matrix.defines }} -DGGML_NATIVE=OFF -DGGML_CPU=OFF -DGGML_BACKEND_DL=ON -DLLAMA_CURL=OFF + cmake --build build --config Release --target ${{ matrix.target }} - name: Pack artifacts id: pack_artifacts - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} run: | - Copy-Item $env:CURL_PATH\bin\libcurl-${{ matrix.arch }}.dll .\build\bin\Release\ - 7z a llama-${{ steps.tag.outputs.name }}-bin-win-${{ matrix.build }}.zip .\build\bin\Release\* + 7z a llama-bin-win-${{ matrix.backend }}-${{ matrix.arch }}.zip .\build\bin\Release\${{ matrix.target }}.dll - name: Upload artifacts uses: actions/upload-artifact@v4 with: - path: llama-${{ steps.tag.outputs.name }}-bin-win-${{ matrix.build }}.zip - name: llama-bin-win-${{ matrix.build }}.zip + path: llama-bin-win-${{ matrix.backend }}-${{ matrix.arch }}.zip + name: llama-bin-win-${{ matrix.backend }}-${{ matrix.arch }}.zip windows-cuda: runs-on: windows-2019 @@ -366,8 +383,6 @@ jobs: - name: Clone id: checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Install ccache uses: hendrikmuhs/ccache-action@v1.2.16 @@ -386,45 +401,30 @@ jobs: run: | choco install ninja - - name: libCURL - id: get_libcurl - uses: ./.github/actions/windows-setup-curl - - name: Build id: cmake_build shell: cmd - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" cmake -S . -B build -G "Ninja Multi-Config" ^ - -DGGML_NATIVE=OFF ^ -DGGML_BACKEND_DL=ON ^ - -DGGML_CPU_ALL_VARIANTS=ON ^ + -DGGML_NATIVE=OFF ^ + -DGGML_CPU=OFF ^ -DGGML_CUDA=ON ^ - -DCURL_LIBRARY="%CURL_PATH%/lib/libcurl.dll.a" -DCURL_INCLUDE_DIR="%CURL_PATH%/include" ^ - ${{ env.CMAKE_ARGS }} + -DLLAMA_CURL=OFF set /A NINJA_JOBS=%NUMBER_OF_PROCESSORS%-1 - cmake --build build --config Release -j %NINJA_JOBS% -t ggml - cmake --build build --config Release - - - name: Determine tag name - id: tag - uses: ./.github/actions/get-tag-name + cmake --build build --config Release -j %NINJA_JOBS% --target ggml-cuda - name: Pack artifacts id: pack_artifacts - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} run: | - cp $env:CURL_PATH\bin\libcurl-x64.dll .\build\bin\Release\libcurl-x64.dll - 7z a llama-${{ steps.tag.outputs.name }}-bin-win-cuda${{ matrix.cuda }}-x64.zip .\build\bin\Release\* + 7z a llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip .\build\bin\Release\ggml-cuda.dll - name: Upload artifacts uses: actions/upload-artifact@v4 with: - path: llama-${{ steps.tag.outputs.name }}-bin-win-cuda${{ matrix.cuda }}-x64.zip - name: llama-bin-win-cuda${{ matrix.cuda }}-x64.zip + path: llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip + name: llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip - name: Copy and pack Cuda runtime run: | @@ -432,13 +432,13 @@ jobs: $dst='.\build\bin\cudart\' robocopy "${{env.CUDA_PATH}}\bin" $dst cudart64_*.dll cublas64_*.dll cublasLt64_*.dll robocopy "${{env.CUDA_PATH}}\lib" $dst cudart64_*.dll cublas64_*.dll cublasLt64_*.dll - 7z a cudart-llama-bin-win-cuda${{ matrix.cuda }}-x64.zip $dst\* + 7z a cudart-llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip $dst\* - name: Upload Cuda runtime uses: actions/upload-artifact@v4 with: - path: cudart-llama-bin-win-cuda${{ matrix.cuda }}-x64.zip - name: cudart-llama-bin-win-cuda${{ matrix.cuda }}-x64.zip + path: cudart-llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip + name: cudart-llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip windows-sycl: runs-on: windows-latest @@ -448,15 +448,14 @@ jobs: shell: bash env: - WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/b380d914-366b-4b77-a74a-05e3c38b3514/intel-oneapi-base-toolkit-2025.0.0.882_offline.exe + WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7cd9bba0-7aab-4e30-b3ae-2221006a4a05/intel-oneapi-base-toolkit-2025.1.1.34_offline.exe WINDOWS_DPCPP_MKL: intel.oneapi.win.cpp-dpcpp-common:intel.oneapi.win.mkl.devel:intel.oneapi.win.dnnl:intel.oneapi.win.tbb.devel ONEAPI_ROOT: "C:/Program Files (x86)/Intel/oneAPI" + steps: - name: Clone id: checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: ccache uses: hendrikmuhs/ccache-action@v1.2.16 @@ -469,15 +468,18 @@ jobs: run: | scripts/install-oneapi.bat $WINDOWS_BASEKIT_URL $WINDOWS_DPCPP_MKL - # TODO: add libcurl support ; we will also need to modify win-build-sycl.bat to accept user-specified args - - name: Build id: cmake_build - run: examples/sycl/win-build-sycl.bat - - - name: Determine tag name - id: tag - uses: ./.github/actions/get-tag-name + shell: cmd + run: | + call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 --force + cmake -G "Ninja" -B build ^ + -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=icx ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DGGML_BACKEND_DL=ON -DBUILD_SHARED_LIBS=ON ^ + -DGGML_CPU=OFF -DGGML_SYCL=ON ^ + -DLLAMA_CURL=OFF + cmake --build build --target ggml-sycl -j - name: Build the release package id: pack_artifacts @@ -502,12 +504,12 @@ jobs: cp "${{ env.ONEAPI_ROOT }}/tbb/latest/bin/tbb12.dll" ./build/bin echo "cp oneAPI running time dll files to ./build/bin done" - 7z a llama-${{ steps.tag.outputs.name }}-bin-win-sycl-x64.zip ./build/bin/* + 7z a llama-bin-win-sycl-x64.zip ./build/bin/* - name: Upload the release package uses: actions/upload-artifact@v4 with: - path: llama-${{ steps.tag.outputs.name }}-bin-win-sycl-x64.zip + path: llama-bin-win-sycl-x64.zip name: llama-bin-win-sycl-x64.zip windows-hip: @@ -515,14 +517,14 @@ jobs: strategy: matrix: - gpu_target: [gfx1100, gfx1101, gfx1030] + include: + - name: "radeon" + gpu_targets: "gfx1100;gfx1101;gfx1102;gfx1030;gfx1031;gfx1032" steps: - name: Clone id: checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Clone rocWMMA repository id: clone_rocwmma @@ -532,7 +534,7 @@ jobs: - name: ccache uses: hendrikmuhs/ccache-action@v1.2.16 with: - key: windows-latest-cmake-hip-release + key: windows-latest-cmake-hip-${{ matrix.name }}-x64 evict-old-files: 1d - name: Install @@ -550,50 +552,39 @@ jobs: run: | & 'C:\Program Files\AMD\ROCm\*\bin\clang.exe' --version - - name: libCURL - id: get_libcurl - uses: ./.github/actions/windows-setup-curl - - name: Build id: cmake_build - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} run: | $env:HIP_PATH=$(Resolve-Path 'C:\Program Files\AMD\ROCm\*\bin\clang.exe' | split-path | split-path) $env:CMAKE_PREFIX_PATH="${env:HIP_PATH}" cmake -G "Unix Makefiles" -B build -S . ` -DCMAKE_C_COMPILER="${env:HIP_PATH}\bin\clang.exe" ` -DCMAKE_CXX_COMPILER="${env:HIP_PATH}\bin\clang++.exe" ` - -DCMAKE_CXX_FLAGS="-I$($PWD.Path.Replace('\', '/'))/rocwmma/library/include/" ` + -DCMAKE_CXX_FLAGS="-I$($PWD.Path.Replace('\', '/'))/rocwmma/library/include/ -Wno-ignored-attributes -Wno-nested-anon-types" ` -DCMAKE_BUILD_TYPE=Release ` - -DAMDGPU_TARGETS=${{ matrix.gpu_target }} ` + -DGGML_BACKEND_DL=ON ` + -DGGML_NATIVE=OFF ` + -DGGML_CPU=OFF ` + -DAMDGPU_TARGETS="${{ matrix.gpu_targets }}" ` -DGGML_HIP_ROCWMMA_FATTN=ON ` -DGGML_HIP=ON ` - -DCURL_LIBRARY="$env:CURL_PATH/lib/libcurl.dll.a" -DCURL_INCLUDE_DIR="$env:CURL_PATH/include" ` - ${{ env.CMAKE_ARGS }} - cmake --build build -j ${env:NUMBER_OF_PROCESSORS} + -DLLAMA_CURL=OFF + cmake --build build --target ggml-hip -j ${env:NUMBER_OF_PROCESSORS} md "build\bin\rocblas\library\" cp "${env:HIP_PATH}\bin\hipblas.dll" "build\bin\" cp "${env:HIP_PATH}\bin\rocblas.dll" "build\bin\" cp "${env:HIP_PATH}\bin\rocblas\library\*" "build\bin\rocblas\library\" - - name: Determine tag name - id: tag - uses: ./.github/actions/get-tag-name - - name: Pack artifacts id: pack_artifacts - env: - CURL_PATH: ${{ steps.get_libcurl.outputs.curl_path }} run: | - cp $env:CURL_PATH\bin\libcurl-x64.dll .\build\bin\libcurl-x64.dll - 7z a llama-${{ steps.tag.outputs.name }}-bin-win-hip-x64-${{ matrix.gpu_target }}.zip .\build\bin\* + 7z a llama-bin-win-hip-${{ matrix.name }}-x64.zip .\build\bin\* - name: Upload artifacts uses: actions/upload-artifact@v4 with: - path: llama-${{ steps.tag.outputs.name }}-bin-win-hip-x64-${{ matrix.gpu_target }}.zip - name: llama-bin-win-hip-x64-${{ matrix.gpu_target }}.zip + path: llama-bin-win-hip-${{ matrix.name }}-x64.zip + name: llama-bin-win-hip-${{ matrix.name }}-x64.zip ios-xcode-build: runs-on: macos-latest @@ -655,14 +646,16 @@ jobs: runs-on: ubuntu-latest needs: - - ubuntu-22-cpu - - ubuntu-22-vulkan - windows + - windows-cpu - windows-cuda - windows-sycl - windows-hip + - ubuntu-22-cpu + - ubuntu-22-vulkan - macOS-arm64 - macOS-x64 + - ios-xcode-build steps: - name: Clone @@ -680,10 +673,43 @@ jobs: uses: actions/download-artifact@v4 with: path: ./artifact + merge-multiple: true - name: Move artifacts id: move_artifacts - run: mkdir -p ./artifact/release && mv ./artifact/*/*.zip ./artifact/release + run: | + mkdir -p release + + echo "Adding CPU backend files to existing zips..." + for arch in x64 arm64; do + cpu_zip="artifact/llama-bin-win-cpu-${arch}.zip" + temp_dir=$(mktemp -d) + echo "Extracting CPU backend for $arch..." + unzip "$cpu_zip" -d "$temp_dir" + + echo "Adding CPU files to $arch zips..." + for target_zip in artifact/llama-bin-win-*-${arch}.zip; do + if [[ "$target_zip" == "$cpu_zip" ]]; then + continue + fi + echo "Adding CPU backend to $(basename "$target_zip")" + realpath_target_zip=$(realpath "$target_zip") + (cd "$temp_dir" && zip -r "$realpath_target_zip" .) + done + + rm -rf "$temp_dir" + done + + echo "Renaming and moving zips to release..." + for zip_file in artifact/llama-bin-win-*.zip; do + base_name=$(basename "$zip_file" .zip) + zip_name="llama-${{ steps.tag.outputs.name }}-${base_name#llama-}.zip" + echo "Moving $zip_file to release/$zip_name" + mv "$zip_file" "release/$zip_name" + done + + echo "Moving other artifacts..." + mv -v artifact/*.zip release - name: Create release id: create_release @@ -702,7 +728,7 @@ jobs: const path = require('path'); const fs = require('fs'); const release_id = '${{ steps.create_release.outputs.id }}'; - for (let file of await fs.readdirSync('./artifact/release')) { + for (let file of await fs.readdirSync('./release')) { if (path.extname(file) === '.zip') { console.log('uploadReleaseAsset', file); await github.repos.uploadReleaseAsset({ @@ -710,7 +736,7 @@ jobs: repo: context.repo.repo, release_id: release_id, name: file, - data: await fs.readFileSync(`./artifact/release/${file}`) + data: await fs.readFileSync(`./release/${file}`) }); } } diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml new file mode 100644 index 0000000000000..5c286155951e5 --- /dev/null +++ b/.github/workflows/winget.yml @@ -0,0 +1,42 @@ +name: Update Winget Package + +on: + workflow_dispatch: # allows manual triggering + schedule: + - cron: '28 5 * * *' # Update every day at 5:28 UTC + +jobs: + update: + name: Update Winget Package + runs-on: ubuntu-latest + + steps: + - name: Install cargo binstall + uses: cargo-bins/cargo-binstall@268643a6b5ea099f5718ee5cd3ff7dc89a5eb49b + + - name: Install komac + run: | + cargo binstall komac@2.11.2 -y + + - name: Find latest release + id: find_latest_release + uses: actions/github-script@v6 + with: + script: | + const { data: releases } = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + console.log("Latest release:", releases[0].tag_name); + return releases[0].tag_name; + + - name: Update manifest + env: + VERSION: ${{ steps.find_latest_release.outputs.result }} + run: | + echo "Updating manifest..." + komac update --version ${{ env.VERSION }} \ + --urls "https://github.com/ggml-org/llama.cpp/releases/download/${{ env.VERSION }}/llama-${{ env.VERSION }}-bin-win-vulkan-x64.zip" \ + --token ${{ secrets.WINGET_GITHUB_TOKEN }} \ + --submit \ + ggml.llamacpp diff --git a/.gitignore b/.gitignore index f8ceb1560a1df..6906e660d6914 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,4 @@ poetry.toml # Local scripts /run-vim.sh /run-chat.sh +HEXAGON_Tools/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ac3e9090336d9..323edacff3d10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,20 @@ set(CMAKE_WARN_UNUSED_CLI YES) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +if(CMAKE_SYSTEM_NAME STREQUAL "Android") + if(DEFINED HTP_ARCH_VERSION) + if (${HTP_ARCH_VERSION} STREQUAL "v75" OR ${HTP_ARCH_VERSION} STREQUAL "v79") + #works fine on Snapdragon 8Gen3&8Elite with 1.5x - 3x performance gains with the default ggml backend + set(OPT_FLAG " -O3 -march=armv8.7-a -mcpu=cortex-x1 -mtune=cortex-x1 -ffp-model=fast -fno-finite-math-only") + message("OPT_FLAG:${OPT_FLAG}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") + endif() + endif() +endif() + if (NOT XCODE AND NOT MSVC AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") @@ -120,6 +134,7 @@ llama_option_depr(WARNING LLAMA_RPC GGML_RPC) llama_option_depr(WARNING LLAMA_SYCL GGML_SYCL) llama_option_depr(WARNING LLAMA_SYCL_F16 GGML_SYCL_F16) llama_option_depr(WARNING LLAMA_CANN GGML_CANN) +llama_option_depr(WARNING LLAMA_HEXAGON GGML_HEXAGON) if (NOT MSVC) if (LLAMA_SANITIZE_THREAD) diff --git a/README.md b/README.md index 5472f7abdeb21..540c29a4f1847 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ range of hardware - locally and in the cloud. - Apple silicon is a first-class citizen - optimized via ARM NEON, Accelerate and Metal frameworks - AVX, AVX2, AVX512 and AMX support for x86 architectures - 1.5-bit, 2-bit, 3-bit, 4-bit, 5-bit, 6-bit, and 8-bit integer quantization for faster inference and reduced memory use -- Custom CUDA kernels for running LLMs on NVIDIA GPUs (support for AMD GPUs via HIP and Moore Threads MTT GPUs via MUSA) +- Custom CUDA kernels for running LLMs on NVIDIA GPUs (support for AMD GPUs via HIP and Moore Threads GPUs via MUSA) - Vulkan and SYCL backend support - CPU+GPU hybrid inference to partially accelerate models larger than the total VRAM capacity @@ -237,7 +237,7 @@ Instructions for adding support for new models: [HOWTO-add-model.md](docs/develo | [BLAS](docs/build.md#blas-build) | All | | [BLIS](docs/backend/BLIS.md) | All | | [SYCL](docs/backend/SYCL.md) | Intel and Nvidia GPU | -| [MUSA](docs/build.md#musa) | Moore Threads MTT GPU | +| [MUSA](docs/build.md#musa) | Moore Threads GPU | | [CUDA](docs/build.md#cuda) | Nvidia GPU | | [HIP](docs/build.md#hip) | AMD GPU | | [Vulkan](docs/build.md#vulkan) | GPU | @@ -580,3 +580,4 @@ $ echo "source ~/.llama-completion.bash" >> ~/.bashrc - [minja](https://github.com/google/minja) - Minimal Jinja parser in C++, used by various tools/examples - MIT License - [linenoise.cpp](./tools/run/linenoise.cpp/linenoise.cpp) - C++ library that provides readline-like line editing capabilities, used by `llama-run` - BSD 2-Clause License - [curl](https://curl.se/) - Client-side URL transfer library, used by various tools/examples - [CURL License](https://curl.se/docs/copyright.html) +- [miniaudio.h](https://github.com/mackron/miniaudio) - Single-header audio format decoder, used by multimodal subsystem - Public domain diff --git a/ci/README.md b/ci/README.md index ec3f44350394a..6e297f1a82788 100644 --- a/ci/README.md +++ b/ci/README.md @@ -54,7 +54,7 @@ docker run --privileged -it \ -v $HOME/llama.cpp/ci-cache:/ci-cache \ -v $HOME/llama.cpp/ci-results:/ci-results \ -v $PWD:/ws -w /ws \ - mthreads/musa:rc3.1.1-devel-ubuntu22.04 + mthreads/musa:rc4.0.1-mudnn-devel-ubuntu22.04 ``` Inside the container, execute the following commands: diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a7ff3ac16c446..564af1448f95a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -58,19 +58,20 @@ add_library(${TARGET} STATIC arg.cpp arg.h base64.hpp + chat-parser.cpp + chat-parser.h chat.cpp chat.h common.cpp common.h console.cpp console.h + json-partial.cpp + json-partial.h json-schema-to-grammar.cpp - json.hpp llguidance.cpp log.cpp log.h - minja/chat-template.hpp - minja/minja.hpp ngram-cache.cpp ngram-cache.h regex-partial.cpp @@ -143,7 +144,7 @@ if (LLAMA_LLGUIDANCE) set(LLAMA_COMMON_EXTRA_LIBS ${LLAMA_COMMON_EXTRA_LIBS} llguidance ${LLGUIDANCE_PLATFORM_LIBS}) endif () -target_include_directories(${TARGET} PUBLIC .) +target_include_directories(${TARGET} PUBLIC . ../vendor) target_compile_features (${TARGET} PUBLIC cxx_std_17) target_link_libraries (${TARGET} PRIVATE ${LLAMA_COMMON_EXTRA_LIBS} PUBLIC llama Threads::Threads) diff --git a/common/arg.cpp b/common/arg.cpp index 305168043c27c..cfa9878f90730 100644 --- a/common/arg.cpp +++ b/common/arg.cpp @@ -1,10 +1,11 @@ -#include "gguf.h" // for reading GGUF splits #include "arg.h" +#include "chat.h" #include "common.h" +#include "gguf.h" // for reading GGUF splits +#include "json-schema-to-grammar.h" #include "log.h" #include "sampling.h" -#include "chat.h" // fix problem with std::min and std::max #if defined(_WIN32) @@ -15,6 +16,9 @@ #include #endif +#define JSON_ASSERT GGML_ASSERT +#include + #include #include #include @@ -34,12 +38,10 @@ #include #endif -#include "json-schema-to-grammar.h" - using json = nlohmann::ordered_json; std::initializer_list mmproj_examples = { - LLAMA_EXAMPLE_LLAVA, + LLAMA_EXAMPLE_MTMD, LLAMA_EXAMPLE_SERVER, }; @@ -242,33 +244,7 @@ static bool curl_perform_with_retry(const std::string & url, CURL * curl, int ma } // download one single file from remote URL to local path -static bool common_download_file_single(const std::string & url, const std::string & path, const std::string & bearer_token) { - // Initialize libcurl - curl_ptr curl(curl_easy_init(), &curl_easy_cleanup); - curl_slist_ptr http_headers; - if (!curl) { - LOG_ERR("%s: error initializing libcurl\n", __func__); - return false; - } - - // Set the URL, allow to follow http redirection - curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L); - - http_headers.ptr = curl_slist_append(http_headers.ptr, "User-Agent: llama-cpp"); - // Check if hf-token or bearer-token was specified - if (!bearer_token.empty()) { - std::string auth_header = "Authorization: Bearer " + bearer_token; - http_headers.ptr = curl_slist_append(http_headers.ptr, auth_header.c_str()); - } - curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, http_headers.ptr); - -#if defined(_WIN32) - // CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of - // operating system. Currently implemented under MS-Windows. - curl_easy_setopt(curl.get(), CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); -#endif - +static bool common_download_file_single(const std::string & url, const std::string & path, const std::string & bearer_token, bool offline) { // Check if the file already exists locally auto file_exists = std::filesystem::exists(path); @@ -279,6 +255,10 @@ static bool common_download_file_single(const std::string & url, const std::stri std::string last_modified; if (file_exists) { + if (offline) { + LOG_INF("%s: using cached file (offline mode): %s\n", __func__, path.c_str()); + return true; // skip verification/downloading + } // Try and read the JSON metadata file (note: stream autoclosed upon exiting this block). std::ifstream metadata_in(metadata_path); if (metadata_in.good()) { @@ -297,6 +277,10 @@ static bool common_download_file_single(const std::string & url, const std::stri } // if we cannot open the metadata file, we assume that the downloaded file is not valid (etag and last-modified are left empty, so we will download it again) } else { + if (offline) { + LOG_ERR("%s: required file is not available in cache (offline mode): %s\n", __func__, path.c_str()); + return false; + } LOG_INF("%s: no previous model file found %s\n", __func__, path.c_str()); } @@ -310,50 +294,73 @@ static bool common_download_file_single(const std::string & url, const std::stri bool head_request_ok = false; bool should_download = !file_exists; // by default, we should download if the file does not exist - // get ETag to see if the remote file has changed - { - typedef size_t(*CURLOPT_HEADERFUNCTION_PTR)(char *, size_t, size_t, void *); - auto header_callback = [](char * buffer, size_t /*size*/, size_t n_items, void * userdata) -> size_t { - common_load_model_from_url_headers * headers = (common_load_model_from_url_headers *) userdata; + // Initialize libcurl + curl_ptr curl(curl_easy_init(), &curl_easy_cleanup); + curl_slist_ptr http_headers; + if (!curl) { + LOG_ERR("%s: error initializing libcurl\n", __func__); + return false; + } - static std::regex header_regex("([^:]+): (.*)\r\n"); - static std::regex etag_regex("ETag", std::regex_constants::icase); - static std::regex last_modified_regex("Last-Modified", std::regex_constants::icase); + // Set the URL, allow to follow http redirection + curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L); - std::string header(buffer, n_items); - std::smatch match; - if (std::regex_match(header, match, header_regex)) { - const std::string & key = match[1]; - const std::string & value = match[2]; - if (std::regex_match(key, match, etag_regex)) { - headers->etag = value; - } else if (std::regex_match(key, match, last_modified_regex)) { - headers->last_modified = value; - } - } - return n_items; - }; + http_headers.ptr = curl_slist_append(http_headers.ptr, "User-Agent: llama-cpp"); + // Check if hf-token or bearer-token was specified + if (!bearer_token.empty()) { + std::string auth_header = "Authorization: Bearer " + bearer_token; + http_headers.ptr = curl_slist_append(http_headers.ptr, auth_header.c_str()); + } + curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, http_headers.ptr); - curl_easy_setopt(curl.get(), CURLOPT_NOBODY, 1L); // will trigger the HEAD verb - curl_easy_setopt(curl.get(), CURLOPT_NOPROGRESS, 1L); // hide head request progress - curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION, static_cast(header_callback)); - curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA, &headers); +#if defined(_WIN32) + // CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of + // operating system. Currently implemented under MS-Windows. + curl_easy_setopt(curl.get(), CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); +#endif - // we only allow retrying once for HEAD requests - // this is for the use case of using running offline (no internet), retrying can be annoying - bool was_perform_successful = curl_perform_with_retry(url, curl.get(), 1, 0, "HEAD"); - if (!was_perform_successful) { - head_request_ok = false; - } + typedef size_t(*CURLOPT_HEADERFUNCTION_PTR)(char *, size_t, size_t, void *); + auto header_callback = [](char * buffer, size_t /*size*/, size_t n_items, void * userdata) -> size_t { + common_load_model_from_url_headers * headers = (common_load_model_from_url_headers *) userdata; - long http_code = 0; - curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &http_code); - if (http_code == 200) { - head_request_ok = true; - } else { - LOG_WRN("%s: HEAD invalid http status code received: %ld\n", __func__, http_code); - head_request_ok = false; + static std::regex header_regex("([^:]+): (.*)\r\n"); + static std::regex etag_regex("ETag", std::regex_constants::icase); + static std::regex last_modified_regex("Last-Modified", std::regex_constants::icase); + + std::string header(buffer, n_items); + std::smatch match; + if (std::regex_match(header, match, header_regex)) { + const std::string & key = match[1]; + const std::string & value = match[2]; + if (std::regex_match(key, match, etag_regex)) { + headers->etag = value; + } else if (std::regex_match(key, match, last_modified_regex)) { + headers->last_modified = value; + } } + return n_items; + }; + + curl_easy_setopt(curl.get(), CURLOPT_NOBODY, 1L); // will trigger the HEAD verb + curl_easy_setopt(curl.get(), CURLOPT_NOPROGRESS, 1L); // hide head request progress + curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION, static_cast(header_callback)); + curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA, &headers); + + // we only allow retrying once for HEAD requests + // this is for the use case of using running offline (no internet), retrying can be annoying + bool was_perform_successful = curl_perform_with_retry(url, curl.get(), 1, 0, "HEAD"); + if (!was_perform_successful) { + head_request_ok = false; + } + + long http_code = 0; + curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &http_code); + if (http_code == 200) { + head_request_ok = true; + } else { + LOG_WRN("%s: HEAD invalid http status code received: %ld\n", __func__, http_code); + head_request_ok = false; } // if head_request_ok is false, we don't have the etag or last-modified headers @@ -460,12 +467,12 @@ static bool common_download_file_single(const std::string & url, const std::stri // download multiple files from remote URLs to local paths // the input is a vector of pairs -static bool common_download_file_multiple(const std::vector> & urls, const std::string & bearer_token) { +static bool common_download_file_multiple(const std::vector> & urls, const std::string & bearer_token, bool offline) { // Prepare download in parallel std::vector> futures_download; for (auto const & item : urls) { - futures_download.push_back(std::async(std::launch::async, [bearer_token](const std::pair & it) -> bool { - return common_download_file_single(it.first, it.second, bearer_token); + futures_download.push_back(std::async(std::launch::async, [bearer_token, offline](const std::pair & it) -> bool { + return common_download_file_single(it.first, it.second, bearer_token, offline); }, item)); } @@ -481,14 +488,15 @@ static bool common_download_file_multiple(const std::vector> common_remote_get_content(const std::string & * * Note: we use the Ollama-compatible HF API, but not using the blobId. Instead, we use the special "ggufFile" field which returns the value for "hf_file". This is done to be backward-compatible with existing cache files. */ -static struct common_hf_file_res common_get_hf_file(const std::string & hf_repo_with_tag, const std::string & bearer_token) { +static struct common_hf_file_res common_get_hf_file(const std::string & hf_repo_with_tag, const std::string & bearer_token, bool offline) { auto parts = string_split(hf_repo_with_tag, ':'); std::string tag = parts.size() > 1 ? parts.back() : "latest"; std::string hf_repo = parts[0]; @@ -638,20 +646,25 @@ static struct common_hf_file_res common_get_hf_file(const std::string & hf_repo_ long res_code = 0; std::string res_str; bool use_cache = false; - try { - auto res = common_remote_get_content(url, params); - res_code = res.first; - res_str = std::string(res.second.data(), res.second.size()); - } catch (const std::exception & e) { - LOG_WRN("error: failed to get manifest: %s\n", e.what()); - LOG_WRN("try reading from cache\n"); - // try to read from cache + if (!offline) { try { + auto res = common_remote_get_content(url, params); + res_code = res.first; + res_str = std::string(res.second.data(), res.second.size()); + } catch (const std::exception & e) { + LOG_WRN("error: failed to get manifest at %s: %s\n", url.c_str(), e.what()); + } + } + if (res_code == 0) { + if (std::filesystem::exists(cached_response_path)) { + LOG_WRN("trying to read manifest from cache: %s\n", cached_response_path.c_str()); res_str = read_file(cached_response_path); res_code = 200; use_cache = true; - } catch (const std::exception & e) { - throw std::runtime_error("error: failed to get manifest (check your internet connection)"); + } else { + throw std::runtime_error( + offline ? "error: failed to get manifest (offline mode)" + : "error: failed to get manifest (check your internet connection)"); } } std::string ggufFile; @@ -698,24 +711,25 @@ bool common_has_curl() { return false; } -static bool common_download_file_single(const std::string &, const std::string &, const std::string &) { +static bool common_download_file_single(const std::string &, const std::string &, const std::string &, bool) { LOG_ERR("error: built without CURL, cannot download model from internet\n"); return false; } -static bool common_download_file_multiple(const std::vector> &, const std::string &) { +static bool common_download_file_multiple(const std::vector> &, const std::string &, bool) { LOG_ERR("error: built without CURL, cannot download model from the internet\n"); return false; } static bool common_download_model( const common_params_model &, - const std::string &) { + const std::string &, + bool) { LOG_ERR("error: built without CURL, cannot download model from the internet\n"); return false; } -static struct common_hf_file_res common_get_hf_file(const std::string &, const std::string &) { +static struct common_hf_file_res common_get_hf_file(const std::string &, const std::string &, bool) { LOG_ERR("error: built without CURL, cannot download model from the internet\n"); return {}; } @@ -742,7 +756,8 @@ struct handle_model_result { static handle_model_result common_params_handle_model( struct common_params_model & model, const std::string & bearer_token, - const std::string & model_path_default) { + const std::string & model_path_default, + bool offline) { handle_model_result result; // handle pre-fill default model path and url based on hf_repo and hf_file { @@ -750,7 +765,7 @@ static handle_model_result common_params_handle_model( // short-hand to avoid specifying --hf-file -> default it to --model if (model.hf_file.empty()) { if (model.path.empty()) { - auto auto_detected = common_get_hf_file(model.hf_repo, bearer_token); + auto auto_detected = common_get_hf_file(model.hf_repo, bearer_token, offline); if (auto_detected.repo.empty() || auto_detected.ggufFile.empty()) { exit(1); // built without CURL, error message already printed } @@ -791,7 +806,7 @@ static handle_model_result common_params_handle_model( // then, download it if needed if (!model.url.empty()) { - bool ok = common_download_model(model, bearer_token); + bool ok = common_download_model(model, bearer_token, offline); if (!ok) { LOG_ERR("error: failed to download model from %s\n", model.url.c_str()); exit(1); @@ -934,7 +949,7 @@ static bool common_params_parse_ex(int argc, char ** argv, common_params_context // handle model and download { - auto res = common_params_handle_model(params.model, params.hf_token, DEFAULT_MODEL_PATH); + auto res = common_params_handle_model(params.model, params.hf_token, DEFAULT_MODEL_PATH, params.offline); if (params.no_mmproj) { params.mmproj = {}; } else if (res.found_mmproj && params.mmproj.path.empty() && params.mmproj.url.empty()) { @@ -944,12 +959,12 @@ static bool common_params_parse_ex(int argc, char ** argv, common_params_context // only download mmproj if the current example is using it for (auto & ex : mmproj_examples) { if (ctx_arg.ex == ex) { - common_params_handle_model(params.mmproj, params.hf_token, ""); + common_params_handle_model(params.mmproj, params.hf_token, "", params.offline); break; } } - common_params_handle_model(params.speculative.model, params.hf_token, ""); - common_params_handle_model(params.vocoder.model, params.hf_token, ""); + common_params_handle_model(params.speculative.model, params.hf_token, "", params.offline); + common_params_handle_model(params.vocoder.model, params.hf_token, "", params.offline); } if (params.escape) { @@ -1333,9 +1348,9 @@ common_params_context common_params_parser_init(common_params & params, llama_ex )); add_opt(common_arg( {"--prio"}, "N", - string_format("set process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime (default: %d)\n", params.cpuparams.priority), + string_format("set process/thread priority : low(-1), normal(0), medium(1), high(2), realtime(3) (default: %d)\n", params.cpuparams.priority), [](common_params & params, int prio) { - if (prio < 0 || prio > 3) { + if (prio < GGML_SCHED_PRIO_LOW || prio > GGML_SCHED_PRIO_REALTIME) { throw std::invalid_argument("invalid value"); } params.cpuparams.priority = (enum ggml_sched_priority) prio; @@ -1445,6 +1460,14 @@ common_params_context common_params_parser_init(common_params & params, llama_ex params.n_keep = value; } )); + add_opt(common_arg( + {"--swa-full"}, + string_format("use full-size SWA cache (default: %s)\n" + "[(more info)](https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055)", params.swa_full ? "true" : "false"), + [](common_params & params) { + params.swa_full = true; + } + ).set_env("LLAMA_ARG_SWA_FULL")); add_opt(common_arg( {"--no-context-shift"}, string_format("disables context shift on infinite text generation (default: %s)", params.ctx_shift ? "disabled" : "enabled"), @@ -1670,7 +1693,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex [](common_params & params) { params.warmup = false; } - ).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_EMBEDDING})); + ).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_EMBEDDING, LLAMA_EXAMPLE_RETRIEVAL})); add_opt(common_arg( {"--spm-infill"}, string_format( @@ -2057,13 +2080,6 @@ common_params_context common_params_parser_init(common_params & params, llama_ex params.grp_attn_w = value; } ).set_env("LLAMA_ARG_GRP_ATTN_W").set_examples({LLAMA_EXAMPLE_MAIN})); - add_opt(common_arg( - {"-dkvc", "--dump-kv-cache"}, - "verbose print of the KV cache", - [](common_params & params) { - params.dump_kv_cache = true; - } - )); add_opt(common_arg( {"-nkvo", "--no-kv-offload"}, "disable KV offload", @@ -2232,12 +2248,12 @@ common_params_context common_params_parser_init(common_params & params, llama_ex } ).set_examples(mmproj_examples).set_env("LLAMA_ARG_NO_MMPROJ_OFFLOAD")); add_opt(common_arg( - {"--image"}, "FILE", - "path to an image file. use with multimodal models. Specify multiple times for batching", + {"--image", "--audio"}, "FILE", + "path to an image or audio file. use with multimodal models, can be repeated if you have multiple files\n", [](common_params & params, const std::string & value) { params.image.emplace_back(value); } - ).set_examples({LLAMA_EXAMPLE_LLAVA})); + ).set_examples({LLAMA_EXAMPLE_MTMD})); if (llama_supports_rpc()) { add_opt(common_arg( {"--rpc"}, "SERVERS", @@ -2847,15 +2863,24 @@ common_params_context common_params_parser_init(common_params & params, llama_ex ).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_MAIN}).set_env("LLAMA_ARG_JINJA")); add_opt(common_arg( {"--reasoning-format"}, "FORMAT", - "reasoning format (default: deepseek; allowed values: deepseek, none)\n" - "controls whether thought tags are extracted from the response, and in which format they're returned. 'none' leaves thoughts unparsed in `message.content`, 'deepseek' puts them in `message.reasoning_content` (for DeepSeek R1 & Command R7B only).\n" - "only supported for non-streamed responses", + "controls whether thought tags are allowed and/or extracted from the response, and in which format they're returned; one of:\n" + "- none: leaves thoughts unparsed in `message.content`\n" + "- deepseek: puts thoughts in `message.reasoning_content` (except in streaming mode, which behaves as `none`)\n" + "(default: deepseek)", [](common_params & params, const std::string & value) { /**/ if (value == "deepseek") { params.reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK; } else if (value == "none") { params.reasoning_format = COMMON_REASONING_FORMAT_NONE; } - else { std::invalid_argument("invalid value"); } + else { throw std::invalid_argument("invalid value"); } } ).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_MAIN}).set_env("LLAMA_ARG_THINK")); + add_opt(common_arg( + {"--reasoning-budget"}, "N", + "controls the amount of thinking allowed; currently only one of: -1 for unrestricted thinking budget, or 0 to disable thinking (default: -1)", + [](common_params & params, int value) { + if (value != 0 && value != -1) { throw std::invalid_argument("invalid value"); } + params.reasoning_budget = value; + } + ).set_examples({LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_MAIN}).set_env("LLAMA_ARG_THINK_BUDGET")); add_opt(common_arg( {"--chat-template"}, "JINJA_TEMPLATE", string_format( @@ -2867,7 +2892,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex [](common_params & params, const std::string & value) { params.chat_template = value; } - ).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_LLAVA}).set_env("LLAMA_ARG_CHAT_TEMPLATE")); + ).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_MTMD}).set_env("LLAMA_ARG_CHAT_TEMPLATE")); add_opt(common_arg( {"--chat-template-file"}, "JINJA_TEMPLATE_FILE", string_format( @@ -2954,7 +2979,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex [](common_params & params, const std::string & value) { /**/ if (value == "jsonl") { params.batched_bench_output_jsonl = true; } else if (value == "md") { params.batched_bench_output_jsonl = false; } - else { std::invalid_argument("invalid value"); } + else { throw std::invalid_argument("invalid value"); } } ).set_examples({LLAMA_EXAMPLE_BENCH})); add_opt(common_arg( @@ -2986,6 +3011,13 @@ common_params_context common_params_parser_init(common_params & params, llama_ex common_log_set_verbosity_thold(INT_MAX); } )); + add_opt(common_arg( + {"--offline"}, + "Offline mode: forces use of cache, prevents network access", + [](common_params & params) { + params.offline = true; + } + ).set_env("LLAMA_OFFLINE")); add_opt(common_arg( {"-lv", "--verbosity", "--log-verbosity"}, "N", "Set the verbosity threshold. Messages with a higher verbosity will be ignored.", diff --git a/common/chat-parser.cpp b/common/chat-parser.cpp new file mode 100644 index 0000000000000..65b664cb37da4 --- /dev/null +++ b/common/chat-parser.cpp @@ -0,0 +1,380 @@ +#include "chat-parser.h" +#include "common.h" +#include "log.h" +#include "regex-partial.h" + +#include +#include +#include +#include + +using json = nlohmann::ordered_json; + +common_chat_msg_parser::common_chat_msg_parser(const std::string & input, bool is_partial, const common_chat_syntax & syntax) + : input_(input), is_partial_(is_partial), syntax_(syntax) +{ + result_.role = "assistant"; + + while (true) { + std::string id = std::to_string(std::rand()); + if (input.find(id) == std::string::npos) { + healing_marker_ = id; + break; + } + } +} + +std::string common_chat_msg_parser::str(const common_string_range & rng) const { + GGML_ASSERT(rng.begin <= rng.end); + return input_.substr(rng.begin, rng.end - rng.begin); +} + +void common_chat_msg_parser::add_content(const std::string &content) { + result_.content += content; +} + +void common_chat_msg_parser::add_reasoning_content(const std::string &reasoning_content) { + result_.reasoning_content += reasoning_content; +} + +bool common_chat_msg_parser::add_tool_call(const std::string & name, const std::string & id, const std::string & arguments) { + if (name.empty()) { + return false; + } + + common_chat_tool_call tool_call; + tool_call.name = name; + tool_call.arguments = arguments; + tool_call.id = id; + + // LOG_DBG("Tool call arguments:\n\traw: %s\n\tresult: %s\n", arguments.c_str(), tool_call.arguments.c_str()); + result_.tool_calls.emplace_back(tool_call); + return true; +} +bool common_chat_msg_parser::add_tool_call(const json & tool_call) { + std::string name = tool_call.contains("name") ? tool_call.at("name") : ""; + std::string id = tool_call.contains("id") ? tool_call.at("id") : ""; + std::string arguments = tool_call.contains("arguments") ? tool_call.at("arguments") : ""; + return add_tool_call(name, id, arguments); +} + +bool common_chat_msg_parser::add_tool_calls(const json & arr) { + for (const auto & item : arr) { + if (!add_tool_call(item)) { + return false; + } + } + return true; +} +void common_chat_msg_parser::finish() { + if (!is_partial_ && pos_ != input_.size()) { + throw std::runtime_error("Unexpected content at end of input");// + input_.substr(pos_)); + } +} + +bool common_chat_msg_parser::consume_spaces() { + const auto length = input_.size(); + auto consumed = false; + while (pos_ < length && std::isspace(input_[pos_])) { + ++pos_; + consumed = true; + } + return consumed; +} + +bool common_chat_msg_parser::try_consume_literal(const std::string & literal) { + auto pos = pos_; + for (auto i = 0u; i < literal.size(); ++i) { + if (pos >= input_.size()) { + return false; + } + if (input_[pos] != literal[i]) { + return false; + } + ++pos; + } + pos_ = pos; + return true; +} + +std::optional common_chat_msg_parser::try_find_literal(const std::string & literal) { + auto idx = input_.find(literal, pos_); + if (idx != std::string::npos) { + find_regex_result res; + res.prelude = input_.substr(pos_, idx - pos_); + auto end = idx + literal.size(); + res.groups.emplace_back(common_string_range{idx, end}); + move_to(end); + return res; + } + if (is_partial_) { + idx = string_find_partial_stop(input_, literal); + if (idx != std::string::npos && idx >= pos_) { + find_regex_result res; + res.prelude = input_.substr(pos_, idx - pos_); + auto end = input_.size(); + res.groups.emplace_back(common_string_range{idx, end}); + move_to(end); + return res; + } + } + return std::nullopt; +} + +void common_chat_msg_parser::consume_literal(const std::string & literal) { + if (!try_consume_literal(literal)) { + throw common_chat_msg_partial_exception(literal); + } +} + +bool common_chat_msg_parser::try_parse_reasoning(const std::string & start_think, const std::string & end_think) { + auto handle_reasoning = [&](const std::string & reasoning, bool closed) { + auto stripped_reasoning = string_strip(reasoning); + if (stripped_reasoning.empty()) { + return; + } + if (syntax_.reasoning_in_content) { + add_content(syntax_.reasoning_format == COMMON_REASONING_FORMAT_DEEPSEEK ? "" : start_think); + add_content(stripped_reasoning); + if (closed) { + add_content(syntax_.reasoning_format == COMMON_REASONING_FORMAT_DEEPSEEK ? "" : end_think); + } + } else { + add_reasoning_content(stripped_reasoning); + } + }; + if (syntax_.reasoning_format != COMMON_REASONING_FORMAT_NONE) { + if (syntax_.thinking_forced_open || try_consume_literal(start_think)) { + if (auto res = try_find_literal(end_think)) { + handle_reasoning(res->prelude, /* closed */ true); + consume_spaces(); + return true; + } + auto rest = consume_rest(); + if (!rest.empty()) { + handle_reasoning(rest, /* closed */ !is_partial()); + } + // Allow unclosed thinking tags, for now (https://github.com/ggml-org/llama.cpp/issues/13812, https://github.com/ggml-org/llama.cpp/issues/13877) + // if (!syntax_.thinking_forced_open) { + // throw common_chat_msg_partial_exception(end_think); + // } + return true; + } + } + return false; +} + +std::string common_chat_msg_parser::consume_rest() { + auto rest = input_.substr(pos_); + pos_ = input_.size(); + return rest; +} + +// Tries to find the regex, consumes it (pos right after it) and gives the prelude (right before it) and the groups to the callback. +std::optional common_chat_msg_parser::try_find_regex(const common_regex & regex, size_t from, bool add_prelude_to_content) { + auto m = regex.search(input_, from == std::string::npos ? pos_ : from); + if (m.type == COMMON_REGEX_MATCH_TYPE_NONE) { + return std::nullopt; + } + auto prelude = input_.substr(pos_, m.groups[0].begin - pos_); + pos_ = m.groups[0].end; + + if (add_prelude_to_content) { + add_content(prelude); + } + if (m.type == COMMON_REGEX_MATCH_TYPE_PARTIAL) { + if (is_partial()) { + throw common_chat_msg_partial_exception(regex.str()); + } + return std::nullopt; + } + return find_regex_result{prelude, m.groups}; +} + +common_chat_msg_parser::find_regex_result common_chat_msg_parser::consume_regex(const common_regex & regex) { + if (auto result = try_consume_regex(regex)) { + return *result; + } + throw common_chat_msg_partial_exception(regex.str()); +} + +std::optional common_chat_msg_parser::try_consume_regex(const common_regex & regex) { + auto m = regex.search(input_, pos_); + if (m.type == COMMON_REGEX_MATCH_TYPE_NONE) { + return std::nullopt; + } + if (m.type == COMMON_REGEX_MATCH_TYPE_PARTIAL) { + if (is_partial()) { + throw common_chat_msg_partial_exception(regex.str()); + } + return std::nullopt; + } + if (m.groups[0].begin != pos_) { + // Didn't match at the current position. + return std::nullopt; + } + pos_ = m.groups[0].end; + + return find_regex_result { + /* .prelude = */ "", + m.groups, + }; +} + +std::optional common_chat_msg_parser::try_consume_json() { + auto it = input_.cbegin() + pos_; + const auto end = input_.cend(); + common_json result; + if (!common_json_parse(it, end, healing_marker_, result)) { + return std::nullopt; + } + pos_ = std::distance(input_.cbegin(), it); + if (result.healing_marker.marker.empty()) { + // No healing marker, just return the parsed json + return result; + } + if (!is_partial()) { + throw common_chat_msg_partial_exception("JSON"); + } + return result; +} + +common_json common_chat_msg_parser::consume_json() { + if (auto result = try_consume_json()) { + return *result; + } + throw common_chat_msg_partial_exception("JSON"); +} + +common_chat_msg_parser::consume_json_result common_chat_msg_parser::consume_json_with_dumped_args( + const std::vector> & args_paths, + const std::vector> & content_paths +) { + if (auto result = try_consume_json_with_dumped_args(args_paths, content_paths)) { + return *result; + } + throw common_chat_msg_partial_exception("JSON"); +} + +std::optional common_chat_msg_parser::try_consume_json_with_dumped_args( + const std::vector> & args_paths, + const std::vector> & content_paths +) { + auto partial = try_consume_json(); + if (!partial) { + return std::nullopt; + } + auto is_arguments_path = [&](const std::vector & path) { + return std::find(args_paths.begin(), args_paths.end(), path) != args_paths.end(); + }; + auto is_content_path = [&](const std::vector & path) { + return std::find(content_paths.begin(), content_paths.end(), path) != content_paths.end(); + }; + + if (partial->healing_marker.marker.empty()) { + if (args_paths.empty()) { + // No arguments to dump, and JSON was parsed fully. + return consume_json_result { + partial->json, + /* .is_partial = */ false, + }; + } + if (is_arguments_path({})) { + // Entire JSON is the arguments and was parsed fully. + return consume_json_result { + partial->json.dump(), + /* .is_partial = */ false, + }; + } + } + + LOG_DBG("Parsed partial JSON: %s (json_healing_marker: %s)\n", partial->json.dump().c_str(), partial->healing_marker.json_dump_marker.c_str()); + + auto found_healing_marker = false; + std::vector path; + std::function remove_unsupported_healings_and_dump_args = [&](const json & j) -> json { + if (is_arguments_path(path)) { + auto arguments = j.dump(); + if (is_partial() && !partial->healing_marker.marker.empty()) { + auto idx = arguments.find(partial->healing_marker.json_dump_marker); + if (idx != std::string::npos) { + arguments.resize(idx); + found_healing_marker = true; + } + if (arguments == "\"") { + // This happens because of completing `:"$magic` after `"arguments"` + arguments = ""; + } + } + return arguments; + } + if (is_content_path(path)) { + if (!j.is_string()) { + throw std::runtime_error("Content path must be a string"); + } + std::string str = j; + auto idx = str.find(partial->healing_marker.marker); // not using json_dump_marker as we're inside a string + if (idx != std::string::npos) { + str.resize(idx); + found_healing_marker = true; + } + return str; + } + if (j.is_object()) { + auto obj = json::object(); + for (const auto & p : j.items()) { + const auto & key = p.key(); + const auto & value = p.value(); + const std::string key_str = key; // NOLINT + auto idx = key_str.find(healing_marker_); + if (idx != std::string::npos) { + found_healing_marker = true; + break; + } + path.push_back(key_str); + if (value.is_string()) { + const std::string value_str = value; + if (value_str.find(healing_marker_) != std::string::npos) { + found_healing_marker = true; + if (is_content_path(path)) { + if (partial->healing_marker.marker == partial->healing_marker.json_dump_marker) { + // The healing occurred inside the string: good. Otherwise we just ditch the entire key/value pair. + obj[key] = remove_unsupported_healings_and_dump_args(value); + } + } + break; + } + obj[key] = value; + } else { + obj[key] = remove_unsupported_healings_and_dump_args(value); + } + path.pop_back(); + } + return obj; + } + if (j.is_array()) { + auto arr = json::array(); + for (const auto & value : j) { + if (value.is_string()) { + std::string str = value; + auto idx = str.find(healing_marker_); + if (idx != std::string::npos) { + // Don't heal array values that aren't in the arguments. + found_healing_marker = true; + break; + } + } + arr.push_back(remove_unsupported_healings_and_dump_args(value)); + } + return arr; + } + return j; + }; + + auto cleaned = remove_unsupported_healings_and_dump_args(partial->json); + LOG_DBG("Cleaned up JSON %s to %s (json_healing_marker : '%s')\n", partial->json.dump().c_str(), cleaned.dump().c_str(), partial->healing_marker.json_dump_marker.c_str()); + return consume_json_result { + cleaned, + /* .is_partial = */ found_healing_marker, + }; +} diff --git a/common/chat-parser.h b/common/chat-parser.h new file mode 100644 index 0000000000000..7ee355056b30a --- /dev/null +++ b/common/chat-parser.h @@ -0,0 +1,118 @@ +#pragma once + +#include "chat.h" +#include "json-partial.h" +#include "regex-partial.h" + +#include + +#include +#include +#include + +class common_chat_msg_partial_exception : public std::runtime_error { + public: + common_chat_msg_partial_exception(const std::string & message) : std::runtime_error(message) {} +}; + +class common_chat_msg_parser { + std::string input_; + bool is_partial_; + common_chat_syntax syntax_; + std::string healing_marker_; + + size_t pos_ = 0; + common_chat_msg result_; + + public: + common_chat_msg_parser(const std::string & input, bool is_partial, const common_chat_syntax & syntax); + const std::string & input() const { return input_; } + size_t pos() const { return pos_; } + const std::string & healing_marker() const { return healing_marker_; } + const bool & is_partial() const { return is_partial_; } + const common_chat_msg & result() const { return result_; } + const common_chat_syntax & syntax() const { return syntax_; } + + void move_to(size_t pos) { + if (pos > input_.size()) { + throw std::runtime_error("Invalid position!"); + } + pos_ = pos; + } + void move_back(size_t n) { + if (pos_ < n) { + throw std::runtime_error("Can't move back that far!"); + } + pos_ -= n; + } + + // Get the substring of the input at the given range + std::string str(const common_string_range & rng) const; + + // Appends to the result.content field + void add_content(const std::string & content); + + // Appends to the result.reasoning_content field + void add_reasoning_content(const std::string & reasoning_content); + + // Adds a tool call to the result. If the tool call is too incomplete (e.g. name empty), it won't add anything. + bool add_tool_call(const std::string & name, const std::string & id, const std::string & arguments); + + // Adds a tool call using the "name", "id" and "arguments" fields of the json object + bool add_tool_call(const nlohmann::ordered_json & tool_call); + + // Adds an array of tool calls using their "name", "id" and "arguments" fields. + bool add_tool_calls(const nlohmann::ordered_json & arr); + + void finish(); + + bool consume_spaces(); + + void consume_literal(const std::string & literal); + + bool try_parse_reasoning(const std::string & start_think, const std::string & end_think); + + std::string consume_rest(); + + struct find_regex_result { + std::string prelude; + std::vector groups; + }; + + std::optional try_find_regex(const common_regex & regex, size_t from = std::string::npos, bool add_prelude_to_content = true); + + bool try_consume_literal(const std::string & literal); + + std::optional try_find_literal(const std::string & literal); + + find_regex_result consume_regex(const common_regex & regex); + + std::optional try_consume_regex(const common_regex & regex); + + std::optional try_consume_json(); + common_json consume_json(); + + struct consume_json_result { + nlohmann::ordered_json value; + bool is_partial; + }; + + /* + Consume (possibly partial) json and converts specific subtrees to (possibly truncated) JSON strings. + + By default, object keys can't be truncated, nor can string values (their corresponding key is removed, + e.g. `{"foo": "bar", "baz": "b` -> `{"foo": "bar"}` + + But one can allow subpaths to be kept truncated, and possibly json-dumped to truncated json strings + - with `content_paths={{"foo"}}` -> `{"foo": "b` -> {"foo": "b"}` + - with `args_paths={{"foo"}}` -> `{"foo": {"b` -> `{"foo": "{b"}` + */ + consume_json_result consume_json_with_dumped_args( + const std::vector> & args_paths = {}, + const std::vector> & content_paths = {} + ); + std::optional try_consume_json_with_dumped_args( + const std::vector> & args_paths = {}, + const std::vector> & content_paths = {} + ); +}; diff --git a/common/chat.cpp b/common/chat.cpp index f138c7bcafcfa..f1ab4c85a913e 100644 --- a/common/chat.cpp +++ b/common/chat.cpp @@ -1,10 +1,21 @@ #include "chat.h" +#include "chat-parser.h" +#include "common.h" +#include "json-partial.h" #include "json-schema-to-grammar.h" #include "log.h" -#include "minja/chat-template.hpp" -#include "minja/minja.hpp" +#include "regex-partial.h" +#include +#include + +#include +#include +#include #include +#include +#include +#include static std::string format_time(const std::chrono::system_clock::time_point & now, const std::string & format) { auto time = std::chrono::system_clock::to_time_t(now); @@ -15,6 +26,101 @@ static std::string format_time(const std::chrono::system_clock::time_point & now return res; } +static std::string string_diff(const std::string & last, const std::string & current) { + if (last.empty()) { + return current; + } + if (!string_starts_with(current, last)) { + if (string_starts_with(last, current)) { + // This happens if the last generation ended on a partial stop word (not erased), + // and the current ended on a stop word (erased). + return ""; + } + throw std::runtime_error("Invalid diff: '" + last + "' not found at start of '" + current + "'"); + } + return current.substr(last.size()); +} + +static bool has_content_or_tool_calls(const common_chat_msg & msg) { + return !msg.content.empty() || !msg.tool_calls.empty(); +} + +template <> +json common_chat_msg::to_json_oaicompat() const +{ + json message { + {"role", "assistant"}, + }; + if (!reasoning_content.empty()) { + message["reasoning_content"] = reasoning_content; + } + if (content.empty() && !tool_calls.empty()) { + message["content"] = json(); + } else { + message["content"] = content; + } + if (!tool_calls.empty()) { + auto arr = json::array(); + for (const auto & tc : tool_calls) { + arr.push_back({ + {"type", "function"}, + {"function", { + {"name", tc.name}, + {"arguments", tc.arguments}, + }}, + {"id", tc.id}, + // // Some templates generate and require an id (sometimes in a very specific format, e.g. Mistral Nemo). + // // We only generate a random id for the ones that don't generate one by themselves + // // (they also won't get to see it as their template likely doesn't use it, so it's all for the client) + // {"id", tc.id.empty() ? gen_tool_call_id() : tc.id}, + }); + } + message["tool_calls"] = arr; + } + return message; +} + +std::vector common_chat_msg_diff::compute_diffs(const common_chat_msg & previous_msg, const common_chat_msg & new_msg) { + std::vector diffs; + // if (previous_msg.reasoning_content != current.reasoning_content) { + // auto & diff = diffs.emplace_back(); + // diff.reasoning_content_delta = string_diff(previous_msg.reasoning_content, current.reasoning_content); + // } + if (previous_msg.content != new_msg.content) { + auto & diff = diffs.emplace_back(); + diff.content_delta = string_diff(previous_msg.content, new_msg.content); + } + + if (new_msg.tool_calls.size() < previous_msg.tool_calls.size()) { + throw std::runtime_error("Invalid diff: now finding less tool calls!"); + } + + if (!previous_msg.tool_calls.empty()) { + auto idx = previous_msg.tool_calls.size() - 1; + const auto & pref = previous_msg.tool_calls[idx]; + const auto & newf = new_msg.tool_calls[idx]; + if (pref.name != newf.name) { + throw std::runtime_error("Invalid diff: tool call mismatch!"); + } + auto args_diff = string_diff(pref.arguments, newf.arguments); + if (!args_diff.empty() || pref.id != newf.id) { + auto & diff = diffs.emplace_back(); + diff.tool_call_index = idx; + if (pref.id != newf.id) { + diff.tool_call_delta.id = newf.id; + diff.tool_call_delta.name = newf.name; + } + diff.tool_call_delta.arguments = args_diff; + } + } + for (size_t idx = previous_msg.tool_calls.size(); idx < new_msg.tool_calls.size(); ++idx) { + auto & diff = diffs.emplace_back(); + diff.tool_call_index = idx; + diff.tool_call_delta = new_msg.tool_calls[idx]; + } + return diffs; +} + typedef minja::chat_template common_chat_template; struct common_chat_templates { @@ -32,7 +138,7 @@ struct templates_params { bool stream; std::string grammar; bool add_generation_prompt = true; - bool extract_reasoning = true; + bool enable_thinking = true; std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); }; @@ -277,6 +383,32 @@ json common_chat_tools_to_json_oaicompat(const std::vector & t return result; } +template <> json common_chat_msg_diff_to_json_oaicompat(const common_chat_msg_diff & diff) { + json delta = json::object(); + // if (!diff.reasoning_content_delta.empty()) { + // delta["reasoning_content"] = msg.reasoning_content; + // } + if (!diff.content_delta.empty()) { + delta["content"] = diff.content_delta; + } + if (diff.tool_call_index != std::string::npos) { + json tool_call; + tool_call["index"] = diff.tool_call_index; + if (!diff.tool_call_delta.id.empty()) { + tool_call["id"] = diff.tool_call_delta.id; + tool_call["type"] = "function"; + } + json function = json::object(); + if (!diff.tool_call_delta.name.empty()) { + function["name"] = diff.tool_call_delta.name; + } + function["arguments"] = diff.tool_call_delta.arguments; + tool_call["function"] = function; + delta["tool_calls"] = json::array({tool_call}); + } + return delta; +} + bool common_chat_verify_template(const std::string & tmpl, bool use_jinja) { if (use_jinja) { try { @@ -444,7 +576,7 @@ common_chat_templates_ptr common_chat_templates_init( return tmpls; } -std::string common_chat_format_name(common_chat_format format) { +const char * common_chat_format_name(common_chat_format format) { switch (format) { case COMMON_CHAT_FORMAT_CONTENT_ONLY: return "Content-only"; case COMMON_CHAT_FORMAT_GENERIC: return "Generic"; @@ -452,182 +584,127 @@ std::string common_chat_format_name(common_chat_format format) { case COMMON_CHAT_FORMAT_LLAMA_3_X: return "Llama 3.x"; case COMMON_CHAT_FORMAT_LLAMA_3_X_WITH_BUILTIN_TOOLS: return "Llama 3.x with builtin tools"; case COMMON_CHAT_FORMAT_DEEPSEEK_R1: return "DeepSeek R1"; - case COMMON_CHAT_FORMAT_DEEPSEEK_R1_EXTRACT_REASONING: return "DeepSeek R1 (extract reasoning)"; case COMMON_CHAT_FORMAT_FIREFUNCTION_V2: return "FireFunction v2"; case COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2: return "Functionary v3.2"; case COMMON_CHAT_FORMAT_FUNCTIONARY_V3_1_LLAMA_3_1: return "Functionary v3.1 Llama 3.1"; case COMMON_CHAT_FORMAT_HERMES_2_PRO: return "Hermes 2 Pro"; - case COMMON_CHAT_FORMAT_HERMES_2_PRO_EXTRACT_REASONING: return "Hermes 2 Pro (extract reasoning)"; case COMMON_CHAT_FORMAT_COMMAND_R7B: return "Command R7B"; - case COMMON_CHAT_FORMAT_COMMAND_R7B_EXTRACT_REASONING: return "Command R7B (extract reasoning)"; default: throw std::runtime_error("Unknown chat format"); } } -static bool parse_json(std::string::const_iterator & it, const std::string::const_iterator & end, json & out) { - // // https://json.nlohmann.me/features/parsing/sax_interface/ - struct json_error_locator : public nlohmann::json_sax { - std::size_t position; - bool found_error; - - json_error_locator() : position(0), found_error(false) {} - - bool parse_error(std::size_t position, const std::string &, const json::exception &) override { // NOLINT - this->position = position - 1; - this->found_error = true; - return false; - } - bool null() override { return true; } // NOLINT - bool boolean(bool) override { return true; } // NOLINT - bool number_integer(number_integer_t) override { return true; } // NOLINT - bool number_unsigned(number_unsigned_t) override { return true; } // NOLINT - bool number_float(number_float_t, const string_t &) override { return true; } // NOLINT - bool string(string_t &) override { return true; } // NOLINT - bool binary(binary_t &) override { return true; } // NOLINT - bool start_object(std::size_t) override { return true; } // NOLINT - bool key(string_t &) override { return true; } // NOLINT - bool end_object() override { return true; } - bool start_array(std::size_t) override { return true; } // NOLINT - bool end_array() override { return true; } - }; - json_error_locator err_loc; - json::sax_parse(it, end, &err_loc); - - std::string::const_iterator temptative_end; - if (err_loc.found_error) { - temptative_end = it + err_loc.position; - } else { - temptative_end = end; - } - std::string json_sub {it, temptative_end}; - try { - out = json::parse(json_sub); - it = temptative_end; - return true; - } catch (const std::exception &) { - return false; - } -} - -static bool parse_literal(std::string::const_iterator & it, const std::string::const_iterator & end, const std::string & expected) { - auto expected_it = expected.begin(); - auto tmp_it = it; - while (tmp_it != end && expected_it != expected.end() && *tmp_it == *expected_it) { - ++tmp_it; - ++expected_it; - } - if (expected_it == expected.end()) { - it = tmp_it; - return true; - } - return false; -} - -static std::optional parse_pattern(std::string::const_iterator & it, const std::string::const_iterator & end, const std::regex & expected) { - std::smatch match; - if (std::regex_match(it, end, match, expected)) { - it = match.suffix().first; - return match; +const char * common_reasoning_format_name(common_reasoning_format format) { + switch (format) { + case COMMON_REASONING_FORMAT_NONE: return "none"; + case COMMON_REASONING_FORMAT_DEEPSEEK: return "deepseek"; + default: + throw std::runtime_error("Unknown reasoning format"); } - return std::nullopt; } -static void consume_spaces(std::string::const_iterator & it, const std::string::const_iterator & end) { - while (it != end && std::isspace(*it)) { - ++it; +static std::string wrap_code_as_arguments(common_chat_msg_parser & builder, const std::string & code) { + std::string arguments; + if (builder.is_partial()) { + arguments = (json {{"code", code + builder.healing_marker()}}).dump(); + auto idx = arguments.find(builder.healing_marker()); + if (idx != std::string::npos) { + arguments.resize(idx); + } + } else { + arguments = (json {{"code", code}}).dump(); } + return arguments; } /** * Takes a prefix regex that must have 1 group to capture the function name, a closing suffix, and expects json parameters in between. * Aggregates the prefix, suffix and in-between text into the content. */ -static common_chat_msg parse_json_tool_calls( - const std::string& input, - const std::optional & trigger_opt, - const std::regex & function_regex, - const std::regex & close_regex, - bool allow_raw_python = false) { - std::smatch match; - - common_chat_msg result; - result.role = "assistant"; - - - auto end = input.end(); - auto it = input.begin(); - - if (trigger_opt) { - if (!std::regex_search(it, end, match, *trigger_opt)) { - result.content = input; - return result; - } - result.content = match.prefix().str(); - it = match.suffix().first; - } +static void parse_json_tool_calls( + common_chat_msg_parser & builder, + const std::optional & block_open, + const std::optional & function_regex_start_only, + const std::optional & function_regex, + const common_regex & close_regex, + const std::optional & block_close, + bool allow_raw_python = false, + const std::function & get_function_name = nullptr) { + + auto parse_tool_calls = [&]() { + size_t from = std::string::npos; + auto first = true; + while (true) { + auto res = function_regex_start_only && first + ? builder.try_consume_regex(*function_regex_start_only) + : function_regex + ? builder.try_find_regex(*function_regex, from) + : std::nullopt; + if (res) { + std::string name; + if (get_function_name) { + name = get_function_name(*res); + } else { + GGML_ASSERT(res->groups.size() == 2); + name = builder.str(res->groups[1]); + } + first = false; + if (name.empty()) { + // get_function_name signalled us that we should skip this match and treat it as content. + from = res->groups[0].begin + 1; + continue; + } + from = std::string::npos; - while (it != end) { - std::sregex_iterator rend; - std::sregex_iterator rit(it, end, function_regex); - if (rit == rend) { - result.content += std::string(it, end); + auto maybe_raw_python = name == "python" && allow_raw_python; + if (builder.input()[builder.pos()] == '{' || !maybe_raw_python) { + if (auto arguments = builder.try_consume_json_with_dumped_args({{}})) { + if (!builder.add_tool_call(name, "", arguments->value) || arguments->is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + builder.consume_regex(close_regex); + } + continue; + } + if (maybe_raw_python) { + auto arguments = wrap_code_as_arguments(builder, builder.consume_rest()); + if (!builder.add_tool_call(name, "", arguments)) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + return; + } + throw common_chat_msg_partial_exception("incomplete tool call"); + } break; } - auto name = rit->str(1); - result.content += std::string(it, rit->prefix().second); - it = rit->suffix().first; - - json arguments; - if (parse_json(it, end, arguments)) { - if (!std::regex_search(it, end, match, close_regex)) { - throw std::runtime_error("Malformed input, missing closing pattern: " + input); - } - it = match.suffix().first; - result.tool_calls.push_back({name, arguments.is_string() ? arguments.get() : arguments.dump(), /* id= */ ""}); - } else { - if (allow_raw_python && name == "python") { - result.tool_calls.push_back({name, json({{"code", std::string(it, end)}}).dump(), /* id= */ ""}); - break; - } - throw std::runtime_error("Failed to parse json tool call arguments: " + input); + if (block_close) { + builder.consume_regex(*block_close); } - } - - if (!result.tool_calls.empty()) { - if (!string_strip(result.content).empty()) { - LOG_WRN("Content found with tool calls: %s\n", result.content.c_str()); + builder.consume_spaces(); + builder.add_content(builder.consume_rest()); + }; + if (block_open) { + if (auto res = builder.try_find_regex(*block_open)) { + parse_tool_calls(); + } else { + builder.add_content(builder.consume_rest()); } - result.content = ""; + } else { + parse_tool_calls(); } - return result; } -static common_chat_tool_call process_tool_call(const json & tool_call) { - const auto & arguments = tool_call.at("arguments"); - return { - /* .name = */ tool_call.at("name"), - /* .arguments = */ arguments.is_string() ? arguments.get() : arguments.dump(), - /* .id = */ tool_call.contains("id") ? tool_call.at("id") : "", - }; -} -static common_chat_msg parse_prefixed_json_tool_call_array(const std::string& input, const std::string & prefix, size_t rstrip_prefix = 0) { - auto content_end = input.find(prefix); - size_t tc_start = std::string::npos; - - common_chat_msg result; - result.role = "assistant"; - if (content_end == std::string::npos) { - result.content = input; - } else { - tc_start = content_end + prefix.size() - rstrip_prefix; - result.content = input.substr(0, content_end); - auto tool_calls = json::parse(input.substr(tc_start)); - for (const auto & tool_call : tool_calls) { - result.tool_calls.emplace_back(process_tool_call(tool_call)); +static void parse_prefixed_json_tool_call_array(common_chat_msg_parser & builder, const common_regex & prefix, size_t rstrip_prefix = 0) { + static const std::vector> args_paths = {{"arguments"}}; + if (auto res = builder.try_find_regex(prefix)) { + builder.move_back(rstrip_prefix); + auto tool_calls = builder.consume_json_with_dumped_args(args_paths); + if (!builder.add_tool_calls(tool_calls.value) || tool_calls.is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call array"); } + } else { + builder.add_content(builder.consume_rest()); } - return result; } static void foreach_function(const json & tools, const std::function & fn) { @@ -754,29 +831,36 @@ static common_chat_params common_chat_params_init_generic(const common_chat_temp data.format = COMMON_CHAT_FORMAT_GENERIC; return data; } -static common_chat_msg common_chat_parse_generic(const std::string & input) { - json data = json::parse(input); - common_chat_msg result; - result.role = "assistant"; - if (data.contains("tool_calls")) { - for (const auto & tool_call : data.at("tool_calls")) { - result.tool_calls.push_back({ - tool_call.at("name"), - tool_call.at("arguments").dump(), - tool_call.contains("id") ? tool_call.at("id") : "", - }); +static void common_chat_parse_generic(common_chat_msg_parser & builder) { + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + static const std::vector> content_paths = { + {"response"}, + }; + static const std::vector> args_paths = { + {"tool_call", "arguments"}, + {"tool_calls", "arguments"}, + }; + auto data = builder.consume_json_with_dumped_args(args_paths, content_paths); + if (data.value.contains("tool_calls")) { + if (!builder.add_tool_calls(data.value.at("tool_calls")) || data.is_partial) { + throw common_chat_msg_partial_exception("incomplete tool calls"); } - } else if (data.contains("tool_call")) { - result.tool_calls.push_back({ - data.at("tool_call").at("name"), - data.at("tool_call").at("arguments").dump(), - /* id= */ "", - }); - } else if (data.contains("response")) { - const auto & response = data.at("response"); - result.content = response.is_string() ? response.get() : response.dump(2); + } else if (data.value.contains("tool_call")) { + if (!builder.add_tool_call(data.value.at("tool_call")) || data.is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + } else if (data.value.contains("response")) { + const auto & response = data.value.at("response"); + builder.add_content(response.is_string() ? response.template get() : response.dump(2)); + if (data.is_partial) { + throw common_chat_msg_partial_exception("incomplete response"); + } + } else { + throw common_chat_msg_partial_exception("Expected 'tool_call', 'tool_calls' or 'response' in JSON"); } - return result; } static common_chat_params common_chat_params_init_mistral_nemo(const common_chat_template & tmpl, const struct templates_params & inputs) { @@ -823,12 +907,44 @@ static common_chat_params common_chat_params_init_mistral_nemo(const common_chat data.format = COMMON_CHAT_FORMAT_MISTRAL_NEMO; return data; } -static common_chat_msg common_chat_parse_mistral_nemo(const std::string & input) { - return parse_prefixed_json_tool_call_array(input, "[TOOL_CALLS]"); +static void common_chat_parse_mistral_nemo(common_chat_msg_parser & builder) { + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + + static const common_regex prefix(regex_escape("[TOOL_CALLS]")); + parse_prefixed_json_tool_call_array(builder, prefix); } static common_chat_params common_chat_params_init_command_r7b(const common_chat_template & tmpl, const struct templates_params & inputs) { common_chat_params data; + + auto adjusted_messages = json::array(); + for (const auto & msg : inputs.messages) { + auto has_reasoning_content = msg.contains("reasoning_content") && msg.at("reasoning_content").is_string(); + auto has_tool_calls = msg.contains("tool_calls") && msg.at("tool_calls").is_array(); + if (has_reasoning_content && has_tool_calls) { + auto adjusted_message = msg; + adjusted_message["tool_plan"] = msg.at("reasoning_content"); + adjusted_message.erase("reasoning_content"); + adjusted_messages.push_back(adjusted_message); + } else { + adjusted_messages.push_back(msg); + } + } + data.prompt = apply(tmpl, adjusted_messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt, {}); + data.format = COMMON_CHAT_FORMAT_COMMAND_R7B; + if (string_ends_with(data.prompt, "<|START_THINKING|>")) { + if (!inputs.enable_thinking) { + data.prompt += "<|END_THINKING|>"; + } else { + data.thinking_forced_open = true; + } + } else if (!inputs.enable_thinking && string_ends_with(data.prompt, "<|CHATBOT_TOKEN|>")) { + data.prompt += "<|START_THINKING|><|END_THINKING|>"; + } + data.grammar_lazy = inputs.tool_choice != COMMON_CHAT_TOOL_CHOICE_REQUIRED; data.grammar = build_grammar([&](const common_grammar_builder & builder) { auto schemas = json::array(); @@ -859,11 +975,16 @@ static common_chat_params common_chat_params_init_command_r7b(const common_chat_ if (!inputs.parallel_tool_calls) { schema["maxItems"] = 1; } - builder.add_rule("root", "\"<|START_ACTION|>\" " + builder.add_schema("tool_calls", schema) + " \"<|END_ACTION|>\""); + builder.add_rule("root", + std::string(data.thinking_forced_open ? "( \"<|END_THINKING|>\" space )? " : "") + + "\"<|START_ACTION|>\" " + builder.add_schema("tool_calls", schema) + " \"<|END_ACTION|>\""); }); data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_WORD, - "<|START_ACTION|>", + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL, + // If thinking_forced_open, then we capture the tag in the grammar, + // (important for required tool choice) and in the trigger's first capture (decides what is sent to the grammar) + std::string(data.thinking_forced_open ? "[\\s\\S]*?(<\\|END_THINKING\\|>\\s*)" : "(?:<\\|START_THINKING\\|>[\\s\\S]*?<\\|END_THINKING\\|>\\s*)?") + + "(<\\|START_ACTION\\|>)[\\s\\S]*" }); data.preserved_tokens = { "<|START_ACTION|>", @@ -873,61 +994,40 @@ static common_chat_params common_chat_params_init_command_r7b(const common_chat_ "<|START_THINKING|>", "<|END_THINKING|>", }; - auto adjusted_messages = json::array(); - for (const auto & msg : inputs.messages) { - auto has_reasoning_content = msg.contains("reasoning_content") && msg.at("reasoning_content").is_string(); - auto has_tool_calls = msg.contains("tool_calls") && msg.at("tool_calls").is_array(); - if (has_reasoning_content && has_tool_calls) { - auto adjusted_message = msg; - adjusted_message["tool_plan"] = msg.at("reasoning_content"); - adjusted_message.erase("reasoning_content"); - adjusted_messages.push_back(adjusted_message); - } else { - adjusted_messages.push_back(msg); - } - } - data.prompt = apply(tmpl, adjusted_messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt, {}); - data.format = inputs.extract_reasoning ? COMMON_CHAT_FORMAT_COMMAND_R7B_EXTRACT_REASONING : COMMON_CHAT_FORMAT_COMMAND_R7B; return data; } -static common_chat_msg common_chat_parse_command_r7b(const std::string & input, bool extract_reasoning) { - static const std::regex thought_regex("(<\\|START_THINKING\\|>([\\s\\S]*?)<\\|END_THINKING\\|>)([\\s\\S]*)"); - static const std::regex action_regex("<\\|START_ACTION\\|>([\\s\\S]*?)<\\|END_ACTION\\|>"); - static const std::regex response_regex("(?:<\\|START_RESPONSE\\|>)?([\\s\\S]*?)<\\|END_RESPONSE\\|>"); - - std::smatch match; - - common_chat_msg result; - result.role = "assistant"; - - std::string rest = input; - if (std::regex_match(rest, match, thought_regex)) { - if (extract_reasoning) { - result.reasoning_content = match[2].str(); - } else if (!match[2].str().empty()) { - // Let the unparsed thinking tags through in content only if their insides aren't empty. - result.content = match[1].str(); +static void common_chat_parse_command_r7b(common_chat_msg_parser & builder) { + builder.try_parse_reasoning("<|START_THINKING|>", "<|END_THINKING|>"); + + static const common_regex start_action_regex("<\\|START_ACTION\\|>"); + static const common_regex end_action_regex("<\\|END_ACTION\\|>"); + static const common_regex start_response_regex("<\\|START_RESPONSE\\|>"); + static const common_regex end_response_regex("<\\|END_RESPONSE\\|>"); + + if (auto res = builder.try_find_regex(start_action_regex)) { + // If we didn't extract thoughts, prelude includes them. + auto tool_calls = builder.consume_json_with_dumped_args({{"parameters"}}); + for (const auto & tool_call : tool_calls.value) { + std::string name = tool_call.contains("tool_name") ? tool_call.at("tool_name") : ""; + std::string id = tool_call.contains("tool_call_id") ? tool_call.at("tool_call_id") : ""; + std::string arguments = tool_call.contains("parameters") ? tool_call.at("parameters") : ""; + if (!builder.add_tool_call(name, id, arguments) || tool_calls.is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } } - rest = match[3].str(); - } - if (std::regex_match(rest, match, action_regex)) { - auto actions_str = match[1].str(); - auto actions = json::parse(actions_str); - for (const auto & action : actions) { - result.tool_calls.push_back({ - /* .name = */ action.at("tool_name"), - /* .arguments = */ action.at("parameters").dump(), - /* .id = */ action.at("tool_call_id"), - }); + if (tool_calls.is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + builder.consume_regex(end_action_regex); + } else if (auto res = builder.try_find_regex(start_response_regex)) { + if (!builder.try_find_regex(end_response_regex)) { + builder.add_content(builder.consume_rest()); + throw common_chat_msg_partial_exception(end_response_regex.str()); } - } else if (std::regex_match(rest, match, response_regex)) { - auto response = match[1].str(); - result.content += response; } else { - result.content += rest; + builder.add_content(builder.consume_rest()); } - return result; } static void expect_tool_parameters(const std::string & name, const json & parameters, const std::vector & expected_properties) { @@ -1004,8 +1104,8 @@ static common_chat_params common_chat_params_init_llama_3_x(const common_chat_te }); // Small models may hallucinate function names so we match anything (*at the start*) that looks like the JSON of a function call, regardless of the name. data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START, - "\\{\\s*(?:\"type\"\\s*:\\s*\"function\"\\s*,\\s*)?\"name\"\\s*:\\s*\"", // + name + "\"[\\s\\S]*", + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL, + "(\\{\\s*(?:\"type\"\\s*:\\s*\"function\"\\s*,\\s*)?\"name\"\\s*:\\s*\")[\\s\\S]*", // + name + "\"[\\s\\S]*", }); if (!builtin_tools.empty()) { data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "<|python_tag|>"}); @@ -1028,42 +1128,93 @@ static common_chat_params common_chat_params_init_llama_3_x(const common_chat_te }); return data; } -static common_chat_msg common_chat_parse_llama_3_1(const std::string & input, bool with_builtin_tools = false) { - // TODO: tighten & simplify the parser, don't accept leading text context. - static const std::regex function_regex( +static void common_chat_parse_llama_3_1(common_chat_msg_parser & builder, bool with_builtin_tools = false) { + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + + static const common_regex function_regex( "\\s*\\{\\s*(?:\"type\"\\s*:\\s*\"function\"\\s*,\\s*)?\"name\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"parameters\"\\s*: "); - static const std::regex close_regex("\\}\\s*"); - static const std::regex builtin_call_regex("<\\|python_tag\\|>\\s*([^.(]+)\\s*\\.\\s*call\\s*\\(\\s*([\\w]+)\\s*=\\s*([\\s\\S]*?)\\)"); + static const common_regex close_regex("\\}\\s*"); + + static const common_regex function_name_regex("\\s*(\\w+)\\s*\\.\\s*call\\("); + static const common_regex arg_name_regex("\\s*(\\w+)\\s*=\\s*"); if (with_builtin_tools) { - std::smatch match; - if (std::regex_match(input, match, builtin_call_regex)) { - try { - auto name = match[1].str(); - auto arg_name = match[2].str(); - auto arg_value_str = match[3].str(); - auto arg_value = json::parse(arg_value_str); - - common_chat_msg msg; - msg.role = "assistant"; - msg.tool_calls.push_back({ - /* .name = */ name, - /* .arguments = */ (json { - {arg_name, arg_value}, - }).dump(), - /* .id = */ "", - }); - return msg; - } catch (const std::exception & e) { - LOG_WRN("Failed to parse builtin tool call arguments (%s): %s", e.what(), input.c_str()); + static const common_regex builtin_call_regex("<\\|python_tag\\|>"); + if (auto res = builder.try_find_regex(builtin_call_regex)) { + auto fun_res = builder.consume_regex(function_name_regex); + auto function_name = builder.str(fun_res.groups[1]); + + common_healing_marker healing_marker; + json args = json::object(); + while (true) { + if (auto arg_res = builder.try_consume_regex(arg_name_regex)) { + auto arg_name = builder.str(arg_res->groups[1]); + auto partial = builder.consume_json(); + args[arg_name] = partial.json; + healing_marker.marker = partial.healing_marker.marker; + healing_marker.json_dump_marker = partial.healing_marker.json_dump_marker; + builder.consume_spaces(); + if (!builder.try_consume_literal(",")) { + break; + } + } else { + break; + } } + builder.consume_literal(")"); + builder.consume_spaces(); + + auto arguments = args.dump(); + if (!builder.add_tool_call(function_name, "", arguments)) { + throw common_chat_msg_partial_exception("Incomplete tool call"); + } + return; } } - return parse_json_tool_calls(input, std::nullopt, function_regex, close_regex); + parse_json_tool_calls( + builder, + /* block_open= */ std::nullopt, + /* function_regex_start_only= */ function_regex, + /* function_regex= */ std::nullopt, + close_regex, + std::nullopt); + } static common_chat_params common_chat_params_init_deepseek_r1(const common_chat_template & tmpl, const struct templates_params & inputs) { common_chat_params data; + auto prompt = apply(tmpl, inputs.messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt); + + // Hacks to fix the official (broken) prompt. + // It is advisable to use --chat-template-file models/templates/llama-cpp-deepseek-r1.jinja instead, + // until the official template is fixed. + if (tmpl.source().find("{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}") != std::string::npos) { + // Don't leave the chat dangling after tool results + if (string_ends_with(prompt, "<|tool▁outputs▁end|>")) { + prompt += "<|end▁of▁sentence|>"; + if (inputs.add_generation_prompt) { + prompt += "<|Assistant|>"; + } + } + // Fix up tool call delta example added by Minja + prompt = std::regex_replace( + prompt, + std::regex("(<|tool▁call▁end|>)[\\s\\r\\n]*(<|tool▁outputs▁begin|>|<|User|>)"), + "$1<|tool▁calls▁end|><|end▁of▁sentence|>$2"); + } + data.prompt = prompt; + data.format = COMMON_CHAT_FORMAT_DEEPSEEK_R1; + if (string_ends_with(data.prompt, "\n")) { + if (!inputs.enable_thinking) { + data.prompt += ""; + } else { + data.thinking_forced_open = true; + } + } + if (inputs.tools.is_array() && !inputs.tools.empty()) { data.grammar_lazy = inputs.tool_choice != COMMON_CHAT_TOOL_CHOICE_REQUIRED && inputs.json_schema.is_null(); data.grammar = build_grammar([&](const common_grammar_builder & builder) { @@ -1074,21 +1225,25 @@ static common_chat_params common_chat_params_init_deepseek_r1(const common_chat_ auto parameters = function.at("parameters"); builder.resolve_refs(parameters); tool_rules.push_back(builder.add_rule(name + "-call", - "\"<|tool▁call▁begin|>function<|tool▁sep|>" + name + "\\n" + "( \"<|tool▁call▁begin|>\" )? \"function<|tool▁sep|>" + name + "\\n" "```json\\n\" " + builder.add_schema(name + "-args", parameters) + " " "\"```<|tool▁call▁end|>\"")); }); // Distill Qwen 7B & 32B models seem confused re/ syntax of their tool call opening tag, // so we accept common variants (then it's all constrained) builder.add_rule("root", - "( \"<|tool▁calls▁begin|>\" | \"<|tool_calls_begin|>\" | \"<|tool calls begin|>\" | \"<|tool\\\\_calls\\\\_begin|>\" ) " + std::string(data.thinking_forced_open ? "( \"\" space )? " : "") + + "( \"<|tool▁calls▁begin|>\" | \"<|tool_calls_begin|>\" | \"<|tool calls begin|>\" | \"<|tool\\\\_calls\\\\_begin|>\" | \"<|tool▁calls|>\" ) " "(" + string_join(tool_rules, " | ") + ")" + (inputs.parallel_tool_calls ? "*" : "") + " " "\"<|tool▁calls▁end|>\"" " space"); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "<|tool▁calls▁begin|>"}); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "<|tool_calls_begin|>"}); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "<|tool calls begin|>"}); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "<|tool\\_calls\\_begin|>"}); + data.grammar_triggers.push_back({ + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL, + // If thinking_forced_open, then we capture the tag in the grammar, + // (important for required tool choice) and in the trigger's first capture (decides what is sent to the grammar) + std::string(data.thinking_forced_open ? "[\\s\\S]*?(\\s*)" : "(?:[\\s\\S]*?\\s*)?") + + "(<|tool▁calls▁begin|>|<|tool_calls_begin|>|<|tool calls begin|>|<|tool\\\\_calls\\\\_begin|>|<|tool▁calls|>)[\\s\\S]*" + }); data.preserved_tokens = { "", "", @@ -1100,65 +1255,27 @@ static common_chat_params common_chat_params_init_deepseek_r1(const common_chat_ }; }); } - auto prompt = apply(tmpl, inputs.messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt); - - // Hacks to fix the official (broken) prompt. - // It is advisable to use --chat-template-file models/templates/llama-cpp-deepseek-r1.jinja instead, - // until the official template is fixed. - if (tmpl.source().find("{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}") != std::string::npos) { - // Don't leave the chat dangling after tool results - if (string_ends_with(prompt, "<|tool▁outputs▁end|>")) { - prompt += "<|end▁of▁sentence|>"; - if (inputs.add_generation_prompt) { - prompt += "<|Assistant|>"; - } - } - // Fix up tool call delta example added by Minja - prompt = std::regex_replace( - prompt, - std::regex("(<|tool▁call▁end|>)[\\s\\r\\n]*(<|tool▁outputs▁begin|>|<|User|>)"), - "$1<|tool▁calls▁end|><|end▁of▁sentence|>$2"); - } - data.prompt = prompt; - data.format = inputs.extract_reasoning ? COMMON_CHAT_FORMAT_DEEPSEEK_R1_EXTRACT_REASONING : COMMON_CHAT_FORMAT_DEEPSEEK_R1; return data; } -static common_chat_msg handle_think_tag_prelude(const std::string & input, bool extract_reasoning, const std::function & rest_parser) { - std::smatch match; - static const std::regex reasoning_content_regex("((?:)?([\\s\\S\\r\\n]*?))?([\\s\\S\\r\\n]*)"); - if (std::regex_match(input, match, reasoning_content_regex)) { - auto rest = match[3].str(); - auto msg = rest_parser(rest); - auto reasoning_content = string_strip(match[2].str()); - if (extract_reasoning) { - msg.reasoning_content = reasoning_content; - } else if (!reasoning_content.empty()) { - std::ostringstream content; - content << "" << reasoning_content << "" << msg.content; - msg.content = content.str(); - } - return msg; - } - return rest_parser(input); -} -static common_chat_msg common_chat_parse_deepseek_r1(const std::string & input, bool extract_reasoning) { - return handle_think_tag_prelude(input, extract_reasoning, [](const std::string & input) { - static const std::regex function_regex("<|tool▁call▁begin|>function<|tool▁sep|>([^\n]+)\n```json\n"); - static const std::regex close_regex("```[\\s\\r\\n]*<|tool▁call▁end|>"); - static const std::regex tool_calls_regex("[\\s\\r\\n]*(?:<|tool▁calls▁begin|>|<|tool_calls_begin|>|<|tool calls begin|>|<|tool\\\\_calls\\\\_begin|>)([\\s\\S\\r\\n]*?)<|tool▁calls▁end|>"); - - common_chat_msg msg; - msg.role = "assistant"; - std::smatch match; - if (std::regex_search(input, match, tool_calls_regex)) { - auto tool_calls = match[1].str(); - auto msg2 = parse_json_tool_calls(tool_calls, std::nullopt, function_regex, close_regex); - msg.tool_calls = std::move(msg2.tool_calls); - } else { - msg.content = input; - } - return msg; - }); +static void common_chat_parse_deepseek_r1(common_chat_msg_parser & builder) { + builder.try_parse_reasoning("", ""); + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + + static const common_regex tool_calls_begin("(?:<|tool▁calls▁begin|>|<|tool_calls_begin|>|<|tool calls begin|>|<|tool\\\\_calls\\\\_begin|>|<|tool▁calls|>)"); + static const common_regex tool_calls_end("<|tool▁calls▁end|>"); + static const common_regex function_regex("(?:<|tool▁call▁begin|>)?function<|tool▁sep|>([^\n]+)\n```json\n"); + static const common_regex close_regex("```[\\s\\r\\n]*<|tool▁call▁end|>"); + + parse_json_tool_calls( + builder, + /* block_open= */ tool_calls_begin, + /* function_regex_start_only= */ std::nullopt, + function_regex, + close_regex, + tool_calls_end); } static common_chat_params common_chat_params_init_firefunction_v2(const common_chat_template & tmpl, const struct templates_params & inputs) { @@ -1206,13 +1323,19 @@ static common_chat_params common_chat_params_init_firefunction_v2(const common_c } return data; } -static common_chat_msg common_chat_parse_firefunction_v2(const std::string & input) { - return parse_prefixed_json_tool_call_array(input, " functools[", /* rstrip_prefix= */ 1); +static void common_chat_parse_firefunction_v2(common_chat_msg_parser & builder) { + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + static const common_regex prefix(regex_escape(" functools[")); + parse_prefixed_json_tool_call_array(builder, prefix, /* rstrip_prefix= */ 1); } static common_chat_params common_chat_params_init_functionary_v3_2(const common_chat_template & tmpl, const struct templates_params & inputs) { // >>>all\nlet's call functions>>>fn1\n{"arg1": 1...}\n>>>fn2\n{"arg1": 1...}... // Using ">>>f1\n", ">>>f2\n"... as trigger words for the grammar + // If the function is python, we also allow raw python code (if the line after `python\n` doesn't start w/ opening `{`), which the model seems to prefer for multiline code. common_chat_params data; data.prompt = apply(tmpl, inputs.messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt); data.format = COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2; @@ -1226,24 +1349,21 @@ static common_chat_params common_chat_params_init_functionary_v3_2(const common_ std::string name = function.at("name"); auto parameters = function.at("parameters"); builder.resolve_refs(parameters); + std::string args_pattern = "[\\s\\S]*"; auto args_rule = builder.add_schema(name + "-args", parameters); - first_tool_rules.push_back(builder.add_rule(name + "-call", "( \"assistant<|end_header_id|>\\n\" )? \"" + name + "\\n\" " + args_rule)); - subsequent_tool_rules.push_back(builder.add_rule(name + "-call2", "\">>>" + name + "\\n\" " + args_rule)); - data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START, - regex_escape(name + "\n"), - }); - data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START, - regex_escape("assistant<|end_header_id|>\n" + name + "\n"), - }); - data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_WORD, - regex_escape(">>>" + name + "\n"), - }); + if (name == "python") { + args_rule = builder.add_rule(name + "-maybe-raw-args", args_rule + " | [^{] .*"); + } else { + args_pattern = "\\{" + args_pattern; + } + auto call_rule = builder.add_rule(name + "-call", "\"" + name + "\\n\" " + args_rule); + first_tool_rules.push_back(call_rule); + if (inputs.parallel_tool_calls) { + subsequent_tool_rules.push_back(builder.add_rule(name + "-call2", "\">>>\" " + call_rule)); + } data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_WORD, - ">>>assistant<|end_header_id|>\n" + name, + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL, + "((?:[\\s\\S]+?>>>)?" + regex_escape(name) + "\n)" + args_pattern, }); }); data.preserved_tokens = { @@ -1261,40 +1381,33 @@ static common_chat_params common_chat_params_init_functionary_v3_2(const common_ } return data; } - -static common_chat_msg common_chat_parse_functionary_v3_2(const std::string & input) { - static const std::regex function_regex(R"((?:>>>)?(?:assistant<|end_header_id|>\n)?(\w+)\n)"); - static const std::regex close_regex(R"($|(?=>>>))"); - - std::string content; - auto it = input.begin(); - const auto end = input.end(); - - if (parse_literal(it, end, "all\n")) { - std::smatch match; - if (std::regex_search(it, end, match, function_regex)) { - auto fun_it = match.prefix().second; - content = std::string(it, fun_it); - it = fun_it; - } else { - common_chat_msg res; - res.role = "assistant"; - res.content = std::string(it, end); - return res; - } - } - // TODO: tighten & simplify. - try { - auto res = parse_json_tool_calls(std::string(it, end), std::nullopt, function_regex, close_regex, /* allow_raw_python= */ true); - res.content = content + res.content; - return res; - } catch (const std::exception & e) { - LOG_ERR("Failed to parse functionary v3.2 input: %s\n", e.what()); - common_chat_msg res; - res.role = "assistant"; - res.content = input; - return res; - } +static void common_chat_parse_functionary_v3_2(common_chat_msg_parser & builder) { + static const common_regex function_regex_start_only(R"((\w+\n\{|python\n|all\n))"); + static const common_regex function_regex(R"(>>>(\w+\n\{|python\n|all\n))"); + static const common_regex close_regex(R"(\s*)"); + + parse_json_tool_calls( + builder, + std::nullopt, + function_regex_start_only, + function_regex, + close_regex, + std::nullopt, + /* allow_raw_python= */ true, + /* get_function_name= */ [&](const auto & res) -> std::string { + auto at_start = res.groups[0].begin == 0; + auto name = builder.str(res.groups[1]); + if (!name.empty() && name.back() == '{') { + // Unconsume the opening brace '{' to ensure the JSON parsing goes well. + builder.move_back(1); + } + auto idx = name.find_last_not_of("\n{"); + name = name.substr(0, idx + 1); + if (at_start && name == "all") { + return ""; + } + return name; + }); } static common_chat_params common_chat_params_init_functionary_v3_1_llama_3_1(const common_chat_template & tmpl, const struct templates_params & inputs) { @@ -1355,229 +1468,224 @@ static common_chat_params common_chat_params_init_functionary_v3_1_llama_3_1(con // TODO: if (has_raw_python) return data; } -static common_chat_msg common_chat_parse_functionary_v3_1_llama_3_1(const std::string & input) { +static void common_chat_parse_functionary_v3_1_llama_3_1(common_chat_msg_parser & builder) { + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } // This version of Functionary still supports the llama 3.1 tool call format for the python tool. - static const std::regex python_tag_regex(R"(<\|python_tag\|>([\s\S\n]*)$)"); - std::smatch match; - if (std::regex_search(input, match, python_tag_regex)) { - auto code = match[1].str(); - common_chat_msg msg; - msg.role = "assistant"; - msg.content = match.prefix().str(); - msg.tool_calls.push_back({ - /* .name = */ "python", - /* .arguments = */ (json {{"code", code}}).dump(), - /* .id = */ "", - }); - return msg; + static const common_regex python_tag_regex(regex_escape("<|python_tag|>")); + + static const common_regex function_regex(R"()"); + static const common_regex close_regex(R"()"); + + parse_json_tool_calls( + builder, + /* block_open= */ std::nullopt, + /* function_regex_start_only= */ std::nullopt, + function_regex, + close_regex, + std::nullopt); + + if (auto res = builder.try_find_regex(python_tag_regex)) { + auto arguments = wrap_code_as_arguments(builder, builder.consume_rest()); + builder.add_tool_call("python", "", arguments); + return; } - static const std::regex function_regex(R"()"); - static const std::regex close_regex(R"()"); - // TODO: tighten & simplify. - return parse_json_tool_calls(input, std::nullopt, function_regex, close_regex); } static common_chat_params common_chat_params_init_hermes_2_pro(const common_chat_template & tmpl, const struct templates_params & inputs) { common_chat_params data; - // (content)?({"name": "foo", "arguments": {"a": 1}})* - data.grammar_lazy = inputs.tool_choice != COMMON_CHAT_TOOL_CHOICE_REQUIRED; - data.grammar = build_grammar([&](const common_grammar_builder & builder) { - std::vector tool_rules; - std::vector tool_call_alts; - foreach_function(inputs.tools, [&](const json & tool) { - const auto & function = tool.at("function"); - std::string name = function.at("name"); - auto parameters = function.at("parameters"); - builder.resolve_refs(parameters); - tool_rules.push_back(builder.add_schema(name + "-call", { - {"type", "object"}, - {"properties", json { - {"name", json {{"const", name}}}, - {"arguments", parameters}, - }}, - {"required", json::array({"name", "arguments"})}, - })); - tool_call_alts.push_back(builder.add_rule( - name + "-function-tag", - "\"\" space " + - builder.add_schema(name + "-args", parameters) + " " - "\"\" space")); - data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_WORD, - "", + json additional_context = { + {"enable_thinking", inputs.enable_thinking}, + }; + + data.prompt = apply(tmpl, inputs.messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt, additional_context); + data.format = COMMON_CHAT_FORMAT_HERMES_2_PRO; + if (string_ends_with(data.prompt, "\n")) { + if (!inputs.enable_thinking) { + data.prompt += ""; + } else { + data.thinking_forced_open = true; + } + } + + if (!inputs.tools.is_null()) { + // (content)?({"name": "foo", "arguments": {"a": 1}})* + data.grammar_lazy = inputs.tool_choice != COMMON_CHAT_TOOL_CHOICE_REQUIRED; + data.grammar = build_grammar([&](const common_grammar_builder & builder) { + std::vector tool_rules; + std::vector tool_call_alts; + std::vector escaped_names; + foreach_function(inputs.tools, [&](const json & tool) { + const auto & function = tool.at("function"); + std::string name = function.at("name"); + auto parameters = function.at("parameters"); + builder.resolve_refs(parameters); + tool_rules.push_back(builder.add_schema(name + "-call", { + {"type", "object"}, + {"properties", json { + {"name", json {{"const", name}}}, + {"arguments", parameters}, + }}, + {"required", json::array({"name", "arguments"})}, + })); + tool_call_alts.push_back(builder.add_rule( + name + "-function-tag", + "\"\" space " + + builder.add_schema(name + "-args", parameters) + " " + "\"\" space")); + + data.grammar_triggers.push_back({ + COMMON_GRAMMAR_TRIGGER_TYPE_WORD, + "", + }); + auto escaped_name = regex_escape(name); + data.grammar_triggers.push_back({ + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN, + " alt_tags { + any_tool_call, + "\"\" space " + any_tool_call + " \"\"", + // The rest is just to accommodate common "good bad" outputs. + "\"\" space " + any_tool_call + " \"\"", + "\"\" space " + any_tool_call + " \"\"", + "\"\" space " + any_tool_call + " \"\"", + "\"\" space " + any_tool_call + " \"\"", + "\"\" space " + any_tool_call + " \"\"", + "\"\" space " + any_tool_call + " \"\"", + }; + auto wrappable_tool_call = builder.add_rule("wrappable_tool_call", "( " + string_join(alt_tags, " | ") + " ) space"); + tool_call_alts.push_back(wrappable_tool_call); + tool_call_alts.push_back( + "( \"```\\n\" | \"```json\\n\" | \"```xml\\n\" ) space " + wrappable_tool_call + " space \"```\" space "); + auto tool_call = builder.add_rule("tool_call", string_join(tool_call_alts, " | ")); + builder.add_rule("root", + std::string(data.thinking_forced_open ? "( \"\" space )? " : "") + + (inputs.parallel_tool_calls ? "(" + tool_call + ")+" : tool_call)); + // Trigger on some common known "good bad" outputs (only from the start and with a json that's about a specific argument name to avoid false positives) data.grammar_triggers.push_back({ - COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN, - " tag in the grammar, + // (important for required tool choice) and in the trigger's first capture (decides what is sent to the grammar) + std::string(data.thinking_forced_open ? "[\\s\\S]*?(\\s*)" : "(?:[\\s\\S]*?\\s*)?") + ( + "(\\s*" + "(?:" + "||||)?" + "\\s*\\{\\s*\"name\"\\s*:\\s*\"(?:" + string_join(escaped_names, "|") + ")\"" + ")" + ")[\\s\\S]*" + ), }); + data.preserved_tokens = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "```", + "```json", + "```xml", + }; }); - auto any_tool_call = builder.add_rule("any_tool_call", "( " + string_join(tool_rules, " | ") + " ) space"); - std::vector alt_tags { - any_tool_call, - "\"\" space " + any_tool_call + " \"\"", - // The rest is just to accommodate common "good bad" outputs. - "\"\" space " + any_tool_call + " \"\"", - "\"\" space " + any_tool_call + " \"\"", - "\"\" space " + any_tool_call + " \"\"", - "\"\" space " + any_tool_call + " \"\"", - "\"\" space " + any_tool_call + " \"\"", - "\"\" space " + any_tool_call + " \"\"", - }; - auto wrappable_tool_call = builder.add_rule("wrappable_tool_call", "( " + string_join(alt_tags, " | ") + " ) space"); - tool_call_alts.push_back(wrappable_tool_call); - tool_call_alts.push_back( - "( \"```\\n\" | \"```json\\n\" | \"```xml\\n\" ) space " + wrappable_tool_call + " space \"```\" space "); - auto tool_call = builder.add_rule("tool_call", string_join(tool_call_alts, " | ")); - builder.add_rule("root", inputs.parallel_tool_calls ? "(" + tool_call + ")+" : tool_call); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, ""}); - data.grammar_triggers.push_back({COMMON_GRAMMAR_TRIGGER_TYPE_WORD, "|||)?\\s*\\{\\s*\"", //name\"\\s*:\\s*\"" + escaped_name + "\"", - }); - data.preserved_tokens = { - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "```", - "```json", - "```xml", - }; - }); + } - data.prompt = apply(tmpl, inputs.messages, inputs.tools.empty() ? json() : inputs.tools, inputs.add_generation_prompt); - data.format = inputs.extract_reasoning ? COMMON_CHAT_FORMAT_HERMES_2_PRO_EXTRACT_REASONING : COMMON_CHAT_FORMAT_HERMES_2_PRO; return data; } -static common_chat_msg common_chat_parse_hermes_2_pro(const std::string& input, bool extract_reasoning) { - return handle_think_tag_prelude(input, extract_reasoning, [](const std::string & input) { - static const std::regex open_regex( - "(?:" - "(```(?:xml|json)?\\n\\s*)?" // match 1 (block_start) - "(" // match 2 (open_tag) - "|" - "|" - "|" - "|" - "|" - "|" - "|" +static void common_chat_parse_hermes_2_pro(common_chat_msg_parser & builder) { + builder.try_parse_reasoning("", ""); + if (!builder.syntax().parse_tool_calls) { + builder.add_content(builder.consume_rest()); + return; + } + + static const common_regex open_regex( + "(?:" + "(```(?:xml|json)?\\n\\s*)?" // match 1 (block_start) + "(" // match 2 (open_tag) + "" + "|" + "|" + "|" + "|" + "|" + "|" + "|" ")?" - "(\\s*\\{\\s*\"name\"\\s*:[\\s\\S]*)" // match 3 (named tool call + rest) - ")" - "|" - "(?:]+)>" // match 4 (function name) - "|)" // match 5 (function name again) - "([\\s\\S]*)" // match 6 (function arguments + rest)})" - ); - - try { - common_chat_msg msg; - msg.role = "assistant"; - - std::string::const_iterator it = input.begin(); - const std::string::const_iterator end = input.end(); - std::smatch match; - - while (it != end) { - if (std::regex_search(it, end, match, open_regex)) { - // Add content before the match - msg.content += std::string(it, match[0].first); - - auto block_start = match[1].str(); - std::string block_end = block_start.empty() ? "" : "```"; - - auto open_tag = match[2].str(); - std::string close_tag; - - if (match[3].matched) { - close_tag = open_tag.empty() ? "" : "]+)>" // match 4 (function name) + "|" // match 5 (function name again) + ); + + if (auto res = builder.try_find_regex(open_regex)) { + const auto & block_start = res->groups[1]; + std::string block_end = block_start.empty() ? "" : "```"; + + const auto & open_tag = res->groups[2]; + std::string close_tag; + + if (!res->groups[3].empty()) { + builder.move_to(res->groups[3].begin); + close_tag = open_tag.empty() ? "" : "value) || tool_call->is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + builder.consume_spaces(); + builder.consume_literal(close_tag); + builder.consume_spaces(); + if (!block_end.empty()) { + builder.consume_literal(block_end); + builder.consume_spaces(); + } + builder.add_content(builder.consume_rest()); + } else { + throw common_chat_msg_partial_exception("failed to parse tool call"); + } + } else { + auto function_name = builder.str(res->groups[4]); + if (function_name.empty()) { + function_name = builder.str(res->groups[5]); + } + GGML_ASSERT(!function_name.empty()); - msg.tool_calls.emplace_back(process_tool_call(tool_call)); - it = json_it; // Move iterator past parsed JSON + close_tag = ""; - // Handle close tags - consume_spaces(it, end); - if (!close_tag.empty() && !parse_literal(it, end, close_tag)) { - throw std::runtime_error("Failed to parse closing tag"); - } - consume_spaces(it, end); - if (!block_end.empty() && !parse_literal(it, end, block_end)) { - throw std::runtime_error("Failed to parse block end"); - } - consume_spaces(it, end); - } else { - // Not a valid tool call, treat as content - msg.content += std::string(match[0].first, match[0].second); - it = match[0].second; - } - } else { - auto function_name = match[4].str(); - if (function_name.empty()) { - function_name = match[5].str(); - } - GGML_ASSERT(!function_name.empty()); - - close_tag = ""; - // Start parsing from after the opening tags - auto json_it = match[6].first; - json arguments; - if (parse_json(json_it, end, arguments)) { - msg.tool_calls.emplace_back(process_tool_call({ - {"name", function_name}, - {"arguments", arguments}, - })); - it = json_it; // Move iterator past parsed JSON - - // Handle close tags - consume_spaces(it, end); - if (!close_tag.empty() && !parse_literal(it, end, close_tag)) { - throw std::runtime_error("Failed to parse closing tag"); - } - consume_spaces(it, end); - if (!block_end.empty() && !parse_literal(it, end, block_end)) { - throw std::runtime_error("Failed to parse block end"); - } - consume_spaces(it, end); - } else { - // Not a valid tool call, treat as content - msg.content += std::string(match[0].first, match[0].second); - it = match[0].second; - } - } - } else { - // Add remaining content - msg.content += std::string(it, end); - break; + if (auto arguments = builder.try_consume_json_with_dumped_args({{}})) { + if (!builder.add_tool_call(function_name, "", arguments->value) || arguments->is_partial) { + throw common_chat_msg_partial_exception("incomplete tool call"); + } + builder.consume_spaces(); + builder.consume_literal(close_tag); + builder.consume_spaces(); + if (!block_end.empty()) { + builder.consume_literal(block_end); + builder.consume_spaces(); } } - return msg; - } catch (const std::exception & e) { - LOG_ERR("Failed to parse hermes 2 pro input: %s\n", e.what()); - common_chat_msg msg; - msg.role = "assistant"; - msg.content = input; - return msg; + builder.add_content(builder.consume_rest()); } - }); + } else { + builder.add_content(builder.consume_rest()); + } } static common_chat_params common_chat_params_init_without_tools(const common_chat_template & tmpl, const struct templates_params & inputs) { @@ -1609,8 +1717,8 @@ static common_chat_params common_chat_templates_apply_jinja( const auto & caps = tmpl.original_caps(); params.messages = common_chat_msgs_to_json_oaicompat(inputs.messages, /* concat_text= */ !tmpl.original_caps().requires_typed_content); params.add_generation_prompt = inputs.add_generation_prompt; - params.extract_reasoning = inputs.extract_reasoning; params.tool_choice = inputs.tool_choice; + params.enable_thinking = inputs.enable_thinking; params.grammar = inputs.grammar; params.now = inputs.now; if (!inputs.json_schema.empty()) { @@ -1644,7 +1752,7 @@ static common_chat_params common_chat_templates_apply_jinja( } // Hermes 2/3 Pro, Qwen 2.5 Instruct (w/ tools) - if (src.find("") != std::string::npos && params.json_schema.is_null() && params.tools.is_array() && params.json_schema.is_null()) { + if (src.find("") != std::string::npos && params.json_schema.is_null()) { return common_chat_params_init_hermes_2_pro(tmpl, params); } @@ -1758,44 +1866,64 @@ common_chat_params common_chat_templates_apply( : common_chat_templates_apply_legacy(tmpls, inputs); } -static common_chat_msg common_chat_parse_content_only(const std::string & input) { - common_chat_msg msg; - msg.role = "assistant"; - msg.content = input; - return msg; +static void common_chat_parse_content_only(common_chat_msg_parser & builder) { + builder.add_content(builder.consume_rest()); } -common_chat_msg common_chat_parse(const std::string & input, common_chat_format format) { - switch (format) { +static void common_chat_parse(common_chat_msg_parser & builder) { + LOG_DBG("Parsing input with format %s: %s\n", common_chat_format_name(builder.syntax().format), builder.input().c_str()); + + switch (builder.syntax().format) { case COMMON_CHAT_FORMAT_CONTENT_ONLY: - return common_chat_parse_content_only(input); + common_chat_parse_content_only(builder); + break; case COMMON_CHAT_FORMAT_GENERIC: - return common_chat_parse_generic(input); + common_chat_parse_generic(builder); + break; case COMMON_CHAT_FORMAT_MISTRAL_NEMO: - return common_chat_parse_mistral_nemo(input); + common_chat_parse_mistral_nemo(builder); + break; case COMMON_CHAT_FORMAT_LLAMA_3_X: - return common_chat_parse_llama_3_1(input); + common_chat_parse_llama_3_1(builder); + break; case COMMON_CHAT_FORMAT_LLAMA_3_X_WITH_BUILTIN_TOOLS: - return common_chat_parse_llama_3_1(input, /* with_builtin_tools= */ true); + common_chat_parse_llama_3_1(builder, /* with_builtin_tools= */ true); + break; case COMMON_CHAT_FORMAT_DEEPSEEK_R1: - return common_chat_parse_deepseek_r1(input, /* extract_reasoning= */ false); - case COMMON_CHAT_FORMAT_DEEPSEEK_R1_EXTRACT_REASONING: - return common_chat_parse_deepseek_r1(input, /* extract_reasoning= */ true); + common_chat_parse_deepseek_r1(builder); + break; case COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2: - return common_chat_parse_functionary_v3_2(input); + common_chat_parse_functionary_v3_2(builder); + break; case COMMON_CHAT_FORMAT_FUNCTIONARY_V3_1_LLAMA_3_1: - return common_chat_parse_functionary_v3_1_llama_3_1(input); + common_chat_parse_functionary_v3_1_llama_3_1(builder); + break; case COMMON_CHAT_FORMAT_HERMES_2_PRO: - return common_chat_parse_hermes_2_pro(input, /* extract_reasoning= */ false); - case COMMON_CHAT_FORMAT_HERMES_2_PRO_EXTRACT_REASONING: - return common_chat_parse_hermes_2_pro(input, /* extract_reasoning= */ true); + common_chat_parse_hermes_2_pro(builder); + break; case COMMON_CHAT_FORMAT_FIREFUNCTION_V2: - return common_chat_parse_firefunction_v2(input); + common_chat_parse_firefunction_v2(builder); + break; case COMMON_CHAT_FORMAT_COMMAND_R7B: - return common_chat_parse_command_r7b(input, /* extract_reasoning= */ false); - case COMMON_CHAT_FORMAT_COMMAND_R7B_EXTRACT_REASONING: - return common_chat_parse_command_r7b(input, /* extract_reasoning= */ true); + common_chat_parse_command_r7b(builder); + break; default: - throw std::runtime_error("Unsupported format: " + common_chat_format_name(format)); + throw std::runtime_error(std::string("Unsupported format: ") + common_chat_format_name(builder.syntax().format)); + } + builder.finish(); +} + +common_chat_msg common_chat_parse(const std::string & input, bool is_partial, const common_chat_syntax & syntax) { + common_chat_msg_parser builder(input, is_partial, syntax); + try { + common_chat_parse(builder); + } catch (const common_chat_msg_partial_exception & ex) { + LOG_DBG("Partial parse: %s\n", ex.what()); + if (!is_partial) { + throw std::runtime_error(ex.what()); + } } + auto msg = builder.result(); + LOG_DBG("Parsed message: %s\n", common_chat_msgs_to_json_oaicompat({msg}).at(0).dump().c_str()); + return msg; } diff --git a/common/chat.h b/common/chat.h index d26a09c2f7c4f..f6b1d0ffcc989 100644 --- a/common/chat.h +++ b/common/chat.h @@ -3,6 +3,7 @@ #pragma once #include "common.h" +#include #include #include #include @@ -13,11 +14,19 @@ struct common_chat_tool_call { std::string name; std::string arguments; std::string id; + + bool operator==(const common_chat_tool_call & other) const { + return name == other.name && arguments == other.arguments && id == other.id; + } }; struct common_chat_msg_content_part { std::string type; std::string text; + + bool operator==(const common_chat_msg_content_part & other) const { + return type == other.type && text == other.text; + } }; struct common_chat_msg { @@ -28,6 +37,51 @@ struct common_chat_msg { std::string reasoning_content; std::string tool_name; std::string tool_call_id; + + template T to_json_oaicompat() const; + + bool empty() const { + return content.empty() && content_parts.empty() && tool_calls.empty() && reasoning_content.empty() && tool_name.empty() && tool_call_id.empty(); + } + void ensure_tool_call_ids_set(std::vector & ids_cache, const std::function & gen_tool_call_id) { + for (auto i = 0u; i < tool_calls.size(); i++) { + if (ids_cache.size() <= i) { + auto id = tool_calls[i].id; + if (id.empty()) { + id = gen_tool_call_id(); + } + ids_cache.push_back(id); + } + tool_calls[i].id = ids_cache[i]; + } + } + bool operator==(const common_chat_msg & other) const { + return role == other.role + && content == other.content + && content_parts == other.content_parts + && tool_calls == other.tool_calls + && reasoning_content == other.reasoning_content + && tool_name == other.tool_name + && tool_call_id == other.tool_call_id; + } + bool operator!=(const common_chat_msg & other) const { + return !(*this == other); + } +}; + +struct common_chat_msg_diff { + // std::string reasoning_content_delta; + std::string content_delta; + size_t tool_call_index = std::string::npos; + common_chat_tool_call tool_call_delta; + + static std::vector compute_diffs(const common_chat_msg & previous_msg, const common_chat_msg & new_msg); + + bool operator==(const common_chat_msg_diff & other) const { + return content_delta == other.content_delta + && tool_call_index == other.tool_call_index + && tool_call_delta == other.tool_call_delta; + } }; struct common_chat_tool { @@ -49,14 +103,11 @@ enum common_chat_format { COMMON_CHAT_FORMAT_LLAMA_3_X, COMMON_CHAT_FORMAT_LLAMA_3_X_WITH_BUILTIN_TOOLS, COMMON_CHAT_FORMAT_DEEPSEEK_R1, - COMMON_CHAT_FORMAT_DEEPSEEK_R1_EXTRACT_REASONING, COMMON_CHAT_FORMAT_FIREFUNCTION_V2, COMMON_CHAT_FORMAT_FUNCTIONARY_V3_2, COMMON_CHAT_FORMAT_FUNCTIONARY_V3_1_LLAMA_3_1, COMMON_CHAT_FORMAT_HERMES_2_PRO, - COMMON_CHAT_FORMAT_HERMES_2_PRO_EXTRACT_REASONING, COMMON_CHAT_FORMAT_COMMAND_R7B, - COMMON_CHAT_FORMAT_COMMAND_R7B_EXTRACT_REASONING, COMMON_CHAT_FORMAT_COUNT, // Not a format, just the # formats }; @@ -71,7 +122,8 @@ struct common_chat_templates_inputs { std::vector tools; common_chat_tool_choice tool_choice = COMMON_CHAT_TOOL_CHOICE_AUTO; bool parallel_tool_calls = false; - bool extract_reasoning = true; + common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_NONE; + bool enable_thinking = true; std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); }; @@ -80,11 +132,21 @@ struct common_chat_params { std::string prompt; std::string grammar; bool grammar_lazy = false; + bool thinking_forced_open = false; std::vector grammar_triggers; std::vector preserved_tokens; std::vector additional_stops; }; +struct common_chat_syntax { + common_chat_format format = COMMON_CHAT_FORMAT_CONTENT_ONLY; + common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_NONE; + // Whether reasoning_content should be inlined in the content (e.g. for reasoning_format=deepseek in stream mode) + bool reasoning_in_content = false; + bool thinking_forced_open = false; + bool parse_tool_calls = true; +}; + // Check if the template supplied via "--chat-template" is supported or not. Returns true if it's valid bool common_chat_verify_template(const std::string & tmpl, bool use_jinja); @@ -121,8 +183,9 @@ std::string common_chat_format_example( const struct common_chat_templates * tmpls, bool use_jinja); -std::string common_chat_format_name(common_chat_format format); -common_chat_msg common_chat_parse( const std::string & input, common_chat_format format); +const char* common_chat_format_name(common_chat_format format); +const char* common_reasoning_format_name(common_reasoning_format format); +common_chat_msg common_chat_parse(const std::string & input, bool is_partial, const common_chat_syntax & syntax); common_chat_tool_choice common_chat_tool_choice_parse_oaicompat(const std::string & tool_choice); @@ -135,3 +198,5 @@ template T common_chat_msgs_to_json_oaicompat(const std::vector std::vector common_chat_tools_parse_oaicompat(const T & tools); template T common_chat_tools_to_json_oaicompat(const std::vector & tools); + +template T common_chat_msg_diff_to_json_oaicompat(const common_chat_msg_diff & diff); diff --git a/common/common.cpp b/common/common.cpp index 62e922a99c092..4cc40ed8b37a4 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -203,6 +203,7 @@ bool set_process_priority(enum ggml_sched_priority prio) { DWORD p = NORMAL_PRIORITY_CLASS; switch (prio) { + case GGML_SCHED_PRIO_LOW: p = BELOW_NORMAL_PRIORITY_CLASS; break; case GGML_SCHED_PRIO_NORMAL: p = NORMAL_PRIORITY_CLASS; break; case GGML_SCHED_PRIO_MEDIUM: p = ABOVE_NORMAL_PRIORITY_CLASS; break; case GGML_SCHED_PRIO_HIGH: p = HIGH_PRIORITY_CLASS; break; @@ -228,6 +229,7 @@ bool set_process_priority(enum ggml_sched_priority prio) { int p = 0; switch (prio) { + case GGML_SCHED_PRIO_LOW: p = 5; break; case GGML_SCHED_PRIO_NORMAL: p = 0; break; case GGML_SCHED_PRIO_MEDIUM: p = -5; break; case GGML_SCHED_PRIO_HIGH: p = -10; break; @@ -849,7 +851,7 @@ std::string fs_get_cache_directory() { if (getenv("LLAMA_CACHE")) { cache_directory = std::getenv("LLAMA_CACHE"); } else { -#if defined(__linux__) || defined(__FreeBSD__) || defined(_AIX) +#if defined(__linux__) || defined(__FreeBSD__) || defined(_AIX) || defined(__OpenBSD__) if (std::getenv("XDG_CACHE_HOME")) { cache_directory = std::getenv("XDG_CACHE_HOME"); } else { @@ -903,13 +905,16 @@ struct common_init_result common_init_from_params(common_params & params) { ok = false; } - if (llama_vocab_eos(vocab) == LLAMA_TOKEN_NULL) { - LOG_WRN("%s: warning: vocab does not have an EOS token, reranking will not work\n", __func__); - ok = false; - } + bool has_eos = llama_vocab_eos(vocab) != LLAMA_TOKEN_NULL; + bool has_sep = llama_vocab_sep(vocab) != LLAMA_TOKEN_NULL; - if (llama_vocab_sep(vocab) == LLAMA_TOKEN_NULL) { - LOG_WRN("%s: warning: vocab does not have a SEP token, reranking will not work\n", __func__); + if (!has_eos && !has_sep) { + LOG_WRN("%s: warning: vocab does not have an EOS token or SEP token, reranking will not work\n", __func__); + ok = false; + } else if (!has_eos) { + LOG_WRN("%s: warning: vocab does not have an EOS token, using SEP token as fallback\n", __func__); + } else if (!has_sep) { + LOG_WRN("%s: warning: vocab does not have a SEP token, reranking will not work\n", __func__); ok = false; } @@ -1102,6 +1107,9 @@ struct llama_model_params common_model_params_to_llama(common_params & params) { mparams.tensor_buft_overrides = params.tensor_buft_overrides.data(); } + mparams.progress_callback = params.load_progress_callback; + mparams.progress_callback_user_data = params.load_progress_callback_user_data; + return mparams; } @@ -1133,6 +1141,7 @@ struct llama_context_params common_context_params_to_llama(const common_params & cparams.flash_attn = params.flash_attn; cparams.no_perf = params.no_perf; cparams.op_offload = !params.no_op_offload; + cparams.swa_full = params.swa_full; if (params.reranking) { cparams.embeddings = true; @@ -1325,81 +1334,6 @@ std::string common_detokenize(const struct llama_vocab * vocab, const std::vecto return text; } -// -// KV cache utils -// - -void common_kv_cache_dump_view(const llama_kv_cache_view & view, int row_size) { - static const char slot_chars[] = ".123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+"; - - printf("=== Dumping KV cache. total cells %d, max sequences per cell %d, populated cells %d, total tokens in cache %d, largest empty slot=%d @ %d", - view.n_cells, view.n_seq_max, view.used_cells, view.token_count, view.max_contiguous, view.max_contiguous_idx); - - llama_kv_cache_view_cell * c_curr = view.cells; - llama_seq_id * cs_curr = view.cells_sequences; - - for (int i = 0; i < view.n_cells; i++, c_curr++, cs_curr += view.n_seq_max) { - if (i % row_size == 0) { - printf("\n%5d: ", i); - } - int seq_count = 0; - for (int j = 0; j < view.n_seq_max; j++) { - if (cs_curr[j] >= 0) { seq_count++; } - } - putchar(slot_chars[std::min(sizeof(slot_chars) - 2, size_t(seq_count))]); - } - - printf("\n=== Done dumping\n"); -} - -void common_kv_cache_dump_view_seqs(const llama_kv_cache_view & view, int row_size) { - static const char slot_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - printf("=== Dumping KV cache. total cells %d, max sequences per cell %d, populated cells %d, total tokens in cache %d, largest empty slot=%d @ %d\n", - view.n_cells, view.n_seq_max, view.used_cells, view.token_count, view.max_contiguous, view.max_contiguous_idx); - - std::unordered_map seqs; - llama_kv_cache_view_cell * c_curr = view.cells; - llama_seq_id * cs_curr = view.cells_sequences; - - for (int i = 0; i < view.n_cells; i++, c_curr++, cs_curr += view.n_seq_max) { - for (int j = 0; j < view.n_seq_max; j++) { - if (cs_curr[j] < 0) { continue; } - if (seqs.find(cs_curr[j]) == seqs.end()) { - if (seqs.size() + 1 >= sizeof(slot_chars)) { break; } - const size_t sz = seqs.size(); - seqs[cs_curr[j]] = sz; - } - } - if (seqs.size() + 1 >= sizeof(slot_chars)) { break; } - } - - printf("=== Sequence legend: "); - for (const auto & it : seqs) { - printf("%zu=%d, ", it.second, it.first); - } - printf("'+'=other sequence ids"); - - c_curr = view.cells; - cs_curr = view.cells_sequences; - for (int i = 0; i < view.n_cells; i++, c_curr++, cs_curr += view.n_seq_max) { - if (i % row_size == 0) { - printf("\n%5d: ", i); - } - for (int j = 0; j < view.n_seq_max; j++) { - if (cs_curr[j] >= 0) { - const auto & it = seqs.find(cs_curr[j]); - putchar(it != seqs.end() ? int(slot_chars[it->second]) : '+'); - } else { - putchar('.'); - } - } - putchar(' '); - } - - printf("\n=== Done dumping\n"); -} - // // Embedding utils // diff --git a/common/common.h b/common/common.h index da525dd420b7d..cee1e3039cf9e 100644 --- a/common/common.h +++ b/common/common.h @@ -76,7 +76,7 @@ enum llama_example { LLAMA_EXAMPLE_SERVER, LLAMA_EXAMPLE_CVECTOR_GENERATOR, LLAMA_EXAMPLE_EXPORT_LORA, - LLAMA_EXAMPLE_LLAVA, + LLAMA_EXAMPLE_MTMD, LLAMA_EXAMPLE_LOOKUP, LLAMA_EXAMPLE_PARALLEL, LLAMA_EXAMPLE_TTS, @@ -115,7 +115,7 @@ enum common_grammar_trigger_type { COMMON_GRAMMAR_TRIGGER_TYPE_TOKEN, COMMON_GRAMMAR_TRIGGER_TYPE_WORD, COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN, - COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START, + COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL, }; struct common_grammar_trigger { @@ -291,6 +291,7 @@ struct common_params { int32_t verbosity = 0; int32_t control_vector_layer_start = -1; // layer range for control vector int32_t control_vector_layer_end = -1; // layer range for control vector + bool offline = false; int32_t ppl_stride = 0; // stride for perplexity calculations. If left at 0, the pre-existing approach will be used. int32_t ppl_output_type = 0; // = 0 -> ppl output is as usual, = 1 -> ppl output is num_tokens, ppl, one per line @@ -323,13 +324,13 @@ struct common_params { bool flash_attn = false; // flash attention bool no_perf = false; // disable performance metrics bool ctx_shift = true; // context shift on inifinite text generation + bool swa_full = false; // use full-size SWA cache (https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055) bool input_prefix_bos = false; // prefix BOS to user inputs, preceding input_prefix bool use_mmap = true; // use mmap for faster loads bool use_mlock = false; // use mlock to keep model in memory bool verbose_prompt = false; // print prompt tokens before generation bool display_prompt = true; // print prompt before generation - bool dump_kv_cache = false; // dump the KV cache contents for debugging purposes bool no_kv_offload = false; // disable KV offloading bool warmup = true; // warmup run bool check_tensors = false; // validate tensor data @@ -368,6 +369,7 @@ struct common_params { bool use_jinja = false; // NOLINT bool enable_chat_template = true; common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK; + int reasoning_budget = -1; bool prefill_assistant = true; // if true, any trailing assistant message will be prefilled into the response std::vector api_keys; @@ -428,6 +430,11 @@ struct common_params { // common params std::string out_file; // output filename for all example programs + // optional callback for model loading progress and cancellation: + // called with a progress value between 0.0 and 1.0. + // return false from callback to abort model loading or true to continue + llama_progress_callback load_progress_callback = NULL; + void * load_progress_callback_user_data = NULL; }; // call once at the start of a program if it uses libcommon @@ -616,16 +623,6 @@ std::string common_detokenize( const std::vector & tokens, bool special = true); -// -// KV cache utils -// - -// Dump the KV cache view with the number of sequences per cell. -void common_kv_cache_dump_view(const llama_kv_cache_view & view, int row_size = 80); - -// Dump the KV cache view showing individual sequences in each cell (long output). -void common_kv_cache_dump_view_seqs(const llama_kv_cache_view & view, int row_size = 40); - // // Embedding utils // diff --git a/common/json-partial.cpp b/common/json-partial.cpp new file mode 100644 index 0000000000000..d9d91699899f7 --- /dev/null +++ b/common/json-partial.cpp @@ -0,0 +1,256 @@ +#include "json-partial.h" + +#include "log.h" + +#include + +#include + +using json = nlohmann::ordered_json; + +enum common_json_stack_element_type { + COMMON_JSON_STACK_ELEMENT_OBJECT, + COMMON_JSON_STACK_ELEMENT_KEY, + COMMON_JSON_STACK_ELEMENT_ARRAY, +}; + +struct common_json_stack_element { + common_json_stack_element_type type; + std::string key; +}; + +bool common_json_parse( + const std::string & input, + const std::string & healing_marker, + common_json & out) +{ + std::string::const_iterator it = input.begin(); + const auto end = input.end(); + return common_json_parse(it, end, healing_marker, out); +} + +bool common_json_parse( + std::string::const_iterator & it, + const std::string::const_iterator & end, + const std::string & healing_marker, + common_json & out) +{ + // // https://json.nlohmann.me/features/parsing/sax_interface/ + struct json_error_locator : public nlohmann::json_sax { + std::size_t position; + bool found_error; + std::string last_token; + std::string exception_message; + std::vector stack; + + json_error_locator() : position(0), found_error(false) {} + + bool parse_error(std::size_t position, const std::string & last_token, const json::exception & ex) override { // NOLINT + this->position = position - 1; + this->found_error = true; + this->last_token = last_token; + this->exception_message = ex.what(); + return false; + } + void close_value() { + if (!stack.empty() && (stack.back().type == COMMON_JSON_STACK_ELEMENT_KEY)) { + stack.pop_back(); + } + } + bool null() override { // NOLINT + close_value(); + return true; + } + bool boolean(bool) override { // NOLINT + close_value(); + return true; + } + bool number_integer(number_integer_t) override { // NOLINT + close_value(); + return true; + } + bool number_unsigned(number_unsigned_t) override { // NOLINT + close_value(); + return true; + } + bool number_float(number_float_t, const string_t &) override { // NOLINT + close_value(); + return true; + } + bool string(string_t &) override { // NOLINT + close_value(); + return true; + } + bool binary(binary_t &) override { // NOLINT + close_value(); + return true; + } + bool start_object(std::size_t) override { // NOLINT + stack.push_back({COMMON_JSON_STACK_ELEMENT_OBJECT, ""}); + return true; + } + bool end_object() override { + GGML_ASSERT(!stack.empty() && stack.back().type == COMMON_JSON_STACK_ELEMENT_OBJECT); + stack.pop_back(); + close_value(); + return true; + } + bool key(string_t & key) override { // NOLINT + stack.push_back({COMMON_JSON_STACK_ELEMENT_KEY, key}); + return true; + } + bool start_array(std::size_t) override { // NOLINT + stack.push_back({COMMON_JSON_STACK_ELEMENT_ARRAY, ""}); + return true; + } + bool end_array() override { + GGML_ASSERT(!stack.empty() && stack.back().type == COMMON_JSON_STACK_ELEMENT_ARRAY); + stack.pop_back(); + close_value(); + return true; + } + }; + json_error_locator err_loc; + auto start = it; + json::sax_parse(it, end, &err_loc); + + if (err_loc.found_error) { + it = start; + auto temptative_end = it + err_loc.position; + // LOG_DBG("Error at position %zu (is_end = %s): %s\n", err_loc.position, temptative_end == end ? "true" : "false", err_loc.exception_message.c_str()); + + auto input = std::string(it, temptative_end); + try { + out.json = json::parse(input); + // out.json = json::parse(it, temptative_end); + it = temptative_end; + return true; + } catch (const std::exception & ex) { + // No, needs healing. + LOG_DBG("Failed to parse up to error: %s: <<<%s>>>\n", ex.what(), std::string(it, temptative_end).c_str()); + } + auto can_parse = [](const std::string & str) { + try { + auto _ = json::parse(str); // NOLINT + return true; + } catch (const std::exception &) { + return false; + } + }; + if (!healing_marker.empty() && !err_loc.stack.empty()) { + std::string str(it, temptative_end); + auto last_non_sp_pos = str.find_last_not_of(" \n\r\t"); + if (last_non_sp_pos == std::string::npos) { + throw std::runtime_error("Cannot heal a truncated JSON that stopped in an unknown location"); + } + auto last_non_sp_char = str[last_non_sp_pos]; + // Used to detect stops on a number, which may not be complete. + auto was_maybe_number = [&]() { + if (!str.empty() && std::isspace(str.back())) { + return false; + } + return std::isdigit(last_non_sp_char) || + last_non_sp_char == '.' || + last_non_sp_char == 'e' || + last_non_sp_char == 'E' || + last_non_sp_char == '-'; + }; + + std::string closing; + for (size_t i = err_loc.stack.size(); i > 0; i--) { + auto & el = err_loc.stack[i - 1]; + if (el.type == COMMON_JSON_STACK_ELEMENT_OBJECT) { + closing += "}"; + } else if (el.type == COMMON_JSON_STACK_ELEMENT_ARRAY) { + closing += "]"; + } else if (el.type != COMMON_JSON_STACK_ELEMENT_KEY) { + throw std::runtime_error("Unexpected stack element type"); + } + } + + const auto & magic_seed = out.healing_marker.marker = healing_marker;//"$llama.cpp.json$"; + + if (err_loc.stack.back().type == COMMON_JSON_STACK_ELEMENT_KEY) { + // We're inside an object value + if (last_non_sp_char == ':' && can_parse(str + "1" + closing)) { + // Was about to create an object value + str += (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\"" + closing; + } else if (can_parse(str + ": 1" + closing)) { + str += (out.healing_marker.json_dump_marker = ":\"" + magic_seed) + "\"" + closing; + } else if (last_non_sp_char == '{' && can_parse(str + closing)) { + // Was about to create an object + str += (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\": 1" + closing; + } else if (can_parse(str + "\"" + closing)) { + // Was inside an object value string + str += (out.healing_marker.json_dump_marker = magic_seed) + "\"" + closing; + } else if (str[str.length() - 1] == '\\' && can_parse(str + "\\\"" + closing)) { + // Was inside an object value string after an escape + str += (out.healing_marker.json_dump_marker = "\\" + magic_seed) + "\"" + closing; + } else { + // find last : + auto last_pos = str.find_last_of(':'); + if (last_pos == std::string::npos) { + throw std::runtime_error("Cannot heal a truncated JSON that stopped in an unknown location"); + } + // Cutting back to opening : for object value + str = str.substr(0, last_pos + 1) + (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\"" + closing; + } + } else if (err_loc.stack.back().type == COMMON_JSON_STACK_ELEMENT_ARRAY) { + if ((last_non_sp_char == ',' || last_non_sp_char == '[') && can_parse(str + "1" + closing)) { + // Was about to create an array value + str += (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\"" + closing; + } else if (can_parse(str + "\"" + closing)) { + // Was inside an array value string + str += (out.healing_marker.json_dump_marker = magic_seed) + "\"" + closing; + } else if (str[str.length() - 1] == '\\' && can_parse(str + "\\\"" + closing)) { + // Was inside an array value string after an escape + str += (out.healing_marker.json_dump_marker = "\\" + magic_seed) + "\"" + closing; + } else if (!was_maybe_number() && can_parse(str + ", 1" + closing)) { + // Had just finished a value + str += (out.healing_marker.json_dump_marker = ",\"" + magic_seed) + "\"" + closing; + } else { + auto last_pos = str.find_last_of("[,"); + if (last_pos == std::string::npos) { + throw std::runtime_error("Cannot heal a truncated JSON array stopped in an unknown location"); + } + // Cutting back to last [ or , for array value + str = str.substr(0, last_pos + 1) + (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\"" + closing; + } + } else if (err_loc.stack.back().type == COMMON_JSON_STACK_ELEMENT_OBJECT) { + if ((last_non_sp_char == '{' && can_parse(str + closing)) || + (last_non_sp_char == ',' && can_parse(str + "\"\": 1" + closing))) { + // Was about to create an object key+value + str += (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\": 1" + closing; + } else if (!was_maybe_number() && can_parse(str + ",\"\": 1" + closing)) { + // Was about to create an object key+value + str += (out.healing_marker.json_dump_marker = ",\"" + magic_seed) + "\": 1" + closing; + } else if (can_parse(str + "\": 1" + closing)) { + // Was inside an object key string + str += (out.healing_marker.json_dump_marker = magic_seed) + "\": 1" + closing; + } else if (str[str.length() - 1] == '\\' && can_parse(str + "\\\": 1" + closing)) { + // Was inside an object key string after an escape + str += (out.healing_marker.json_dump_marker = "\\" + magic_seed) + "\": 1" + closing; + } else { + auto last_pos = str.find_last_of(':'); + if (last_pos == std::string::npos) { + throw std::runtime_error("Cannot heal a truncated JSON object stopped in an unknown location"); + } + // fprintf(stderr, "Cutting back to last : for object key+value\n"); + str = str.substr(0, last_pos + 1) + (out.healing_marker.json_dump_marker = "\"" + magic_seed) + "\"" + closing; + } + } else { + throw std::runtime_error("Cannot heal a truncated JSON object stopped in an unknown location"); + } + // fprintf(stderr, "HEALED:\nSTRING <<<\n%s\n>>>\n\nmagic_cut: <<<\n%s\n>>>\n\n", str.c_str(), out.healing_marker.json_dump_marker.c_str()); + out.json = json::parse(str); + it = temptative_end; + return true; + } + // TODO: handle unclosed top-level primitive if the stack was empty but we got an error (e.g. "tru", "\"", etc...) + // fprintf(stderr, "Closing: TODO\n"); + return false; + } + out.json = json::parse(it, end); + it = end; + return true; +} diff --git a/common/json-partial.h b/common/json-partial.h new file mode 100644 index 0000000000000..f63356dc48f78 --- /dev/null +++ b/common/json-partial.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +// Healing marker (empty if the JSON was fully parsed / wasn't healed). +struct common_healing_marker { + // Raw marker. + std::string marker; + + // Cutting the `common_json.json.dump()` string at the (only) occurrence of this marker should yield the original partial JSON string (modulo spaces / if it had the same dump format). + std::string json_dump_marker; +}; + +// Represents a parsed JSON object, with its optional healing marker (a JSON dump fragment that can be used to find the position of healing in the JSON dump string) +struct common_json { + nlohmann::ordered_json json; + + common_healing_marker healing_marker; +}; + +// Parse the JSON string, healing (closing) any partial JSON if `healing_marker` is not empty. +// +// Healing completes partial JSON strings by adding a (possibly modified) healing marker, then whatever is needed to close the JSON. +// This allows to parse the resulting healed JSON string, yet be able to cut it again if needed at the healing marker. +// (this is used when parsing JSON outputs from the models, then crafting partial JSONs for the partial tool calls in OAI format). +// +// For instance, parsing `{` with a healing marker `foo` will produce a healed JSON `{"foo":1}`, w/ json_dump_marker = `"foo"` (which can be used to break the JSON again). +bool common_json_parse( + const std::string & input, + const std::string & healing_marker, + common_json & out); + +// Parse the JSON string (see overload above), but advancing an iterator to the end of the input when the (potentially partial) parsing succeeds. +bool common_json_parse( + std::string::const_iterator & it, + const std::string::const_iterator & end, + const std::string & healing_marker, + common_json & out); diff --git a/common/json-schema-to-grammar.cpp b/common/json-schema-to-grammar.cpp index 5b3059c2f774f..d38a74f95c213 100644 --- a/common/json-schema-to-grammar.cpp +++ b/common/json-schema-to-grammar.cpp @@ -1,8 +1,9 @@ #include "json-schema-to-grammar.h" #include "common.h" +#include + #include -#include #include #include #include diff --git a/common/json-schema-to-grammar.h b/common/json-schema-to-grammar.h index 4613f5d9f910c..362991b542682 100644 --- a/common/json-schema-to-grammar.h +++ b/common/json-schema-to-grammar.h @@ -1,9 +1,9 @@ #pragma once -#include "ggml.h" -// Change JSON_ASSERT from assert() to GGML_ASSERT: -#define JSON_ASSERT GGML_ASSERT -#include "json.hpp" +#include + +#include +#include std::string json_schema_to_grammar(const nlohmann::ordered_json & schema, bool force_gbnf = false); diff --git a/common/sampling.cpp b/common/sampling.cpp index 28705e24c0b71..9c04d35fd00a2 100644 --- a/common/sampling.cpp +++ b/common/sampling.cpp @@ -161,7 +161,7 @@ struct common_sampler * common_sampler_init(const struct llama_model * model, co GGML_ABORT("llguidance (cmake -DLLAMA_LLGUIDANCE=ON) is not enabled"); #endif // LLAMA_USE_LLGUIDANCE } else { - std::vector patterns_at_start; + std::vector trigger_patterns; std::vector patterns_anywhere; std::vector trigger_tokens; for (const auto & trigger : params.grammar_triggers) { @@ -173,10 +173,13 @@ struct common_sampler * common_sampler_init(const struct llama_model * model, co break; } case COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN: - case COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START: { - const auto & pattern = trigger.value; - (trigger.type == COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_START ? patterns_at_start : patterns_anywhere).push_back(pattern); + patterns_anywhere.push_back(trigger.value); + break; + } + case COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL: + { + trigger_patterns.push_back(trigger.value); break; } case COMMON_GRAMMAR_TRIGGER_TYPE_TOKEN: @@ -190,10 +193,6 @@ struct common_sampler * common_sampler_init(const struct llama_model * model, co } } - std::vector trigger_patterns; - if (!patterns_at_start.empty()) { - trigger_patterns.push_back("^(" + string_join(patterns_at_start, "|") + ")[\\s\\S]*"); - } if (!patterns_anywhere.empty()) { trigger_patterns.push_back("^[\\s\\S]*?(" + string_join(patterns_anywhere, "|") + ")[\\s\\S]*"); } diff --git a/convert_hf_to_gguf.py b/convert_hf_to_gguf.py index b5402cbead880..ab0f0e0ea087e 100755 --- a/convert_hf_to_gguf.py +++ b/convert_hf_to_gguf.py @@ -45,7 +45,7 @@ class SentencePieceTokenTypes(IntEnum): class ModelType(IntEnum): TEXT = 1 - VISION = 2 + MMPROJ = 2 AnyModel = TypeVar("AnyModel", bound="type[ModelBase]") @@ -54,7 +54,7 @@ class ModelType(IntEnum): class ModelBase: _model_classes: dict[ModelType, dict[str, type[ModelBase]]] = { ModelType.TEXT: {}, - ModelType.VISION: {}, + ModelType.MMPROJ: {}, } dir_model: Path @@ -88,7 +88,7 @@ def __init__(self, dir_model: Path, ftype: gguf.LlamaFileType, fname_out: Path, small_first_shard: bool = False, hparams: dict[str, Any] | None = None, remote_hf_model_id: str | None = None): if type(self) is ModelBase or \ type(self) is TextModel or \ - type(self) is VisionModel: + type(self) is MmprojModel: raise TypeError(f"{type(self).__name__!r} should not be directly instantiated") self.dir_model = dir_model @@ -308,6 +308,8 @@ def prepare_tensors(self): gguf.MODEL_TENSOR.TIME_MIX_LERP_FUSED, gguf.MODEL_TENSOR.POSNET_NORM1, gguf.MODEL_TENSOR.POSNET_NORM2, + gguf.MODEL_TENSOR.V_ENC_EMBD_POS, + gguf.MODEL_TENSOR.A_ENC_EMBD_POS, ) ) or not new_name.endswith(".weight") @@ -421,23 +423,26 @@ def load_hparams(dir_model: Path): try: # for security reason, we don't allow loading remote code by default # if a model need remote code, we will fallback to config.json - return AutoConfig.from_pretrained(dir_model, trust_remote_code=False).to_dict() + config = AutoConfig.from_pretrained(dir_model, trust_remote_code=False).to_dict() except Exception as e: logger.warning(f"Failed to load model config from {dir_model}: {e}") logger.warning("Trying to load config.json instead") with open(dir_model / "config.json", "r", encoding="utf-8") as f: config = json.load(f) - if "llm_config" in config: - # rename for InternVL - config["text_config"] = config["llm_config"] - return config + if "llm_config" in config: + # rename for InternVL + config["text_config"] = config["llm_config"] + if "thinker_config" in config: + # rename for Qwen2.5-Omni + config["text_config"] = config["thinker_config"]["text_config"] + return config @classmethod def register(cls, *names: str) -> Callable[[AnyModel], AnyModel]: assert names def func(modelcls: AnyModel) -> AnyModel: - model_type = ModelType.VISION if modelcls.model_arch == gguf.MODEL_ARCH.CLIP_VISION else ModelType.TEXT + model_type = ModelType.MMPROJ if modelcls.model_arch == gguf.MODEL_ARCH.MMPROJ else ModelType.TEXT for name in names: cls._model_classes[model_type][name] = modelcls return modelcls @@ -518,15 +523,15 @@ def set_gguf_parameters(self): self.gguf_writer.add_context_length(n_ctx) logger.info(f"gguf: context length = {n_ctx}") - if (n_embd := self.find_hparam(["hidden_size", "n_embd"], optional=True)) is not None: + if (n_embd := self.find_hparam(["hidden_size", "n_embd", "dim"], optional=True)) is not None: self.gguf_writer.add_embedding_length(n_embd) logger.info(f"gguf: embedding length = {n_embd}") - if (n_ff := self.find_hparam(["intermediate_size", "n_inner"], optional=True)) is not None: + if (n_ff := self.find_hparam(["intermediate_size", "n_inner", "hidden_dim"], optional=True)) is not None: self.gguf_writer.add_feed_forward_length(n_ff) logger.info(f"gguf: feed forward length = {n_ff}") - if (n_head := self.find_hparam(["num_attention_heads", "n_head"], optional=True)) is not None: + if (n_head := self.find_hparam(["num_attention_heads", "n_head", "n_heads"], optional=True)) is not None: self.gguf_writer.add_head_count(n_head) logger.info(f"gguf: head count = {n_head}") @@ -669,12 +674,12 @@ def get_vocab_base_pre(self, tokenizer) -> str: if chkhsh == "8aeee3860c56296a157a1fe2fad249ec40aa59b1bb5709f4ade11c4e6fe652ed": # ref: https://huggingface.co/tiiuae/falcon-7b res = "falcon" - if chkhsh == "9d032fcbd5501f4a38150912590928bfb36091efb5df11b8e2124b0390e3fb1e": - # ref: https://huggingface.co/tiiuae/Falcon3-7B-Base - res = "falcon3" if chkhsh == "0876d13b50744004aa9aeae05e7b0647eac9d801b5ba4668afc01e709c15e19f": # ref: https://huggingface.co/BAAI/bge-small-en-v1.5 res = "bert-bge" + if chkhsh == "9d032fcbd5501f4a38150912590928bfb36091efb5df11b8e2124b0390e3fb1e": + # ref: https://huggingface.co/tiiuae/Falcon3-7B-Base + res = "falcon3" if chkhsh == "8e62295832751ca1e8f92f2226f403dea30dc5165e448b5bfa05af5340c64ec7": # ref: https://huggingface.co/BAAI/bge-large-zh-v1.5 res = "bert-bge-large" @@ -726,9 +731,6 @@ def get_vocab_base_pre(self, tokenizer) -> str: if chkhsh == "7967bfa498ade6b757b064f31e964dddbb80f8f9a4d68d4ba7998fcf281c531a": # ref: https://huggingface.co/jinaai/jina-embeddings-v2-base-code res = "jina-v2-code" - if chkhsh == "b6e8e1518dc4305be2fe39c313ed643381c4da5db34a98f6a04c093f8afbe99b" or chkhsh == "81d72c7348a9f0ebe86f23298d37debe0a5e71149e29bd283904c02262b27516": - # ref: https://huggingface.co/THUDM/glm-4-9b-chat - res = "chatglm-bpe" if chkhsh == "7fc505bd3104ca1083b150b17d088b59534ede9bde81f0dd2090967d7fe52cee": # ref: https://huggingface.co/LumiOpen/Viking-7B res = "viking" @@ -759,9 +761,6 @@ def get_vocab_base_pre(self, tokenizer) -> str: if chkhsh == "60824e3c0d9401f89943cbb2fff727f0e2d4c545ba4df2d6e4f09a6db0f5b450": # ref: https://huggingface.co/facebook/chameleon-7b res = "chameleon" - if chkhsh == "1431a23e583c97432bc230bff598d103ddb5a1f89960c8f1d1051aaa944d0b35": - # ref: https://huggingface.co/sapienzanlp/Minerva-7B-base-v1.0 - res = "minerva-7b" if chkhsh == "8b5a93ed704057481f240da0be7e7dca721d7f8f4755263b6807227a2cbeae65": # ref: https://huggingface.co/sentence-transformers/stsb-roberta-base res = "roberta-bpe" @@ -792,15 +791,24 @@ def get_vocab_base_pre(self, tokenizer) -> str: if chkhsh == "d353350c764d8c3b39c763113960e4fb4919bea5fbf208a0e3b22e8469dc7406": # ref: https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct res = "llama4" - if chkhsh == "a1336059768a55c99a734006ffb02203cd450fed003e9a71886c88acf24fdbc2": - # ref: https://huggingface.co/THUDM/glm-4-9b-hf - res = "glm4" if chkhsh == "0e9433cbbb161f89e264eb32e8e64bfe69e834973ffca5d41d3948a604a3e2a3": # ref: https://huggingface.co/mistral-community/pixtral-12b res = "pixtral" if chkhsh == "d5f1dd6f980fec569fb218a81a7658ac45fc56b38c5a0adeb1c232fbe04ef5ec": # ref: https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Base res = "seed-coder" + if chkhsh == "b6e8e1518dc4305be2fe39c313ed643381c4da5db34a98f6a04c093f8afbe99b": + # ref: https://huggingface.co/THUDM/glm-4-9b-chat + res = "chatglm-bpe" + if chkhsh == "81d72c7348a9f0ebe86f23298d37debe0a5e71149e29bd283904c02262b27516": + # ref: https://huggingface.co/THUDM/glm-4-9b-chat + res = "chatglm-bpe" + if chkhsh == "a1336059768a55c99a734006ffb02203cd450fed003e9a71886c88acf24fdbc2": + # ref: https://huggingface.co/THUDM/glm-4-9b-hf + res = "glm4" + if chkhsh == "1431a23e583c97432bc230bff598d103ddb5a1f89960c8f1d1051aaa944d0b35": + # ref: https://huggingface.co/sapienzanlp/Minerva-7B-base-v1.0 + res = "minerva-7b" if res is None: logger.warning("\n") @@ -1039,6 +1047,10 @@ def _set_vocab_rwkv_world(self): special_vocab.chat_template = "rwkv-world" # hack: Add '\n\n' as the EOT token to make it chat normally special_vocab._set_special_token("eot", 261) + # hack: Override these as they have already been set (incorrectly) + special_vocab.special_token_ids["bos"] = 0 + special_vocab.special_token_ids["eos"] = 0 + special_vocab.add_to_gguf(self.gguf_writer) def _set_vocab_builtin(self, model_name: Literal["gpt-neox", "llama-spm"], vocab_size: int): @@ -1113,60 +1125,116 @@ def _try_set_pooling_type(self) -> None: self.gguf_writer.add_pooling_type(pooling_type) -class VisionModel(ModelBase): - model_type = ModelType.VISION - model_arch = gguf.MODEL_ARCH.CLIP_VISION +class MmprojModel(ModelBase): + model_type = ModelType.MMPROJ + model_arch = gguf.MODEL_ARCH.MMPROJ preprocessor_config: dict[str, Any] global_config: dict[str, Any] + n_block_keys = ["n_layers", "num_hidden_layers", "n_layer", "num_layers", "depth"] + + has_vision_encoder: bool = True # by default + has_audio_encoder: bool = False + + # for models having multiple encoders, we need to separate their hparams + hparams_vision: dict[str, Any] | None = None + hparams_audio: dict[str, Any] | None = None + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.model_arch != gguf.MODEL_ARCH.CLIP_VISION: - raise TypeError("VisionModel must be subclassed with model_arch = gguf.MODEL_ARCH.CLIP_VISION") + if self.model_arch != gguf.MODEL_ARCH.MMPROJ: + raise TypeError("MmprojModel must be subclassed with model_arch = gguf.MODEL_ARCH.MMPROJ") # get n_embd of the text model if "text_config" not in self.hparams: self.hparams["text_config"] = {} + if "audio_config" not in self.hparams: + self.hparams["audio_config"] = {} text_config = {**self.hparams, **self.hparams["text_config"]} self.n_embd_text = text_config.get("hidden_size", text_config.get("n_embd", 0)) assert self.n_embd_text > 0, "n_embd not found in hparams" - if "vision_config" not in self.hparams: - raise ValueError("vision_config not found in hparams") # move vision config to the top level, while preserving the original hparams in global_config - self.global_config = self.hparams - self.hparams = self.hparams["vision_config"] + import copy + self.global_config = copy.deepcopy(self.hparams) + self.hparams_vision = self.get_vision_config() + self.hparams_audio = self.get_audio_config() - self.block_count = self.find_hparam(["n_layers", "num_hidden_layers", "n_layer", "num_layers", "depth"]) - self.tensor_map = gguf.get_tensor_name_map(gguf.MODEL_ARCH.CLIP_VISION, self.block_count) + if self.hparams_vision is None and self.hparams_audio is None: + raise ValueError("vision_config / audio_config not found in hparams") + + # for compat with vision-only models + self.hparams = self.hparams_vision or self.hparams_audio or self.hparams + + # TODO @ngxson : this is a hack to support both vision and audio encoders + have_multiple_encoders = self.has_audio_encoder and self.has_vision_encoder + self.block_count = 128 if have_multiple_encoders else self.find_hparam(self.n_block_keys, True) + self.tensor_map = gguf.get_tensor_name_map(gguf.MODEL_ARCH.MMPROJ, self.block_count) # load preprocessor config with open(self.dir_model / "preprocessor_config.json", "r", encoding="utf-8") as f: self.preprocessor_config = json.load(f) + def get_vision_config(self) -> dict[str, Any] | None: + return self.global_config.get("vision_config") + + def get_audio_config(self) -> dict[str, Any] | None: + return self.global_config.get("audio_config") + def set_type(self): - self.gguf_writer.add_type(gguf.GGUFType.CLIP_VISION) + self.gguf_writer.add_type(gguf.GGUFType.MMPROJ) def set_gguf_parameters(self): self.gguf_writer.add_file_type(self.ftype) - self.gguf_writer.add_vision_projection_dim(self.n_embd_text) - self.gguf_writer.add_vision_has_vision_encoder(True) - # vision config - self.gguf_writer.add_vision_image_size(self.find_hparam(["image_size"])) - self.gguf_writer.add_vision_patch_size(self.find_hparam(["patch_size"])) - self.gguf_writer.add_vision_embedding_length(self.find_hparam(["hidden_size"])) - self.gguf_writer.add_vision_feed_forward_length(self.find_hparam(["intermediate_size"])) - self.gguf_writer.add_vision_block_count(self.block_count) - self.gguf_writer.add_vision_head_count(self.find_hparam(["num_attention_heads"])) + if self.has_vision_encoder: + self.gguf_writer.add_clip_has_vision_encoder(True) + self.gguf_writer.add_vision_projection_dim(self.n_embd_text) + + # vision config + self.gguf_writer.add_vision_image_size(self.find_vparam(["image_size"])) + self.gguf_writer.add_vision_patch_size(self.find_vparam(["patch_size"])) + self.gguf_writer.add_vision_embedding_length(self.find_vparam(["hidden_size"])) + self.gguf_writer.add_vision_feed_forward_length(self.find_vparam(["intermediate_size"])) + self.gguf_writer.add_vision_block_count(self.find_vparam(self.n_block_keys)) + self.gguf_writer.add_vision_head_count(self.find_vparam(["num_attention_heads"])) - # preprocessor config - self.gguf_writer.add_vision_image_mean(self.preprocessor_config["image_mean"]) - self.gguf_writer.add_vision_image_std(self.preprocessor_config["image_std"]) + # preprocessor config + self.gguf_writer.add_vision_image_mean(self.preprocessor_config["image_mean"]) + self.gguf_writer.add_vision_image_std(self.preprocessor_config["image_std"]) + + if self.has_audio_encoder: + self.gguf_writer.add_clip_has_audio_encoder(True) + self.gguf_writer.add_audio_projection_dim(self.n_embd_text) + + # audio config + self.gguf_writer.add_audio_embedding_length(self.find_aparam(["hidden_size"])) + self.gguf_writer.add_audio_feed_forward_length(self.find_aparam(["intermediate_size"])) + self.gguf_writer.add_audio_block_count(self.find_aparam(self.n_block_keys)) + self.gguf_writer.add_audio_head_count(self.find_aparam(["num_attention_heads"])) + + if not self.has_vision_encoder and not self.has_audio_encoder: + raise ValueError("MmprojModel must have either vision or audio encoder") def write_vocab(self): - raise ValueError("VisionModel does not support vocab writing") + raise ValueError("MmprojModel does not support vocab writing") + + def find_vparam(self, keys: Iterable[str], optional: bool = False) -> Any: + assert self.hparams_vision is not None + return self._find_param(self.hparams_vision, keys, optional) + + def find_aparam(self, keys: Iterable[str], optional: bool = False) -> Any: + assert self.hparams_audio is not None + return self._find_param(self.hparams_audio, keys, optional) + + def _find_param(self, obj: dict[str, Any], keys: Iterable[str], optional: bool = False) -> Any: + key = next((k for k in keys if k in obj), None) + if key is not None: + return obj[key] + if optional: + return None + raise KeyError(f"could not find any of: {keys}") @ModelBase.register("GPTNeoXForCausalLM") @@ -1780,7 +1848,8 @@ def prepare_tensors(self): "MistralForCausalLM", "MixtralForCausalLM", "VLlama3ForCausalLM", - "LlavaForConditionalGeneration") + "LlavaForConditionalGeneration", + "LlamaModel") class LlamaModel(TextModel): model_arch = gguf.MODEL_ARCH.LLAMA undo_permute = True @@ -1860,6 +1929,8 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter if is_vision_tensor: return [] # skip vision tensors + elif self.hf_arch == "LlamaModel": + name = "model." + name elif name.startswith("model.text_model"): name = name.replace("text_model.", "") # for SmolVLM elif name.startswith("language_model."): @@ -1950,7 +2021,7 @@ def prepare_tensors(self): "LlavaForConditionalGeneration", # pixtral "Mistral3ForConditionalGeneration", # mistral small 3.1 ) -class LlavaVisionModel(VisionModel): +class LlavaVisionModel(MmprojModel): img_break_tok_id = -1 def __init__(self, *args, **kwargs): @@ -1976,7 +2047,7 @@ def set_gguf_parameters(self): super().set_gguf_parameters() hparams = self.hparams if hparams["model_type"] == "pixtral": - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.PIXTRAL) + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.PIXTRAL) self.gguf_writer.add_vision_attention_layernorm_eps(hparams["layer_norm_eps"]) # hidden_act @@ -2015,7 +2086,7 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter @ModelBase.register("Idefics3ForConditionalGeneration", "SmolVLMForConditionalGeneration") -class SmolVLMModel(VisionModel): +class SmolVLMModel(MmprojModel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.hparams["model_type"] == "smolvlm_vision": @@ -2027,7 +2098,7 @@ def __init__(self, *args, **kwargs): def set_gguf_parameters(self): super().set_gguf_parameters() - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.IDEFICS3) + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.IDEFICS3) self.gguf_writer.add_vision_attention_layernorm_eps(self.hparams.get("layer_norm_eps", 1e-5)) self.gguf_writer.add_vision_projector_scale_factor(self.global_config.get("scale_factor", 2)) self.gguf_writer.add_vision_use_gelu(True) @@ -2092,6 +2163,29 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None): return super().modify_tensors(data_torch, name, bid) +@ModelBase.register("Llama4ForConditionalGeneration") +class Llama4VisionModel(MmprojModel): + def set_gguf_parameters(self): + super().set_gguf_parameters() + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.LLAMA4) + self.gguf_writer.add_vision_attention_layernorm_eps(self.hparams["norm_eps"]) + self.gguf_writer.add_vision_projector_scale_factor(int(1.0 / self.hparams["pixel_shuffle_ratio"])) + assert self.hparams["hidden_act"] == "gelu" + self.gguf_writer.add_vision_use_gelu(True) + + def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: + del bid # unused + if "multi_modal_projector" in name or "vision_model" in name: + # process vision tensors + if "positional_embedding_vlm" in name and ".weight" not in name: + name += ".weight" + if "multi_modal_projector.linear_1" in name: + # despite the name with number postfix, this is a single fully connected layer + return [(gguf.TENSOR_NAMES[gguf.MODEL_TENSOR.V_MMPROJ_FC], data_torch)] + return [(self.map_tensor_name(name), data_torch)] + return [] + + @ModelBase.register("Mistral3ForConditionalGeneration") class Mistral3Model(LlamaModel): model_arch = gguf.MODEL_ARCH.LLAMA @@ -2594,7 +2688,7 @@ def set_gguf_parameters(self): self.gguf_writer.add_file_type(self.ftype) -@ModelBase.register("Qwen2Model", "Qwen2ForCausalLM") +@ModelBase.register("Qwen2Model", "Qwen2ForCausalLM", "Qwen2AudioForConditionalGeneration") class Qwen2Model(TextModel): model_arch = gguf.MODEL_ARCH.QWEN2 @@ -2618,13 +2712,19 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter name = f"model.{name}" # map to Qwen2ForCausalLM tensors if "language_model." in name: name = name.replace("language_model.", "") # for InternVL - if name.startswith("mlp") or name.startswith("vision_model"): - # skip visual tensors + if name.startswith("mlp") or name.startswith("multi_modal_projector") \ + or name.startswith("vision_model") or name.startswith("audio_tower"): + # skip vision and audio tensors return [] yield from super().modify_tensors(data_torch, name, bid) -@ModelBase.register("Qwen2VLForConditionalGeneration", "Qwen2_5_VLForConditionalGeneration") +@ModelBase.register( + "Qwen2VLModel", + "Qwen2VLForConditionalGeneration", + "Qwen2_5_VLForConditionalGeneration", + "Qwen2_5OmniModel", +) class Qwen2VLModel(TextModel): model_arch = gguf.MODEL_ARCH.QWEN2VL @@ -2642,31 +2742,40 @@ def set_vocab(self): def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: del bid # unused - if name.startswith("visual."): - # skip visual tensors + if name.startswith("thinker."): + name = name.replace("thinker.", "") + if name.startswith("visual") or name.startswith("audio") or \ + name.startswith("talker") or name.startswith("token2wav"): + # skip multimodal tensors return [] return [(self.map_tensor_name(name), data_torch)] -@ModelBase.register("Qwen2VLForConditionalGeneration", "Qwen2_5_VLForConditionalGeneration") -class Qwen2VLVisionModel(VisionModel): +@ModelBase.register("Qwen2VLModel", "Qwen2VLForConditionalGeneration", "Qwen2_5_VLForConditionalGeneration") +class Qwen2VLVisionModel(MmprojModel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.hparams["image_size"] = self.hparams.get("image_size", 560) + assert self.hparams_vision is not None + self.hparams_vision["image_size"] = self.hparams_vision.get("image_size", 560) # rename config.json values - self.hparams["num_attention_heads"] = self.hparams.get("num_heads") - self.hparams["num_hidden_layers"] = self.hparams.get("depth") - if "embed_dim" in self.hparams: # qwen2vl - self.hparams["intermediate_size"] = self.hparams.get("hidden_size") - self.hparams["hidden_size"] = self.hparams.get("embed_dim") + self.hparams_vision["num_attention_heads"] = self.hparams_vision.get("num_heads") + self.hparams_vision["num_hidden_layers"] = self.hparams_vision.get("depth") + if "embed_dim" in self.hparams_vision: # qwen2vl + self.hparams_vision["intermediate_size"] = self.hparams_vision.get("hidden_size") + self.hparams_vision["hidden_size"] = self.hparams_vision.get("embed_dim") def set_gguf_parameters(self): super().set_gguf_parameters() - hparams = self.hparams - if self.global_config['model_type'] == 'qwen2_vl': - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.QWEN2VL) - elif self.global_config['model_type'] == 'qwen2_5_vl': - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.QWEN25VL) + assert self.hparams_vision is not None + hparams = self.hparams_vision + model_type = self.global_config['model_type'] + if model_type == 'qwen2_vl': + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.QWEN2VL) + elif model_type == 'qwen2_5_vl' or model_type == 'qwen2_5_omni': + if model_type == 'qwen2_5_omni': + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.QWEN25O) + else: + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.QWEN25VL) self.gguf_writer.add_vision_use_silu(True) # find n_wa_pattern (window attention pattern) fullatt_block_indexes = hparams.get("fullatt_block_indexes") @@ -2724,12 +2833,72 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter return [] # skip other tensors +@ModelBase.register("Qwen2_5OmniModel") +class Qwen25OmniModel(Qwen2VLVisionModel): + has_vision_encoder = True + has_audio_encoder = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + assert self.hparams_audio is not None + self.hparams_audio["hidden_size"] = self.hparams_audio["d_model"] + self.hparams_audio["intermediate_size"] = self.hparams_audio["encoder_ffn_dim"] + self.hparams_audio["num_attention_heads"] = self.hparams_audio["encoder_attention_heads"] + + def set_gguf_parameters(self): + super().set_gguf_parameters() + assert self.hparams_audio is not None + self.gguf_writer.add_audio_num_mel_bins(self.hparams_audio["num_mel_bins"]) + self.gguf_writer.add_audio_attention_layernorm_eps(self.hparams_audio.get("layer_norm_eps", 1e-5)) + + def get_vision_config(self) -> dict[str, Any] | None: + return self.global_config["thinker_config"].get("vision_config") + + def get_audio_config(self) -> dict[str, Any] | None: + return self.global_config["thinker_config"].get("audio_config") + + def generate_extra_tensors(self) -> Iterable[tuple[str, Tensor]]: + # SinusoidsPositionEmbedding + assert self.hparams_audio is not None + max_timescale = 10000 + length = 1500 + channels = self.hparams_audio["hidden_size"] + log_timescale_increment = np.log(max_timescale) / (channels // 2 - 1) + inv_timescales = torch.exp(-log_timescale_increment * torch.arange(channels // 2).float()) + scaled_time = torch.arange(length)[:, np.newaxis] * inv_timescales[np.newaxis, :] + pos_embd = torch.cat([torch.sin(scaled_time), torch.cos(scaled_time)], dim=1).to(dtype=torch.float32) + yield ("audio_tower.embed_positions.weight", pos_embd) + + def tensor_force_quant(self, name, new_name, bid, n_dims): + del bid, new_name, n_dims # unused + if ".conv" in name and ".weight" in name: + return gguf.GGMLQuantizationType.F16 + return False + + def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: + if name.startswith("thinker."): + name = name.replace("thinker.", "") + + if name.startswith("audio_tower"): + # process audio tensors + if "conv1.bias" in name or "conv2.bias" in name: + # transpose conv1 and conv2 bias + data_torch = data_torch.unsqueeze(-1) + if "audio_bos_eos_token" in name: + # this tensor is left unused in transformers code + # https://github.com/huggingface/transformers/blob/6e3063422c4b1c014aa60c32b9254fd2902f0f28/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py#L1809 + return [] + return [(self.map_tensor_name(name), data_torch)] + + return super().modify_tensors(data_torch, name, bid) + + @ModelBase.register("InternVisionModel") -class InternVisionModel(VisionModel): +class InternVisionModel(MmprojModel): def set_gguf_parameters(self): super().set_gguf_parameters() hparams = self.hparams - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.INTERNVL) + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.INTERNVL) self.gguf_writer.add_vision_attention_layernorm_eps(hparams["layer_norm_eps"]) # hidden_act if hparams["hidden_act"] == "silu": @@ -3520,7 +3689,7 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter return [(self.map_tensor_name(name), data_torch)] -@ModelBase.register("BertModel", "BertForMaskedLM", "CamembertModel") +@ModelBase.register("BertModel", "BertForMaskedLM", "CamembertModel", "BertForSequenceClassification") class BertModel(TextModel): model_arch = gguf.MODEL_ARCH.BERT @@ -3528,11 +3697,21 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.vocab_size = None + if cls_out_labels := self.hparams.get("id2label"): + if len(cls_out_labels) == 2 and cls_out_labels[0] == "LABEL_0": + # Remove dummy labels added by AutoConfig + cls_out_labels = None + self.cls_out_labels = cls_out_labels + def set_gguf_parameters(self): super().set_gguf_parameters() self.gguf_writer.add_causal_attention(False) self._try_set_pooling_type() + if self.cls_out_labels: + key_name = gguf.Keys.Classifier.OUTPUT_LABELS.format(arch = gguf.MODEL_ARCH_NAMES[self.model_arch]) + self.gguf_writer.add_array(key_name, [v for k, v in sorted(self.cls_out_labels.items())]) + def set_vocab(self): tokens, toktypes, tokpre = self.get_vocab_base() self.vocab_size = len(tokens) @@ -3583,6 +3762,14 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter if name.startswith("cls.seq_relationship"): return [] + if self.cls_out_labels: + # For BertForSequenceClassification (direct projection layer) + if name == "classifier.weight": + name = "classifier.out_proj.weight" + + if name == "classifier.bias": + name = "classifier.out_proj.bias" + return [(self.map_tensor_name(name), data_torch)] def _xlmroberta_tokenizer_init(self) -> None: @@ -3602,44 +3789,93 @@ def _xlmroberta_set_vocab(self) -> None: from sentencepiece import sentencepiece_model_pb2 as model tokenizer_path = self.dir_model / 'sentencepiece.bpe.model' + + tokenizer_json = {} + tokenizer_config_json = {} if not tokenizer_path.is_file(): - raise FileNotFoundError(f"File not found: {tokenizer_path}") + tokenizer_path = self.dir_model / 'tokenizer.json' + tokenizer_config_path = self.dir_model / 'tokenizer_config.json' - sentencepiece_model = model.ModelProto() # pyright: ignore[reportAttributeAccessIssue] - sentencepiece_model.ParseFromString(open(tokenizer_path, "rb").read()) - assert sentencepiece_model.trainer_spec.model_type == 1 # UNIGRAM + if not tokenizer_path.is_file(): + raise FileNotFoundError(f"File not found: {tokenizer_path}") - add_prefix = sentencepiece_model.normalizer_spec.add_dummy_prefix - remove_whitespaces = sentencepiece_model.normalizer_spec.remove_extra_whitespaces - precompiled_charsmap = sentencepiece_model.normalizer_spec.precompiled_charsmap + from base64 import b64decode + from transformers import AutoTokenizer + tokenizer = AutoTokenizer.from_pretrained(self.dir_model) - tokenizer = SentencePieceProcessor() - tokenizer.LoadFromFile(str(tokenizer_path)) + with open(tokenizer_path, "r", encoding="utf-8") as fp: + tokenizer_json = json.load(fp) - vocab_size = self.hparams.get('vocab_size', tokenizer.vocab_size()) + if tokenizer_config_path.is_file(): + with open(tokenizer_config_path, "r", encoding="utf-8") as fp: + tokenizer_config_json = json.load(fp) + + add_prefix = tokenizer.add_prefix_space + remove_whitespaces = tokenizer.clean_up_tokenization_spaces + precompiled_charsmap = b64decode(tokenizer_json["normalizer"]["precompiled_charsmap"]) + + vocab_size = self.hparams.get("vocab_size", tokenizer.vocab_size) + else: + sentencepiece_model = model.ModelProto() # pyright: ignore[reportAttributeAccessIssue] + sentencepiece_model.ParseFromString(open(tokenizer_path, "rb").read()) + assert sentencepiece_model.trainer_spec.model_type == 1 # UNIGRAM + + add_prefix = sentencepiece_model.normalizer_spec.add_dummy_prefix + remove_whitespaces = sentencepiece_model.normalizer_spec.remove_extra_whitespaces + precompiled_charsmap = sentencepiece_model.normalizer_spec.precompiled_charsmap + + tokenizer = SentencePieceProcessor() + tokenizer.LoadFromFile(str(tokenizer_path)) + + vocab_size = self.hparams.get('vocab_size', tokenizer.vocab_size()) tokens: list[bytes] = [f"[PAD{i}]".encode("utf-8") for i in range(vocab_size)] scores: list[float] = [-10000.0] * vocab_size toktypes: list[int] = [SentencePieceTokenTypes.UNUSED] * vocab_size - for token_id in range(tokenizer.vocab_size()): - piece = tokenizer.IdToPiece(token_id) - text = piece.encode("utf-8") - score = tokenizer.GetScore(token_id) + if isinstance(tokenizer, SentencePieceProcessor): + for token_id in range(tokenizer.vocab_size()): + piece = tokenizer.IdToPiece(token_id) + text = piece.encode("utf-8") + score = tokenizer.GetScore(token_id) - toktype = SentencePieceTokenTypes.NORMAL - if tokenizer.IsUnknown(token_id): - toktype = SentencePieceTokenTypes.UNKNOWN - elif tokenizer.IsControl(token_id): - toktype = SentencePieceTokenTypes.CONTROL - elif tokenizer.IsUnused(token_id): - toktype = SentencePieceTokenTypes.UNUSED - elif tokenizer.IsByte(token_id): - toktype = SentencePieceTokenTypes.BYTE + toktype = SentencePieceTokenTypes.NORMAL + if tokenizer.IsUnknown(token_id): + toktype = SentencePieceTokenTypes.UNKNOWN + elif tokenizer.IsControl(token_id): + toktype = SentencePieceTokenTypes.CONTROL + elif tokenizer.IsUnused(token_id): + toktype = SentencePieceTokenTypes.UNUSED + elif tokenizer.IsByte(token_id): + toktype = SentencePieceTokenTypes.BYTE - tokens[token_id] = text - scores[token_id] = score - toktypes[token_id] = toktype + tokens[token_id] = text + scores[token_id] = score + toktypes[token_id] = toktype + else: + added_vocab = tokenizer.get_added_vocab() + unk_token = tokenizer_config_json.get("unk_token") + unk_token_id = added_vocab.get(unk_token, tokenizer_json["model"].get("unk_id", 3)) + + for token_id in range(vocab_size): + piece = tokenizer._convert_id_to_token(token_id) + text = piece.encode("utf-8") + score = tokenizer_json["model"]["vocab"][token_id][1] + + toktype = SentencePieceTokenTypes.NORMAL + if token_id == unk_token_id: + toktype = SentencePieceTokenTypes.UNKNOWN + elif token_id in tokenizer.all_special_ids: + toktype = SentencePieceTokenTypes.CONTROL + elif token_id in added_vocab.values(): + toktype = SentencePieceTokenTypes.USER_DEFINED + # No reliable way to detect this, but jina doesn't have any + # elif tokenizer.IsByte(token_id): + # toktype = SentencePieceTokenTypes.BYTE + + tokens[token_id] = text + scores[token_id] = score + toktypes[token_id] = toktype if vocab_size > len(tokens): pad_count = vocab_size - len(tokens) @@ -3649,15 +3885,16 @@ def _xlmroberta_set_vocab(self) -> None: scores.append(-1000.0) toktypes.append(SentencePieceTokenTypes.UNUSED) - # realign tokens (see HF tokenizer code) - tokens = [b'', b'', b'', b''] + tokens[3:-1] - scores = [0.0, 0.0, 0.0, 0.0] + scores[3:-1] - toktypes = [ - SentencePieceTokenTypes.CONTROL, - SentencePieceTokenTypes.CONTROL, - SentencePieceTokenTypes.CONTROL, - SentencePieceTokenTypes.UNKNOWN, - ] + toktypes[3:-1] + if isinstance(tokenizer, SentencePieceProcessor): + # realign tokens (see HF tokenizer code) + tokens = [b'', b'', b'', b''] + tokens[3:-1] + scores = [0.0, 0.0, 0.0, 0.0] + scores[3:-1] + toktypes = [ + SentencePieceTokenTypes.CONTROL, + SentencePieceTokenTypes.CONTROL, + SentencePieceTokenTypes.CONTROL, + SentencePieceTokenTypes.UNKNOWN, + ] + toktypes[3:-1] self.gguf_writer.add_tokenizer_model("t5") self.gguf_writer.add_tokenizer_pre("default") @@ -3677,7 +3914,27 @@ def _xlmroberta_set_vocab(self) -> None: self.gguf_writer.add_add_eos_token(True) -@ModelBase.register("RobertaModel") +@ModelBase.register("DistilBertModel", "DistilBertForMaskedLM", "DistilBertForSequenceClassification") +class DistilBertModel(BertModel): + model_arch = gguf.MODEL_ARCH.BERT + + def set_gguf_parameters(self): + self.gguf_writer.add_layer_norm_eps(1e-12) + logger.info("gguf: layer norm epsilon = 1e-12") + super().set_gguf_parameters() + + def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: + if name.startswith("distilbert."): + name = name[11:] + + # These layers act as MLM head, so we don't need them + if name.startswith("vocab_"): + return [] + + return super().modify_tensors(data_torch, name, bid) + + +@ModelBase.register("RobertaModel", "RobertaForSequenceClassification") class RobertaModel(BertModel): model_arch = gguf.MODEL_ARCH.BERT @@ -3987,11 +4244,11 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter @ModelBase.register("Gemma3ForConditionalGeneration") -class Gemma3VisionModel(VisionModel): +class Gemma3VisionModel(MmprojModel): def set_gguf_parameters(self): super().set_gguf_parameters() hparams = self.hparams - self.gguf_writer.add_vision_projector_type(gguf.VisionProjectorType.GEMMA3) + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.GEMMA3) # default values below are taken from HF tranformers code self.gguf_writer.add_vision_attention_layernorm_eps(hparams.get("layer_norm_eps", 1e-6)) self.gguf_writer.add_vision_use_gelu(True) @@ -5938,6 +6195,65 @@ def _reverse_hf_permute(data_torch, n_heads, hidden_dim): return data_torch +@ModelBase.register("UltravoxModel") +class UltravoxModel(TextModel): + model_arch = gguf.MODEL_ARCH.LLAMA # dummy + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + raise NotImplementedError("Ultravox does not have text decoder. Instead, it uses Llama or other models for text. If you want to get the audio encoder, please use --mmproj argument") + + +@ModelBase.register("Qwen2AudioForConditionalGeneration") +class WhisperEncoderModel(MmprojModel): + has_vision_encoder = False # no vision encoder + has_audio_encoder = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.hparams["hidden_size"] = self.hparams["d_model"] + self.hparams["intermediate_size"] = self.hparams["encoder_ffn_dim"] + self.hparams["num_attention_heads"] = self.hparams["encoder_attention_heads"] + + def set_gguf_parameters(self): + super().set_gguf_parameters() + self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.QWEN2A) + self.gguf_writer.add_audio_num_mel_bins(self.hparams["num_mel_bins"]) + self.gguf_writer.add_audio_attention_layernorm_eps(self.hparams.get("layer_norm_eps", 1e-5)) + + def tensor_force_quant(self, name, new_name, bid, n_dims): + del bid, new_name, n_dims # unused + if ".conv" in name and ".weight" in name: + return gguf.GGMLQuantizationType.F16 + return False + + def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: + del bid # unused + + if name.startswith("language_model."): + # skip language model tensors + return [] + + # prevent clash naming with vision tensors + if name.startswith("multi_modal_projector"): + name = "audio." + name + + if "conv1.bias" in name or "conv2.bias" in name: + # transpose conv1 and conv2 bias + data_torch = data_torch.unsqueeze(-1) + + return [(self.map_tensor_name(name), data_torch)] + + +@ModelBase.register("UltravoxModel") +class UltravoxWhisperEncoderModel(WhisperEncoderModel): + has_vision_encoder = False # no vision encoder + has_audio_encoder = True + + def set_gguf_parameters(self): + super().set_gguf_parameters() + self.gguf_writer.add_audio_stack_factor(self.global_config["stack_factor"]) + ###### CONVERSION LOGIC ###### @@ -6113,13 +6429,15 @@ def split_str_to_n_bytes(split_str: str) -> int: def get_model_architecture(hparams: dict[str, Any], model_type: ModelType) -> str: + # TODO @ngxson : this won't work correctly if the model has both audio & vision encoders + # maybe we should fallback to text model's arch in that case, since not many models have both text_config = hparams.get("text_config", {}) vision_config = hparams.get("vision_config", {}) arch = hparams["architectures"][0] # if "architectures" is found in the sub-config, use that instead if model_type == ModelType.TEXT and text_config.get("architectures") is not None: arch = text_config["architectures"][0] - elif model_type == ModelType.VISION and vision_config.get("architectures") is not None: + elif model_type == ModelType.MMPROJ and vision_config.get("architectures") is not None: arch = vision_config["architectures"][0] return arch @@ -6182,7 +6500,7 @@ def main() -> None: with torch.inference_mode(): output_type = ftype_map[args.outtype] - model_type = ModelType.VISION if args.mmproj else ModelType.TEXT + model_type = ModelType.MMPROJ if args.mmproj else ModelType.TEXT hparams = ModelBase.load_hparams(dir_model) model_architecture = get_model_architecture(hparams, model_type) logger.info(f"Model architecture: {model_architecture}") diff --git a/convert_hf_to_gguf_update.py b/convert_hf_to_gguf_update.py index 5993a4c9836b5..2f733f0973686 100755 --- a/convert_hf_to_gguf_update.py +++ b/convert_hf_to_gguf_update.py @@ -1,28 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# This script downloads the tokenizer models of the specified models from Huggingface and -# generates the get_vocab_base_pre() function for convert_hf_to_gguf.py -# -# This is necessary in order to analyze the type of pre-tokenizer used by the model and -# provide the necessary information to llama.cpp via the GGUF header in order to implement -# the same pre-tokenizer. -# -# ref: https://github.com/ggml-org/llama.cpp/pull/6920 -# -# Instructions: -# -# - Add a new model to the "models" list -# - Run the script with your huggingface token: -# -# python3 convert_hf_to_gguf_update.py -# -# - The convert_hf_to_gguf.py script will have had its get_vocab_base_pre() function updated -# - Update llama.cpp with the new pre-tokenizer if necessary -# -# TODO: generate tokenizer tests for llama.cpp -# - import logging import os import pathlib @@ -32,6 +10,7 @@ import sys import json import shutil +import argparse from hashlib import sha256 from enum import IntEnum, auto @@ -41,6 +20,11 @@ logger = logging.getLogger("convert_hf_to_gguf_update") sess = requests.Session() +convert_py_pth = pathlib.Path("convert_hf_to_gguf.py") +convert_py = convert_py_pth.read_text(encoding="utf-8") +hf_token_pth = pathlib.Path.home() / ".cache" / "huggingface" / "token" +hf_token = hf_token_pth.read_text(encoding="utf-8").strip() if hf_token_pth.exists() else None + class TOKENIZER_TYPE(IntEnum): SPM = auto() @@ -49,20 +33,49 @@ class TOKENIZER_TYPE(IntEnum): UGM = auto() +DOC_STRING = """ +This script downloads the tokenizer models of the specified models from Huggingface and +generates the get_vocab_base_pre() function for convert_hf_to_gguf.py + +/!\\ It is intended to be used by contributors and is not meant to be run by end users + +This is necessary in order to analyze the type of pre-tokenizer used by the model and +provide the necessary information to llama.cpp via the GGUF header in order to implement +the same pre-tokenizer. + +ref: https://github.com/ggml-org/llama.cpp/pull/6920 + +Instructions: + +- Add a new model to the "models" list +- Run the script with your huggingface token + By default, token will be read from ~/.cache/huggingface/token +- The convert_hf_to_gguf.py script will have had its get_vocab_base_pre() function updated +- Update llama.cpp with the new pre-tokenizer if necessary +""" +# TODO: generate tokenizer tests for llama.cpp + +parser = argparse.ArgumentParser(description=DOC_STRING, formatter_class=argparse.RawTextHelpFormatter) +parser.add_argument( + "--full", action="store_true", + help="download full list of models - make sure you have access to all of them", +) +parser.add_argument( + "hf_token", + help="optional HF token", + nargs="?", +) +args = parser.parse_args() +hf_token = args.hf_token if args.hf_token is not None else hf_token + +if hf_token is None: + logger.error("HF token is required. Please provide it as an argument or set it in ~/.cache/huggingface/token") + sys.exit(1) + # TODO: this string has to exercise as much pre-tokenizer functionality as possible # will be updated with time - contributions welcome CHK_TXT = '\n \n\n \n\n\n \t \t\t \t\n \n \n \n \n🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български \'\'\'\'\'\'```````\"\"\"\"......!!!!!!?????? I\'ve been \'told he\'s there, \'RE you sure? \'M not sure I\'ll make it, \'D you like some tea? We\'Ve a\'lL' -if len(sys.argv) == 2: - token = sys.argv[1] - if not token.startswith("hf_"): - logger.info("Huggingface token seems invalid") - logger.info("Usage: python convert_hf_to_gguf_update.py ") - sys.exit(1) -else: - logger.info("Usage: python convert_hf_to_gguf_update.py ") - sys.exit(1) - # TODO: add models here, base models preferred models = [ {"name": "llama-spm", "tokt": TOKENIZER_TYPE.SPM, "repo": "https://huggingface.co/meta-llama/Llama-2-7b-hf", }, @@ -103,7 +116,6 @@ class TOKENIZER_TYPE(IntEnum): {"name": "exaone", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct", }, {"name": "phi-2", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/microsoft/phi-2", }, {"name": "chameleon", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/facebook/chameleon-7b", }, - {"name": "minerva-7b", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/sapienzanlp/Minerva-7B-base-v1.0", }, {"name": "roberta-bpe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/sentence-transformers/stsb-roberta-base"}, {"name": "gigachat", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/ai-sage/GigaChat-20B-A3B-instruct"}, {"name": "megrez", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/Infinigence/Megrez-3B-Instruct"}, @@ -114,11 +126,19 @@ class TOKENIZER_TYPE(IntEnum): {"name": "trillion", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/trillionlabs/Trillion-7B-preview", }, {"name": "bailingmoe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/inclusionAI/Ling-lite", }, {"name": "llama4", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct", }, - {"name": "glm4", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/THUDM/glm-4-9b-hf", }, {"name": "pixtral", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/mistral-community/pixtral-12b", }, {"name": "seed-coder", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Base", }, ] +# some models are known to be broken upstream, so we will skip them as exceptions +pre_computed_hashes = [ + # chatglm-bpe has 2 hashes, why? + {"name": "chatglm-bpe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/THUDM/glm-4-9b-chat", "chkhsh": "b6e8e1518dc4305be2fe39c313ed643381c4da5db34a98f6a04c093f8afbe99b"}, + {"name": "chatglm-bpe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/THUDM/glm-4-9b-chat", "chkhsh": "81d72c7348a9f0ebe86f23298d37debe0a5e71149e29bd283904c02262b27516"}, + {"name": "glm4", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/THUDM/glm-4-9b-hf", "chkhsh": "a1336059768a55c99a734006ffb02203cd450fed003e9a71886c88acf24fdbc2"}, + {"name": "minerva-7b", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/sapienzanlp/Minerva-7B-base-v1.0", "chkhsh": "1431a23e583c97432bc230bff598d103ddb5a1f89960c8f1d1051aaa944d0b35"}, +] + def download_file_with_auth(url, token, save_path): headers = {"Authorization": f"Bearer {token}"} @@ -169,9 +189,29 @@ def download_model(model): if os.path.isfile(save_path): logger.info(f"{name}: File {save_path} already exists - skipping") continue - download_file_with_auth(f"{repo}/resolve/main/{file}", token, save_path) + download_file_with_auth(f"{repo}/resolve/main/{file}", hf_token, save_path) + + +# get list of existing models and chkhsh from the convert_hf_to_gguf.py file +# returns mapping res --> chkhsh +def get_existing_models(convert_py): + pattern = r'if chkhsh == "([a-f0-9]{64})":\s*\n\s*.*\s*res = "([^"]+)"' + matches = re.findall(pattern, convert_py) + output = {} + for chkhsh, res in matches: + output[res] = chkhsh + return output + +existing_models = {} +all_models = models.copy() +if not args.full: + # Filter out models that already exist in convert_hf_to_gguf.py + existing_models = get_existing_models(convert_py) + all_models = models.copy() + models = [model for model in all_models if model["name"] not in existing_models] +logging.info(f"Downloading {len(models)} models...") for model in models: try: download_model(model) @@ -182,9 +222,10 @@ def download_model(model): # generate the source code for the convert_hf_to_gguf.py:get_vocab_base_pre() function: src_ifs = "" -for model in models: +for model in [*all_models, *pre_computed_hashes]: name = model["name"] tokt = model["tokt"] + chkhsh = model.get("chkhsh") if tokt == TOKENIZER_TYPE.SPM or tokt == TOKENIZER_TYPE.UGM: continue @@ -195,35 +236,44 @@ def download_model(model): continue # create the tokenizer - try: - if name == "t5": - tokenizer = AutoTokenizer.from_pretrained(f"models/tokenizers/{name}", use_fast=False) - else: - tokenizer = AutoTokenizer.from_pretrained(f"models/tokenizers/{name}") - except OSError as e: - logger.error(f"Error loading tokenizer for model {name}. The model may not exist or is not accessible with the provided token. Error: {e}") - continue # Skip to the next model if the tokenizer can't be loaded - - chktok = tokenizer.encode(CHK_TXT) - chkhsh = sha256(str(chktok).encode()).hexdigest() - - logger.info(f"model: {name}") - logger.info(f"tokt: {tokt}") - logger.info(f"repo: {model['repo']}") - logger.info(f"chktok: {chktok}") - logger.info(f"chkhsh: {chkhsh}") - - # print the "pre_tokenizer" content from the tokenizer.json - with open(f"models/tokenizers/{name}/tokenizer.json", "r", encoding="utf-8") as f: - cfg = json.load(f) - normalizer = cfg["normalizer"] - logger.info("normalizer: " + json.dumps(normalizer, indent=4)) - pre_tokenizer = cfg["pre_tokenizer"] - logger.info("pre_tokenizer: " + json.dumps(pre_tokenizer, indent=4)) - if "ignore_merges" in cfg["model"]: - logger.info("ignore_merges: " + json.dumps(cfg["model"]["ignore_merges"], indent=4)) - - logger.info("") + if chkhsh is not None: + # if the model has a pre-computed hash, use it + logger.info(f"Using pre-computed hash for model {name}: {chkhsh}") + elif name in existing_models: + # if the model already exists in convert_hf_to_gguf.py, skip compute hash + chkhsh = existing_models[name] + else: + # otherwise, compute the hash of the tokenizer + try: + logger.info(f"Loading tokenizer from {f'models/tokenizers/{name}'}...") + if name == "t5": + tokenizer = AutoTokenizer.from_pretrained(f"models/tokenizers/{name}", use_fast=False) + else: + tokenizer = AutoTokenizer.from_pretrained(f"models/tokenizers/{name}") + except OSError as e: + logger.error(f"Error loading tokenizer for model {name}. The model may not exist or is not accessible with the provided token. Error: {e}") + continue # Skip to the next model if the tokenizer can't be loaded + + chktok = tokenizer.encode(CHK_TXT) + chkhsh = sha256(str(chktok).encode()).hexdigest() + + logger.info(f"model: {name}") + logger.info(f"tokt: {tokt}") + logger.info(f"repo: {model['repo']}") + logger.info(f"chktok: {chktok}") + logger.info(f"chkhsh: {chkhsh}") + + # print the "pre_tokenizer" content from the tokenizer.json + with open(f"models/tokenizers/{name}/tokenizer.json", "r", encoding="utf-8") as f: + cfg = json.load(f) + normalizer = cfg["normalizer"] + logger.info("normalizer: " + json.dumps(normalizer, indent=4)) + pre_tokenizer = cfg["pre_tokenizer"] + logger.info("pre_tokenizer: " + json.dumps(pre_tokenizer, indent=4)) + if "ignore_merges" in cfg["model"]: + logger.info("ignore_merges: " + json.dumps(cfg["model"]["ignore_merges"], indent=4)) + + logger.info("") src_ifs += f" if chkhsh == \"{chkhsh}\":\n" src_ifs += f" # ref: {model['repo']}\n" @@ -271,8 +321,6 @@ def get_vocab_base_pre(self, tokenizer) -> str: return res """ -convert_py_pth = pathlib.Path("convert_hf_to_gguf.py") -convert_py = convert_py_pth.read_text(encoding="utf-8") convert_py = re.sub( r"(# Marker: Start get_vocab_base_pre)(.+?)( +# Marker: End get_vocab_base_pre)", lambda m: m.group(1) + src_func + m.group(3), @@ -288,7 +336,7 @@ def get_vocab_base_pre(self, tokenizer) -> str: tests = [ "ied 4 ½ months", - "Führer", + "Äpfel", "", " ", " ", @@ -367,6 +415,10 @@ def get_vocab_base_pre(self, tokenizer) -> str: logger.error(f"Failed to load tokenizer for model {name}. Error: {e}") continue # Skip this model and continue with the next one in the loop + if not os.path.exists(f"models/ggml-vocab-{name}.gguf"): + logger.info(f"Skip vocab files for model {name}, no GGUF file found") + continue + with open(f"models/ggml-vocab-{name}.gguf.inp", "w", encoding="utf-8") as f: for text in tests: f.write(f"{text}") diff --git a/docs/backend/CANN.md b/docs/backend/CANN.md old mode 100644 new mode 100755 index 23f10175a6b2d..a5ba617ca7bab --- a/docs/backend/CANN.md +++ b/docs/backend/CANN.md @@ -56,60 +56,82 @@ The llama.cpp CANN backend is designed to support Ascend NPU. It utilize the abi ## Model Supports -| Model Name | FP16 | Q8_0 | Q4_0 | +| Model Name | FP16 | Q4_0 | Q8_0 | |:----------------------------|:-----:|:----:|:----:| -| AquilaChat2-7B | √ | √ | √ | -| Baichuan-7b | √ | √ | √ | -| Baichuan2-7B-Chat | √ | √ | √ | -| bitnet_b1_58-large | √ | √ | √ | -| bloom-560m | √ | x | √ | -| bloomz-alpaca-560m | √ | x | √ | -| c4ai-command-r-35B-v01 | x | x | x | -| chatglm3-6B | x | x | x | -| chinese-alpaca-2-1.3b | √ | √ | √ | -| CodeShell-7B | √ | √ | √ | -| deepseek-ai_deepseek-coder-1.3B-base | x | x | x | -| deepseek-ai_DeepSeek-V2-Lite | x | x | x | -| deepseek-coder-6.7B-instruct | x | x | x | -| DeepSeek-V2-Lite-64x1.5B | x | x | x | -| falcon-7b-instruct | √ | √ | √ | -| flan-t5-large | √ | √ | √ | -| gemma-2-9b-it | √ | √ | √ | -| glm-4-9B | x | x | x | -| gpt2 | √ | √ | √ | -| Gpt2-163M | √ | √ | √ | -| granite-3B-code-instruct | √ | √ | √ | +| Llama-2 | √ | √ | √ | +| Llama-3 | √ | √ | √ | +| Mistral-7B | √ | √ | √ | +| Mistral MOE | √ | √ | √ | +| DBRX | - | - | - | +| Falcon | √ | √ | √ | +| Chinese LLaMA/Alpaca | √ | √ | √ | +| Vigogne(French) | √ | √ | √ | +| BERT | x | x | x | +| Koala | √ | √ | √ | +| Baichuan | √ | √ | √ | +| Aquila 1 & 2 | √ | √ | √ | +| Starcoder models | √ | √ | √ | +| Refact | √ | √ | √ | +| MPT | √ | √ | √ | +| Bloom | √ | √ | √ | +| Yi models | √ | √ | √ | +| stablelm models | √ | √ | √ | +| DeepSeek models | x | x | x | +| Qwen models | √ | √ | √ | +| PLaMo-13B | √ | √ | √ | +| Phi models | √ | √ | √ | +| PhiMoE | √ | √ | √ | +| GPT-2 | √ | √ | √ | +| Orion | √ | √ | √ | +| InternlLM2 | √ | √ | √ | +| CodeShell | √ | √ | √ | +| Gemma | √ | √ | √ | +| Mamba | √ | √ | √ | +| Xverse | √ | √ | √ | +| command-r models | √ | √ | √ | +| Grok-1 | - | - | - | +| SEA-LION | √ | √ | √ | | GritLM-7B | √ | √ | √ | -| internlm2_5-7b-chat | √ | √ | √ | -| koala-7B-HF | √ | √ | √ | -| Llama-2-7b-chat-hf | √ | √ | √ | -| Llama-3-Smaug-8B | √ | √ | √ | -| Llama2-Chinese-7b-Chat | √ | √ | √ | -| Llama3-8B | √ | √ | √ | -| Llama3-8b-chinese | √ | √ | √ | -| mamba-130m-hf | √ | √ | √ | -| Mistral-7B-Instruct-v0.2 | √ | √ | √ | -| Mixtral-8x7B-Instruct-v0.1 | x | √ | √ | -| mpt-7B | √ | √ | √ | -| OLMo-1B-hf | √ | √ | √ | -| OpenELM-3B-Instruct | √ | √ | √ | -| Orion-14b-base | √ | √ | √ | -| phi1 | x | x | x | -| phi2 | x | x | x | -| Phi-3-mini-4k-instruct | √ | √ | √ | -| plamo-13b | √ | √ | √ | -| pythia-70M | x | x | x | -| Qwen-7B | √ | √ | √ | -| Qwen2-1.5B-Instruct | √ | x | √ | -| Refact-1_6B-fim | √ | √ | √ | -| SmolLM-135M | √ | √ | √ | -| stablelm-zephyr | x | x | x | -| stablelm-2-zephyr-1_6b | x | x | x | -| starcoderbase-1b | √ | √ | √ | -| starcoder2-3b | √ | √ | √ | -| vigogne-7b-chat | √ | √ | √ | -| xverse-7b-chat | √ | √ | √ | -| Yi-6b-Chat | √ | √ | √ | +| OLMo | √ | √ | √ | +| OLMo 2 | √ | √ | √ | +| OLMoE | √ | √ | √ | +| Granite models | √ | √ | √ | +| GPT-NeoX | √ | √ | √ | +| Pythia | √ | √ | √ | +| Snowflake-Arctic MoE | - | - | - | +| Smaug | √ | √ | √ | +| Poro 34B | √ | √ | √ | +| Bitnet b1.58 models | √ | x | x | +| Flan-T5 | √ | √ | √ | +| Open Elm models | x | √ | √ | +| chatGLM3-6B + ChatGLM4-9b + GLMEdge-1.5b + GLMEdge-4b | √ | √ | √ | +| GLM-4-0414 | √ | √ | √ | +| SmolLM | √ | √ | √ | +| EXAONE-3.0-7.8B-Instruct | √ | √ | √ | +| FalconMamba Models | √ | √ | √ | +| Jais Models | - | x | x | +| Bielik-11B-v2.3 | √ | √ | √ | +| RWKV-6 | - | √ | √ | +| QRWKV-6 | √ | √ | √ | +| GigaChat-20B-A3B | x | x | x | +| Trillion-7B-preview | √ | √ | √ | +| Ling models | √ | √ | √ | + + +**Multimodal** +| Model Name | FP16 | Q4_0 | Q8_0 | +|:----------------------------|:-----:|:----:|:----:| +| LLaVA 1.5 models, LLaVA 1.6 models | x | x | x | +| BakLLaVA | √ | √ | √ | +| Obsidian | √ | - | - | +| ShareGPT4V | x | - | - | +| MobileVLM 1.7B/3B models | - | - | - | +| Yi-VL | - | - | - | +| Mini CPM | √ | √ | √ | +| Moondream | √ | √ | √ | +| Bunny | √ | - | - | +| GLM-EDGE | √ | √ | √ | +| Qwen2-VL | √ | √ | √ | @@ -258,6 +280,15 @@ cmake --build build --config release ### **GitHub contribution**: Please add the **[CANN]** prefix/tag in issues/PRs titles to help the CANN-team check/address them without delay. +## Updates +### Basic Flash Attention Support +The basic FA kernel with aclnnops has been added in aclnn_ops.cpp. +Currently, the FA only supports the cases with FP16 KV tensors and NO logit softcap. +Since the aclnn interface for flash attention cannot support the logit softcap, we will only update the quantized version in the future. + +Authors from Peking University: Bizhao Shi (bshi@pku.edu.cn), Yuxin Yang (yxyang@pku.edu.cn), Ruiyang Ma (ruiyang@stu.pku.edu.cn), and Guojie Luo (gluo@pku.edu.cn). + +We would like to thank Tuo Dai, Shanni Li, and all of the project maintainers from Huawei Technologies Co., Ltd for their help during the code development and pull request. ## TODO - Support more models and data types. diff --git a/docs/backend/SYCL.md b/docs/backend/SYCL.md index d2004dc59f2db..249e73451e66b 100644 --- a/docs/backend/SYCL.md +++ b/docs/backend/SYCL.md @@ -17,25 +17,25 @@ **SYCL** is a high-level parallel programming model designed to improve developers productivity writing code across various hardware accelerators such as CPUs, GPUs, and FPGAs. It is a single-source language designed for heterogeneous computing and based on standard C++17. -**oneAPI** is an open ecosystem and a standard-based specification, supporting multiple architectures including but not limited to intel CPUs, GPUs and FPGAs. The key components of the oneAPI ecosystem include: +**oneAPI** is an open ecosystem and a standard-based specification, supporting multiple architectures including but not limited to Intel CPUs, GPUs and FPGAs. The key components of the oneAPI ecosystem include: - **DPCPP** *(Data Parallel C++)*: The primary oneAPI SYCL implementation, which includes the icpx/icx Compilers. - **oneAPI Libraries**: A set of highly optimized libraries targeting multiple domains *(e.g. Intel oneMKL, oneMath and oneDNN)*. -- **oneAPI LevelZero**: A high performance low level interface for fine-grained control over intel iGPUs and dGPUs. +- **oneAPI LevelZero**: A high performance low level interface for fine-grained control over Intel iGPUs and dGPUs. - **Nvidia & AMD Plugins**: These are plugins extending oneAPI's DPCPP support to SYCL on Nvidia and AMD GPU targets. ### Llama.cpp + SYCL -The llama.cpp SYCL backend is designed to support **Intel GPU** firstly. Based on the cross-platform feature of SYCL, it also supports other vendor GPUs: Nvidia and AMD. +The llama.cpp SYCL backend is primarily designed for **Intel GPUs**. +SYCL cross-platform capabilities enable support for Nvidia GPUs as well, with limited support for AMD. ## Recommended Release -The SYCL backend would be broken by some PRs due to no online CI. - -The following release is verified with good quality: +The following releases are verified and recommended: |Commit ID|Tag|Release|Verified Platform| Update date| |-|-|-|-|-| +|24e86cae7219b0f3ede1d5abdf5bf3ad515cccb8|b5377 |[llama-b5377-bin-win-sycl-x64.zip](https://github.com/ggml-org/llama.cpp/releases/download/b5377/llama-b5377-bin-win-sycl-x64.zip) |ArcB580/Linux/oneAPI 2025.1
LNL Arc GPU/Windows 11/oneAPI 2025.1.1|2025-05-15| |3bcd40b3c593d14261fb2abfabad3c0fb5b9e318|b4040 |[llama-b4040-bin-win-sycl-x64.zip](https://github.com/ggml-org/llama.cpp/releases/download/b4040/llama-b4040-bin-win-sycl-x64.zip) |Arc770/Linux/oneAPI 2024.1
MTL Arc GPU/Windows 11/oneAPI 2024.1| 2024-11-19| |fb76ec31a9914b7761c1727303ab30380fd4f05c|b3038 |[llama-b3038-bin-win-sycl-x64.zip](https://github.com/ggml-org/llama.cpp/releases/download/b3038/llama-b3038-bin-win-sycl-x64.zip) |Arc770/Linux/oneAPI 2024.1
MTL Arc GPU/Windows 11/oneAPI 2024.1|| @@ -106,15 +106,14 @@ SYCL backend supports Intel GPU Family: |-------------------------------|---------|---------------------------------------| | Intel Data Center Max Series | Support | Max 1550, 1100 | | Intel Data Center Flex Series | Support | Flex 170 | -| Intel Arc Series | Support | Arc 770, 730M, Arc A750 | -| Intel built-in Arc GPU | Support | built-in Arc GPU in Meteor Lake, Arrow Lake | -| Intel iGPU | Support | iGPU in 13700k,iGPU in 13400, i5-1250P, i7-1260P, i7-1165G7 | +| Intel Arc Series | Support | Arc 770, 730M, Arc A750, B580 | +| Intel built-in Arc GPU | Support | built-in Arc GPU in Meteor Lake, Arrow Lake, Lunar Lake | +| Intel iGPU | Support | iGPU in 13700k, 13400, i5-1250P, i7-1260P, i7-1165G7 | *Notes:* - **Memory** - The device memory is a limitation when running a large model. The loaded model size, *`llm_load_tensors: buffer_size`*, is displayed in the log when running `./bin/llama-cli`. - - Please make sure the GPU shared memory from the host is large enough to account for the model's size. For e.g. the *llama-2-7b.Q4_0* requires at least 8.0GB for integrated GPU and 4.0GB for discrete GPU. - **Execution Unit (EU)** @@ -138,9 +137,11 @@ Note: AMD GPU support is highly experimental and is incompatible with F16. Additionally, it only supports GPUs with a sub_group_size (warp size) of 32. ## Docker -The docker build option is currently limited to *intel GPU* targets. + +The docker build option is currently limited to *Intel GPU* targets. ### Build image + ```sh # Using FP16 docker build -t llama-cpp-sycl --build-arg="GGML_SYCL_F16=ON" --target light -f .devops/intel.Dockerfile . @@ -148,9 +149,10 @@ docker build -t llama-cpp-sycl --build-arg="GGML_SYCL_F16=ON" --target light -f *Notes*: -To build in default FP32 *(Slower than FP16 alternative)*, you can remove the `--build-arg="GGML_SYCL_F16=ON"` argument from the previous command. +To build in default FP32 *(Slower than FP16 alternative)*, set `--build-arg="GGML_SYCL_F16=OFF"` in the previous command. You can also use the `.devops/llama-server-intel.Dockerfile`, which builds the *"server"* alternative. +Check the [documentation for Docker](../docker.md) to see the available images. ### Run container @@ -250,7 +252,7 @@ sycl-ls - **Intel GPU** -When targeting an intel GPU, the user should expect one or more level-zero devices among the available SYCL devices. Please make sure that at least one GPU is present, for instance [`level_zero:gpu`] in the sample output below: +When targeting an intel GPU, the user should expect one or more devices among the available SYCL devices. Please make sure that at least one GPU is present via `sycl-ls`, for instance `[level_zero:gpu]` in the sample output below: ``` [opencl:acc][opencl:0] Intel(R) FPGA Emulation Platform for OpenCL(TM), Intel(R) FPGA Emulation Device OpenCL 1.2 [2023.16.10.0.17_160000] @@ -282,7 +284,7 @@ For AMD GPUs we should expect at least one SYCL-HIP device [`hip:gpu`]: #### Intel GPU -``` +```sh ./examples/sycl/build.sh ``` @@ -351,7 +353,7 @@ cmake --build build --config Release -j -v #### Retrieve and prepare model -You can refer to the general [*Prepare and Quantize*](README.md#prepare-and-quantize) guide for model prepration, or simply download [llama-2-7b.Q4_0.gguf](https://huggingface.co/TheBloke/Llama-2-7B-GGUF/blob/main/llama-2-7b.Q4_0.gguf) model as example. +You can refer to the general [*Prepare and Quantize*](README.md#prepare-and-quantize) guide for model preparation, or download an already quantized model like [llama-2-7b.Q4_0.gguf](https://huggingface.co/TheBloke/Llama-2-7B-GGUF/blob/main/llama-2-7b.Q4_0.gguf) or [Meta-Llama-3-8B-Instruct-Q4_0.gguf](https://huggingface.co/aptha/Meta-Llama-3-8B-Instruct-Q4_0-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_0.gguf). ##### Check device @@ -398,11 +400,15 @@ Choose one of following methods to run. ```sh ./examples/sycl/run-llama2.sh 0 +# OR +./examples/sycl/run-llama3.sh 0 ``` - Use multiple devices: ```sh ./examples/sycl/run-llama2.sh +# OR +./examples/sycl/run-llama3.sh ``` 2. Command line @@ -425,13 +431,13 @@ Examples: - Use device 0: ```sh -ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -no-cnv -m models/llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:" -n 400 -e -ngl 33 -sm none -mg 0 +ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -no-cnv -m models/llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:" -n 400 -e -ngl 99 -sm none -mg 0 ``` - Use multiple devices: ```sh -ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -no-cnv -m models/llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:" -n 400 -e -ngl 33 -sm layer +ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -no-cnv -m models/llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:" -n 400 -e -ngl 99 -sm layer ``` *Notes:* @@ -452,7 +458,7 @@ use 1 SYCL GPUs: [0] with Max compute units:512 1. Install GPU driver -Intel GPU drivers instructions guide and download page can be found here: [Get intel GPU Drivers](https://www.intel.com/content/www/us/en/products/docs/discrete-gpus/arc/software/drivers.html). +Intel GPU drivers instructions guide and download page can be found here: [Get Intel GPU Drivers](https://www.intel.com/content/www/us/en/products/docs/discrete-gpus/arc/software/drivers.html). 2. Install Visual Studio @@ -629,7 +635,7 @@ Once it is completed, final results will be in **build/Release/bin** #### Retrieve and prepare model -You can refer to the general [*Prepare and Quantize*](README.md#prepare-and-quantize) guide for model prepration, or simply download [llama-2-7b.Q4_0.gguf](https://huggingface.co/TheBloke/Llama-2-7B-GGUF/blob/main/llama-2-7b.Q4_0.gguf) model as example. +You can refer to the general [*Prepare and Quantize*](README.md#prepare-and-quantize) guide for model preparation, or download an already quantized model like [llama-2-7b.Q4_0.gguf](https://huggingface.co/TheBloke/Llama-2-7B-GGUF/blob/main/llama-2-7b.Q4_0.gguf) or [Meta-Llama-3-8B-Instruct-Q4_0.gguf](https://huggingface.co/aptha/Meta-Llama-3-8B-Instruct-Q4_0-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_0.gguf). ##### Check device @@ -648,7 +654,7 @@ Similar to the native `sycl-ls`, available SYCL devices can be queried as follow build\bin\llama-ls-sycl-device.exe ``` -This command will only display the selected backend that is supported by SYCL. The default backend is level_zero. For example, in a system with 2 *intel GPU* it would look like the following: +This command will only display the selected backend that is supported by SYCL. The default backend is level_zero. For example, in a system with 2 *Intel GPU* it would look like the following: ``` found 2 SYCL devices: | | | |Compute |Max compute|Max work|Max sub| | @@ -658,13 +664,14 @@ found 2 SYCL devices: | 1|[level_zero:gpu:1]| Intel(R) UHD Graphics 770| 1.3| 32| 512| 32| 53651849216| ``` + #### Choose level-zero devices |Chosen Device ID|Setting| |-|-| -|0|`set ONEAPI_DEVICE_SELECTOR="level_zero:1"` or no action| +|0|Default option. You may also want to `set ONEAPI_DEVICE_SELECTOR="level_zero:0"`| |1|`set ONEAPI_DEVICE_SELECTOR="level_zero:1"`| -|0 & 1|`set ONEAPI_DEVICE_SELECTOR="level_zero:0;level_zero:1"`| +|0 & 1|`set ONEAPI_DEVICE_SELECTOR="level_zero:0;level_zero:1"` or `set ONEAPI_DEVICE_SELECTOR="level_zero:*"`| #### Execute @@ -673,7 +680,13 @@ Choose one of following methods to run. 1. Script ``` -examples\sycl\win-run-llama2.bat +examples\sycl\win-run-llama-2.bat +``` + +or + +``` +examples\sycl\win-run-llama-3.bat ``` 2. Command line @@ -697,13 +710,13 @@ Examples: - Use device 0: ``` -build\bin\llama-cli.exe -no-cnv -m models\llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:\nStep 1:" -n 400 -e -ngl 33 -s 0 -sm none -mg 0 +build\bin\llama-cli.exe -no-cnv -m models\llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:\nStep 1:" -n 400 -e -ngl 99 -sm none -mg 0 ``` - Use multiple devices: ``` -build\bin\llama-cli.exe -no-cnv -m models\llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:\nStep 1:" -n 400 -e -ngl 33 -s 0 -sm layer +build\bin\llama-cli.exe -no-cnv -m models\llama-2-7b.Q4_0.gguf -p "Building a website can be done in 10 simple steps:\nStep 1:" -n 400 -e -ngl 99 -sm layer ``` @@ -714,7 +727,9 @@ Note: ```sh detect 1 SYCL GPUs: [0] with top Max compute units:512 ``` + Or + ```sh use 1 SYCL GPUs: [0] with Max compute units:512 ``` @@ -726,15 +741,17 @@ use 1 SYCL GPUs: [0] with Max compute units:512 | Name | Value | Function | |--------------------|---------------------------------------|---------------------------------------------| -| GGML_SYCL | ON (mandatory) | Enable build with SYCL code path.
FP32 path - recommended for better perforemance than FP16 on quantized model| +| GGML_SYCL | ON (mandatory) | Enable build with SYCL code path. | | GGML_SYCL_TARGET | INTEL *(default)* \| NVIDIA \| AMD | Set the SYCL target device type. | | GGML_SYCL_DEVICE_ARCH | Optional (except for AMD) | Set the SYCL device architecture, optional except for AMD. Setting the device architecture can improve the performance. See the table [--offload-arch](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/OffloadDesign.md#--offload-arch) for a list of valid architectures. | -| GGML_SYCL_F16 | OFF *(default)* \|ON *(optional)* | Enable FP16 build with SYCL code path. | +| GGML_SYCL_F16 | OFF *(default)* \|ON *(optional)* | Enable FP16 build with SYCL code path. (1.) | | GGML_SYCL_GRAPH | ON *(default)* \|OFF *(Optional)* | Enable build with [SYCL Graph extension](https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/experimental/sycl_ext_oneapi_graph.asciidoc). | | GGML_SYCL_DNN | ON *(default)* \|OFF *(Optional)* | Enable build with oneDNN. | | CMAKE_C_COMPILER | `icx` *(Linux)*, `icx/cl` *(Windows)* | Set `icx` compiler for SYCL code path. | | CMAKE_CXX_COMPILER | `icpx` *(Linux)*, `icx` *(Windows)* | Set `icpx/icx` compiler for SYCL code path. | +1. FP16 is recommended for better prompt processing performance on quantized models. Performance is equivalent in text generation but set `GGML_SYCL_F16=OFF` if you are experiencing issues with FP16 builds. + #### Runtime | Name | Value | Function | @@ -752,7 +769,7 @@ use 1 SYCL GPUs: [0] with Max compute units:512 ## Q&A -- Error: `error while loading shared libraries: libsycl.so.7: cannot open shared object file: No such file or directory`. +- Error: `error while loading shared libraries: libsycl.so: cannot open shared object file: No such file or directory`. - Potential cause: Unavailable oneAPI installation or not set ENV variables. - Solution: Install *oneAPI base toolkit* and enable its ENV through: `source /opt/intel/oneapi/setvars.sh`. @@ -781,18 +798,18 @@ use 1 SYCL GPUs: [0] with Max compute units:512 It's same for other projects including llama.cpp SYCL backend. -- Meet issue: `Native API failed. Native API returns: -6 (PI_ERROR_OUT_OF_HOST_MEMORY) -6 (PI_ERROR_OUT_OF_HOST_MEMORY) -999 (UNKNOWN PI error)` or `failed to allocate SYCL0 buffer` +- `Native API failed. Native API returns: 39 (UR_RESULT_ERROR_OUT_OF_DEVICE_MEMORY)`, `ggml_backend_sycl_buffer_type_alloc_buffer: can't allocate 3503030272 Bytes of memory on device`, or `failed to allocate SYCL0 buffer` - Device Memory is not enough. + You are running out of Device Memory. |Reason|Solution| |-|-| - |Default Context is too big. It leads to more memory usage.|Set `-c 8192` or smaller value.| - |Model is big and require more memory than device's.|Choose smaller quantized model, like Q5 -> Q4;
Use more than one devices to load model.| + | The default context is too big. It leads to excessive memory usage.|Set `-c 8192` or a smaller value.| + | The model is too big and requires more memory than what is available.|Choose a smaller model or change to a smaller quantization, like Q5 -> Q4;
Alternatively, use more than one device to load model.| ### **GitHub contribution**: -Please add the **[SYCL]** prefix/tag in issues/PRs titles to help the SYCL-team check/address them without delay. +Please add the `SYCL :` prefix/tag in issues/PRs titles to help the SYCL contributors to check/address them without delay. ## TODO -- NA +- Review ZES_ENABLE_SYSMAN: https://github.com/intel/compute-runtime/blob/master/programmers-guide/SYSMAN.md#support-and-limitations diff --git a/docs/build.md b/docs/build.md index c9027c0b580a5..32717a793ffad 100644 --- a/docs/build.md +++ b/docs/build.md @@ -63,6 +63,7 @@ cmake --build build --config Release cmake --preset x64-windows-llvm-release cmake --build build-x64-windows-llvm-release ``` +- Curl usage is enabled by default and can be turned off with `-DLLAMA_CURL=OFF`. Otherwise you need to install development libraries for libcurl. ## BLAS Build diff --git a/docs/docker.md b/docs/docker.md index 343146dbd214f..f8f0573c17239 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -22,6 +22,9 @@ Additionally, there the following images, similar to the above: - `ghcr.io/ggml-org/llama.cpp:full-musa`: Same as `full` but compiled with MUSA support. (platforms: `linux/amd64`) - `ghcr.io/ggml-org/llama.cpp:light-musa`: Same as `light` but compiled with MUSA support. (platforms: `linux/amd64`) - `ghcr.io/ggml-org/llama.cpp:server-musa`: Same as `server` but compiled with MUSA support. (platforms: `linux/amd64`) +- `ghcr.io/ggml-org/llama.cpp:full-intel`: Same as `full` but compiled with SYCL support. (platforms: `linux/amd64`) +- `ghcr.io/ggml-org/llama.cpp:light-intel`: Same as `light` but compiled with SYCL support. (platforms: `linux/amd64`) +- `ghcr.io/ggml-org/llama.cpp:server-intel`: Same as `server` but compiled with SYCL support. (platforms: `linux/amd64`) The GPU enabled images are not currently tested by CI beyond being built. They are not built with any variation from the ones in the Dockerfiles defined in [.devops/](../.devops/) and the GitHub Action defined in [.github/workflows/docker.yml](../.github/workflows/docker.yml). If you need different settings (for example, a different CUDA, ROCm or MUSA library, you'll need to build the images locally for now). @@ -104,7 +107,7 @@ You may want to pass in some different `ARGS`, depending on the MUSA environment The defaults are: -- `MUSA_VERSION` set to `rc3.1.1` +- `MUSA_VERSION` set to `rc4.0.1` The resulting images, are essentially the same as the non-MUSA images: diff --git a/docs/function-calling.md b/docs/function-calling.md index c3873c3fa63d1..fd3db9bd16a92 100644 --- a/docs/function-calling.md +++ b/docs/function-calling.md @@ -2,7 +2,6 @@ [chat.h](../common/chat.h) (https://github.com/ggml-org/llama.cpp/pull/9639) adds support for [OpenAI-style function calling](https://platform.openai.com/docs/guides/function-calling) and is used in: - `llama-server` when started w/ `--jinja` flag -- `llama-cli` (WIP: https://github.com/ggml-org/llama.cpp/pull/11556) ## Universal support w/ Native & Generic handlers @@ -325,36 +324,65 @@ To get the official template from original HuggingFace repos, you can use [scrip > [!TIP] > If there is no official `tool_use` Jinja template, you may want to set `--chat-template chatml` to use a default that works with many models (YMMV!), or write your own (e.g. we provide a custom [llama-cpp-deepseek-r1.jinja](../models/templates/llama-cpp-deepseek-r1.jinja) for DeepSeek R1 distills) +> [!CAUTION] +> Beware of extreme KV quantizations (e.g. `-ctk q4_0`), they can substantially degrade the model's tool calling performance. + Test in CLI (or with any library / software that can use OpenAI-compatible API backends): ```bash curl http://localhost:8080/v1/chat/completions -d '{ -"model": "gpt-3.5-turbo", -"tools": [ - { - "type":"function", - "function":{ - "name":"python", - "description":"Runs code in an ipython interpreter and returns the result of the execution after 60 seconds.", - "parameters":{ - "type":"object", - "properties":{ - "code":{ - "type":"string", - "description":"The code to run in the ipython interpreter." + "model": "gpt-3.5-turbo", + "tools": [ + { + "type":"function", + "function":{ + "name":"python", + "description":"Runs code in an ipython interpreter and returns the result of the execution after 60 seconds.", + "parameters":{ + "type":"object", + "properties":{ + "code":{ + "type":"string", + "description":"The code to run in the ipython interpreter." + } + }, + "required":["code"] } - }, - "required":["code"] } - } - } -], -"messages": [ - { - "role": "user", - "content": "Print a hello world message with python." - } -] + } + ], + "messages": [ + { + "role": "user", + "content": "Print a hello world message with python." + } + ] +}' + + +curl http://localhost:8080/v1/chat/completions -d '{ + "model": "gpt-3.5-turbo", + "messages": [ + {"role": "system", "content": "You are a chatbot that uses tools/functions. Dont overthink things."}, + {"role": "user", "content": "What is the weather in Istanbul?"} + ], + "tools": [{ + "type":"function", + "function":{ + "name":"get_current_weather", + "description":"Get the current weather in a given location", + "parameters":{ + "type":"object", + "properties":{ + "location":{ + "type":"string", + "description":"The city and country/state, e.g. `San Francisco, CA`, or `Paris, France`" + } + }, + "required":["location"] + } + } + }] }' ``` diff --git a/docs/multimodal.md b/docs/multimodal.md index 80014ba1cef6d..e849c2a0b8ba1 100644 --- a/docs/multimodal.md +++ b/docs/multimodal.md @@ -4,7 +4,9 @@ llama.cpp supports multimodal input via `libmtmd`. Currently, there are 2 tools - [llama-mtmd-cli](../tools/mtmd/README.md) - [llama-server](../tools/server/README.md) via OpenAI-compatible `/chat/completions` API -To enable it, can use use one of the 2 methods below: +Currently, we support **image** and **audio** input. Audio is highly experimental and may have reduced quality. + +To enable it, you can use one of the 2 methods below: - Use `-hf` option with a supported model (see a list of pre-quantized model below) - To load a model using `-hf` while disabling multimodal, use `--no-mmproj` @@ -31,12 +33,14 @@ llama-server -hf ggml-org/gemma-3-4b-it-GGUF --no-mmproj-offload ## Pre-quantized models -These are ready-to-use models, most of them come with `Q4_K_M` quantization by default. They can be found at the Hugging Face page of the ggml-org: https://huggingface.co/ggml-org +These are ready-to-use models, most of them come with `Q4_K_M` quantization by default. They can be found at the Hugging Face page of the ggml-org: https://huggingface.co/collections/ggml-org/multimodal-ggufs-68244e01ff1f39e5bebeeedc Replaces the `(tool_name)` with the name of binary you want to use. For example, `llama-mtmd-cli` or `llama-server` NOTE: some models may require large context window, for example: `-c 8192` +**Vision models**: + ```sh # Gemma 3 (tool_name) -hf ggml-org/gemma-3-4b-it-GGUF @@ -74,4 +78,32 @@ NOTE: some models may require large context window, for example: `-c 8192` (tool_name) -hf ggml-org/InternVL3-2B-Instruct-GGUF (tool_name) -hf ggml-org/InternVL3-8B-Instruct-GGUF (tool_name) -hf ggml-org/InternVL3-14B-Instruct-GGUF + +# Llama 4 Scout +(tool_name) -hf ggml-org/Llama-4-Scout-17B-16E-Instruct-GGUF + +# Moondream2 20250414 version +(tool_name) -hf ggml-org/moondream2-20250414-GGUF + +``` + +**Audio models**: + +```sh +# Ultravox 0.5 +(tool_name) -hf ggml-org/ultravox-v0_5-llama-3_2-1b-GGUF +(tool_name) -hf ggml-org/ultravox-v0_5-llama-3_1-8b-GGUF + +# Qwen2-Audio and SeaLLM-Audio +# note: no pre-quantized GGUF this model, as they have very poor result +# ref: https://github.com/ggml-org/llama.cpp/pull/13760 +``` + +**Mixed modalities**: + +```sh +# Qwen2.5 Omni +# Capabilities: audio input, vision input +(tool_name) -hf ggml-org/Qwen2.5-Omni-3B-GGUF +(tool_name) -hf ggml-org/Qwen2.5-Omni-7B-GGUF ``` diff --git a/examples/embedding/embedding.cpp b/examples/embedding/embedding.cpp index 01ff6763fff5e..71f700877a3b9 100644 --- a/examples/embedding/embedding.cpp +++ b/examples/embedding/embedding.cpp @@ -41,8 +41,8 @@ static void batch_decode(llama_context * ctx, llama_batch & batch, float * outpu // run model LOG_INF("%s: n_tokens = %d, n_seq = %d\n", __func__, batch.n_tokens, n_seq); - if (llama_encode(ctx, batch) < 0) { - LOG_ERR("%s : failed to encode\n", __func__); + if (llama_decode(ctx, batch) < 0) { + LOG_ERR("%s : failed to process\n", __func__); } for (int i = 0; i < batch.n_tokens; i++) { diff --git a/examples/lookahead/lookahead.cpp b/examples/lookahead/lookahead.cpp index 7df20aee17046..5f8620973f40e 100644 --- a/examples/lookahead/lookahead.cpp +++ b/examples/lookahead/lookahead.cpp @@ -50,8 +50,6 @@ int main(int argc, char ** argv) { const int N = 5; // n-gram size const int G = 15; // max verification n-grams - const bool dump_kv_cache = params.dump_kv_cache; - // init llama.cpp llama_backend_init(); llama_numa_init(params.numa); @@ -152,9 +150,6 @@ int main(int argc, char ** argv) { // here we keep adding new n-grams as we go ngram_container ngrams_observed(llama_vocab_n_tokens(vocab), N, G); - // debug - struct llama_kv_cache_view kvc_view = llama_kv_cache_view_init(ctx, W + G + 1); - const auto t_dec_start = ggml_time_us(); // sample first token @@ -172,12 +167,6 @@ int main(int argc, char ** argv) { } while (true) { - // debug - if (dump_kv_cache) { - llama_kv_cache_view_update(ctx, &kvc_view); - common_kv_cache_dump_view_seqs(kvc_view, 40); - } - // build the mask from https://lmsys.org/blog/2023-11-21-lookahead-decoding/ // // Example for W = 5, N = 4, G = 2: @@ -473,8 +462,6 @@ int main(int argc, char ** argv) { common_sampler_free(smpl); - llama_kv_cache_view_free(&kvc_view); - llama_batch_free(batch); llama_backend_free(); diff --git a/examples/lookup/lookup.cpp b/examples/lookup/lookup.cpp index 4ae93b2a5ed15..2ee502939d554 100644 --- a/examples/lookup/lookup.cpp +++ b/examples/lookup/lookup.cpp @@ -24,8 +24,6 @@ int main(int argc, char ** argv){ // max. number of additional tokens to draft if match is found const int n_draft = params.speculative.n_max; - const bool dump_kv_cache = params.dump_kv_cache; - // init llama.cpp llama_backend_init(); llama_numa_init(params.numa); @@ -110,18 +108,9 @@ int main(int argc, char ** argv){ llama_batch batch_tgt = llama_batch_init(params.n_ctx, 0, 1); - // debug - struct llama_kv_cache_view kvc_view = llama_kv_cache_view_init(ctx, 1); - const auto t_dec_start = ggml_time_us(); while (true) { - // debug - if (dump_kv_cache) { - llama_kv_cache_view_update(ctx, &kvc_view); - common_kv_cache_dump_view_seqs(kvc_view, 40); - } - // print current draft sequence LOG_DBG("drafted %s\n", string_from(ctx, draft).c_str()); diff --git a/examples/parallel/README.md b/examples/parallel/README.md index ece3a66416edd..2468a30d228bb 100644 --- a/examples/parallel/README.md +++ b/examples/parallel/README.md @@ -4,7 +4,7 @@ Simplified simulation of serving incoming requests in parallel ## Example -Generate 128 client requests (`-ns 128`), simulating 8 concurrent clients (`-np 8`). The system prompt is shared (`-pps`), meaning that it is computed once at the start. The client requests consist of 10 junk questions (`-j 10`) followed by the actual question. +Generate 128 client requests (`-ns 128`), simulating 8 concurrent clients (`-np 8`). The system prompt is shared (`-pps`), meaning that it is computed once at the start. The client requests consist of up to 10 junk questions (`--junk 10`) followed by the actual question. ```bash llama-parallel -m model.gguf -np 8 -ns 128 --top-k 1 -pps --junk 10 -c 16384 diff --git a/examples/parallel/parallel.cpp b/examples/parallel/parallel.cpp index b967731a2153c..d7b269df0dea2 100644 --- a/examples/parallel/parallel.cpp +++ b/examples/parallel/parallel.cpp @@ -178,8 +178,6 @@ int main(int argc, char ** argv) { // insert new requests as soon as the previous one is done const bool cont_batching = params.cont_batching; - const bool dump_kv_cache = params.dump_kv_cache; - // is the system prompt shared in the cache const bool is_sp_shared = params.is_pp_shared; @@ -241,8 +239,6 @@ int main(int argc, char ** argv) { int32_t n_total_gen = 0; int32_t n_cache_miss = 0; - struct llama_kv_cache_view kvc_view = llama_kv_cache_view_init(ctx, n_clients); - const auto t_main_start = ggml_time_us(); LOG_INF("%s: Simulating parallel requests from clients:\n", __func__); @@ -272,11 +268,6 @@ int main(int argc, char ** argv) { LOG_INF("Processing requests ...\n\n"); while (true) { - if (dump_kv_cache) { - llama_kv_cache_view_update(ctx, &kvc_view); - common_kv_cache_dump_view_seqs(kvc_view, 40); - } - common_batch_clear(batch); // decode any currently ongoing sequences @@ -324,7 +315,10 @@ int main(int argc, char ** argv) { } else { client.prompt += k_system; } - for (int i = 0; i < n_junk; ++i) { + + const int n_junk_cur = rand() % n_junk; + + for (int i = 0; i < n_junk_cur; ++i) { const int r = rand() % k_questions.size(); client.prompt += "User:\n" + k_questions[r] + "\nAssistant:\n " + k_answers[r] + "\n"; } @@ -349,7 +343,7 @@ int main(int argc, char ** argv) { client.n_decoded = 0; client.i_batch = batch.n_tokens - 1; - LOG_INF("\033[31mClient %3d, seq %4d, started decoding ...\033[0m\n", client.id, client.seq_id); + LOG_INF("\033[31mClient %3d, seq %4d, junk = %4d, started decoding ...\033[0m\n", client.id, client.seq_id, n_junk_cur); g_seq_id += 1; @@ -368,7 +362,9 @@ int main(int argc, char ** argv) { // process in chunks of params.n_batch int32_t n_batch = params.n_batch; - for (int32_t i = 0; i < (int32_t) batch.n_tokens; i += n_batch) { + int32_t i_next = 0; + + for (int32_t i = 0; i < batch.n_tokens; i = i_next) { // experiment: process in powers of 2 //if (i + n_batch > (int32_t) batch.n_tokens && n_batch > 32) { // n_batch /= 2; @@ -376,7 +372,7 @@ int main(int argc, char ** argv) { // continue; //} - const int32_t n_tokens = std::min(n_batch, (int32_t) (batch.n_tokens - i)); + const int32_t n_tokens = std::min(n_batch, batch.n_tokens - i); llama_batch batch_view = { n_tokens, @@ -396,19 +392,24 @@ int main(int argc, char ** argv) { return 1; } - LOG_ERR("%s : failed to decode the batch, retrying with n_batch = %d\n", __func__, n_batch / 2); + LOG_WRN("%s : failed to decode the batch, retrying with n_batch = %d\n", __func__, n_batch / 2); n_cache_miss += 1; // retry with half the batch size to try to find a free slot in the KV cache n_batch /= 2; - i -= n_batch; continue; } LOG_DBG("%s : decoded batch of %d tokens\n", __func__, n_tokens); + // move the head of the batch forward with the number of tokens we just processed + i_next = i + n_tokens; + + // on successful decode, restore the original batch size + n_batch = params.n_batch; + for (auto & client : clients) { if (client.i_batch < (int) i || client.i_batch >= (int) (i + n_tokens)) { continue; diff --git a/examples/passkey/passkey.cpp b/examples/passkey/passkey.cpp index 347ea4a698f2e..5ac881b45e268 100644 --- a/examples/passkey/passkey.cpp +++ b/examples/passkey/passkey.cpp @@ -133,9 +133,8 @@ int main(int argc, char ** argv) { const int ib = i/n_batch - 1; const int bd = n_batch_grp*(n_grp - 1); - llama_kv_self_seq_add (ctx, 0, n_past - n_batch, n_past, ib*bd); - llama_kv_self_seq_div (ctx, 0, n_past - n_batch + ib*bd, n_past + ib*bd, n_grp); - llama_kv_self_update (ctx); + llama_kv_self_seq_add(ctx, 0, n_past - n_batch, n_past, ib*bd); + llama_kv_self_seq_div(ctx, 0, n_past - n_batch + ib*bd, n_past + ib*bd, n_grp); n_past = llama_kv_self_seq_pos_max(ctx, 0) + 1; } @@ -169,8 +168,6 @@ int main(int argc, char ** argv) { llama_kv_self_seq_rm (ctx, 0, n_keep , n_keep + n_discard); llama_kv_self_seq_add(ctx, 0, n_keep + n_discard, n_ctx, -n_discard); - //llama_kv_self_defrag (ctx); - llama_kv_self_update (ctx); n_past = llama_kv_self_seq_pos_max(ctx, 0) + 1; @@ -200,8 +197,6 @@ int main(int argc, char ** argv) { llama_kv_self_seq_rm (ctx, 0, n_keep , n_keep + n_discard); llama_kv_self_seq_add(ctx, 0, n_keep + n_discard, n_ctx, -n_discard); - //llama_kv_self_defrag (ctx); - llama_kv_self_update (ctx); n_past = llama_kv_self_seq_pos_max(ctx, 0) + 1; } diff --git a/examples/retrieval/retrieval.cpp b/examples/retrieval/retrieval.cpp index 0efe20d4b3f5d..754da1411bcc1 100644 --- a/examples/retrieval/retrieval.cpp +++ b/examples/retrieval/retrieval.cpp @@ -81,14 +81,14 @@ static void batch_add_seq(llama_batch & batch, const std::vector & toke } } -static void batch_decode(llama_context * ctx, llama_batch & batch, float * output, int n_seq, int n_embd) { +static void batch_process(llama_context * ctx, llama_batch & batch, float * output, int n_seq, int n_embd) { // clear previous kv_cache values (irrelevant for embeddings) llama_kv_self_clear(ctx); // run model LOG_INF("%s: n_tokens = %d, n_seq = %d\n", __func__, batch.n_tokens, n_seq); if (llama_decode(ctx, batch) < 0) { - LOG_ERR("%s : failed to decode\n", __func__); + LOG_ERR("%s : failed to process\n", __func__); } for (int i = 0; i < batch.n_tokens; i++) { @@ -233,7 +233,7 @@ int main(int argc, char ** argv) { // encode if at capacity if (batch.n_tokens + n_toks > n_batch) { float * out = emb + p * n_embd; - batch_decode(ctx, batch, out, s, n_embd); + batch_process(ctx, batch, out, s, n_embd); common_batch_clear(batch); p += s; s = 0; @@ -246,7 +246,7 @@ int main(int argc, char ** argv) { // final batch float * out = emb + p * n_embd; - batch_decode(ctx, batch, out, s, n_embd); + batch_process(ctx, batch, out, s, n_embd); // save embeddings to chunks for (int i = 0; i < n_chunks; i++) { @@ -267,7 +267,7 @@ int main(int argc, char ** argv) { batch_add_seq(query_batch, query_tokens, 0); std::vector query_emb(n_embd, 0); - batch_decode(ctx, query_batch, query_emb.data(), 1, n_embd); + batch_process(ctx, query_batch, query_emb.data(), 1, n_embd); common_batch_clear(query_batch); diff --git a/examples/simple-chat/simple-chat.cpp b/examples/simple-chat/simple-chat.cpp index 84f4159737260..6608d4bea05c8 100644 --- a/examples/simple-chat/simple-chat.cpp +++ b/examples/simple-chat/simple-chat.cpp @@ -98,7 +98,7 @@ int main(int argc, char ** argv) { auto generate = [&](const std::string & prompt) { std::string response; - const bool is_first = llama_kv_self_used_cells(ctx) == 0; + const bool is_first = llama_kv_self_seq_pos_max(ctx, 0) == 0; // tokenize the prompt const int n_prompt_tokens = -llama_tokenize(vocab, prompt.c_str(), prompt.size(), NULL, 0, is_first, true); @@ -113,7 +113,7 @@ int main(int argc, char ** argv) { while (true) { // check if we have enough space in the context to evaluate this batch int n_ctx = llama_n_ctx(ctx); - int n_ctx_used = llama_kv_self_used_cells(ctx); + int n_ctx_used = llama_kv_self_seq_pos_max(ctx, 0); if (n_ctx_used + batch.n_tokens > n_ctx) { printf("\033[0m\n"); fprintf(stderr, "context size exceeded\n"); diff --git a/examples/simple/simple.cpp b/examples/simple/simple.cpp index 10e79a0a69eeb..633b87e58406e 100644 --- a/examples/simple/simple.cpp +++ b/examples/simple/simple.cpp @@ -84,13 +84,13 @@ int main(int argc, char ** argv) { model_params.n_gpu_layers = ngl; llama_model * model = llama_model_load_from_file(model_path.c_str(), model_params); - const llama_vocab * vocab = llama_model_get_vocab(model); if (model == NULL) { fprintf(stderr , "%s: error: unable to load model\n" , __func__); return 1; } + const llama_vocab * vocab = llama_model_get_vocab(model); // tokenize the prompt // find the number of tokens in the prompt diff --git a/examples/sycl/run-llama2.sh b/examples/sycl/run-llama2.sh index 8ce71e37000a1..40ce8f5b2b7b5 100755 --- a/examples/sycl/run-llama2.sh +++ b/examples/sycl/run-llama2.sh @@ -12,16 +12,16 @@ source /opt/intel/oneapi/setvars.sh INPUT_PROMPT="Building a website can be done in 10 simple steps:\nStep 1:" MODEL_FILE=models/llama-2-7b.Q4_0.gguf -NGL=33 -CONEXT=4096 +NGL=99 +CONTEXT=4096 if [ $# -gt 0 ]; then GGML_SYCL_DEVICE=$1 echo "use $GGML_SYCL_DEVICE as main GPU" #use signle GPU only - ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -s 0 -c ${CONEXT} -mg $GGML_SYCL_DEVICE -sm none + ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -s 0 -c ${CONTEXT} -mg $GGML_SYCL_DEVICE -sm none else #use multiple GPUs with same max compute units - ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -s 0 -c ${CONEXT} + ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -s 0 -c ${CONTEXT} fi diff --git a/examples/sycl/run-llama3.sh b/examples/sycl/run-llama3.sh new file mode 100755 index 0000000000000..933d1b98bc075 --- /dev/null +++ b/examples/sycl/run-llama3.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# MIT license +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: MIT + +# If you want more control, DPC++ Allows selecting a specific device through the +# following environment variable +#export ONEAPI_DEVICE_SELECTOR="level_zero:0" +source /opt/intel/oneapi/setvars.sh + +#export GGML_SYCL_DEBUG=1 + +#ZES_ENABLE_SYSMAN=1, Support to get free memory of GPU by sycl::aspect::ext_intel_free_memory. Recommended to use when --split-mode = layer. + +INPUT_PROMPT="Building a website can be done in 10 simple steps:\nStep 1:" +MODEL_FILE=models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf +NGL=99 # Layers offloaded to the GPU. If the device runs out of memory, reduce this value according to the model you are using. +CONTEXT=4096 + +if [ $# -gt 0 ]; then + GGML_SYCL_DEVICE=$1 + echo "Using $GGML_SYCL_DEVICE as the main GPU" + ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -c ${CONTEXT} -mg $GGML_SYCL_DEVICE -sm none +else + #use multiple GPUs with same max compute units + ZES_ENABLE_SYSMAN=1 ./build/bin/llama-cli -m ${MODEL_FILE} -p "${INPUT_PROMPT}" -n 400 -e -ngl ${NGL} -c ${CONTEXT} +fi diff --git a/examples/sycl/win-run-llama2.bat b/examples/sycl/win-run-llama2.bat index c2918d6dcead6..d7564f4161ca2 100644 --- a/examples/sycl/win-run-llama2.bat +++ b/examples/sycl/win-run-llama2.bat @@ -6,4 +6,4 @@ set INPUT2="Building a website can be done in 10 simple steps:\nStep 1:" @call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 --force -.\build\bin\llama-cli.exe -m models\llama-2-7b.Q4_0.gguf -p %INPUT2% -n 400 -e -ngl 33 -s 0 +.\build\bin\llama-cli.exe -m models\llama-2-7b.Q4_0.gguf -p %INPUT2% -n 400 -e -ngl 99 -s 0 diff --git a/examples/sycl/win-run-llama3.bat b/examples/sycl/win-run-llama3.bat new file mode 100644 index 0000000000000..4b61aebee5588 --- /dev/null +++ b/examples/sycl/win-run-llama3.bat @@ -0,0 +1,9 @@ +:: MIT license +:: Copyright (C) 2024 Intel Corporation +:: SPDX-License-Identifier: MIT + +set INPUT2="Building a website can be done in 10 simple steps:\nStep 1:" +@call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 --force + + +.\build\bin\llama-cli.exe -m models\Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -p %INPUT2% -n 400 -e -ngl 99 diff --git a/examples/training/README.md b/examples/training/README.md index ecdf398f81e14..df425279266e4 100644 --- a/examples/training/README.md +++ b/examples/training/README.md @@ -10,8 +10,8 @@ Proof of concept: ``` sh export model_name=llama_3.2-1b && export quantization=f32 -./build/bin/finetune --file wikitext-2-raw/wiki.test.raw -ngl 999 --model models/${model_name}-${quantization}.gguf -c 512 -b 512 -ub 512 -./build/bin/perplexity --file wikitext-2-raw/wiki.test.raw -ngl 999 --model finetuned-model.gguf +./build/bin/llama-finetune --file wikitext-2-raw/wiki.test.raw -ngl 999 --model models/${model_name}-${quantization}.gguf -c 512 -b 512 -ub 512 +./build/bin/llama-perplexity --file wikitext-2-raw/wiki.test.raw -ngl 999 --model finetuned-model.gguf ``` The perplexity value of the finetuned model should be lower after training on the test set for 2 epochs. diff --git a/ggml/CMakeLists.txt b/ggml/CMakeLists.txt index 4746d5cb76c08..5ddb3f7c8d243 100644 --- a/ggml/CMakeLists.txt +++ b/ggml/CMakeLists.txt @@ -129,6 +129,7 @@ option(GGML_LASX "ggml: enable lasx" ON) option(GGML_LSX "ggml: enable lsx" ON) option(GGML_RVV "ggml: enable rvv" ON) option(GGML_RV_ZFH "ggml: enable riscv zfh" OFF) +option(GGML_XTHEADVECTOR "ggml: enable xtheadvector" OFF) option(GGML_VXE "ggml: enable vxe" ON) option(GGML_CPU_ALL_VARIANTS "ggml: build all variants of the CPU backend (requires GGML_BACKEND_DL)" OFF) @@ -176,7 +177,6 @@ option(GGML_VULKAN_CHECK_RESULTS "ggml: run Vulkan op checks" option(GGML_VULKAN_DEBUG "ggml: enable Vulkan debug output" OFF) option(GGML_VULKAN_MEMORY_DEBUG "ggml: enable Vulkan memory debug output" OFF) option(GGML_VULKAN_SHADER_DEBUG_INFO "ggml: enable Vulkan shader debug info" OFF) -option(GGML_VULKAN_PERF "ggml: enable Vulkan perf output" OFF) option(GGML_VULKAN_VALIDATE "ggml: enable Vulkan validation" OFF) option(GGML_VULKAN_RUN_TESTS "ggml: run Vulkan tests" OFF) option(GGML_KOMPUTE "ggml: use Kompute" OFF) @@ -205,6 +205,7 @@ option(GGML_OPENCL_EMBED_KERNELS "ggml: embed kernels" option(GGML_OPENCL_USE_ADRENO_KERNELS "ggml: use optimized kernels for Adreno" ON) set (GGML_OPENCL_TARGET_VERSION "300" CACHE STRING "gmml: OpenCL API version to target") +option(GGML_HEXAGON "ggml: use HEXAGON" OFF) # toolchain for vulkan-shaders-gen set (GGML_VULKAN_SHADERS_GEN_TOOLCHAIN "" CACHE FILEPATH "ggml: toolchain file for vulkan-shaders-gen") @@ -270,6 +271,7 @@ set(GGML_PUBLIC_HEADERS include/ggml-rpc.h include/ggml-sycl.h include/ggml-vulkan.h + include/ggml-hexagon.h include/gguf.h) set_target_properties(ggml PROPERTIES PUBLIC_HEADER "${GGML_PUBLIC_HEADERS}") diff --git a/ggml/cmake/common.cmake b/ggml/cmake/common.cmake index 1976d0ae9b1e8..bb1ec9b37a7f0 100644 --- a/ggml/cmake/common.cmake +++ b/ggml/cmake/common.cmake @@ -24,3 +24,28 @@ function(ggml_get_flags CCID CCVER) set(GF_C_FLAGS ${C_FLAGS} PARENT_SCOPE) set(GF_CXX_FLAGS ${CXX_FLAGS} PARENT_SCOPE) endfunction() + +function(ggml_get_system_arch) + if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64" OR + CMAKE_GENERATOR_PLATFORM_LWR STREQUAL "arm64" OR + (NOT CMAKE_OSX_ARCHITECTURES AND NOT CMAKE_GENERATOR_PLATFORM_LWR AND + CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm.*|ARM64)$")) + set(GGML_SYSTEM_ARCH "ARM" PARENT_SCOPE) + elseif (CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64" OR + CMAKE_GENERATOR_PLATFORM_LWR MATCHES "^(x86_64|i686|amd64|x64|win32)$" OR + (NOT CMAKE_OSX_ARCHITECTURES AND NOT CMAKE_GENERATOR_PLATFORM_LWR AND + CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|i686|AMD64|amd64)$")) + set(GGML_SYSTEM_ARCH "x86" PARENT_SCOPE) + elseif ("${CMAKE_SYSTEM_PROCESSOR} " STREQUAL "ppc64le " OR + "${CMAKE_SYSTEM_PROCESSOR} " STREQUAL "powerpc ") + set(GGML_SYSTEM_ARCH "PowerPC" PARENT_SCOPE) + elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64") + set(GGML_SYSTEM_ARCH "loongarch64" PARENT_SCOPE) + elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") + set(GGML_SYSTEM_ARCH "riscv64" PARENT_SCOPE) + elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "s390x") + set(GGML_SYSTEM_ARCH "s390x" PARENT_SCOPE) + else() + set(GGML_SYSTEM_ARCH "UNKNOWN" PARENT_SCOPE) + endif() +endfunction() diff --git a/ggml/include/ggml-hexagon.h b/ggml/include/ggml-hexagon.h new file mode 100644 index 0000000000000..0d41a955f6715 --- /dev/null +++ b/ggml/include/ggml-hexagon.h @@ -0,0 +1,36 @@ + /* + * Copyright (c) 2024-2025 The ggml authors + */ +#pragma once + +#include "ggml.h" +#include "ggml-backend.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GGML_HEXAGON_MAX_DEVICES 4 +#define GGML_HEXAGON_BACKEND_NAME "hexagon" + +enum HEXAGONBackend { + HEXAGON_BACKEND_QNNCPU = 0, + HEXAGON_BACKEND_QNNGPU = 1, + HEXAGON_BACKEND_QNNNPU = 2, + HEXAGON_BACKEND_CDSP = 3, + HEXAGON_BACKEND_GGML = 4, //"fake" HEXAGON backend for compare performance between HEXAGON backend and ggml backend +}; + +GGML_BACKEND_API ggml_backend_t ggml_backend_hexagon_init(size_t dev_num, const char * qnn_lib_path); + +GGML_BACKEND_API bool ggml_backend_is_hexagon(ggml_backend_t backend); + +GGML_BACKEND_API int ggml_backend_hexagon_get_device_count(void); + +GGML_BACKEND_API ggml_backend_reg_t ggml_backend_hexagon_reg(void); + +const char * ggml_backend_hexagon_get_devname(size_t dev_num); + +#ifdef __cplusplus +} +#endif diff --git a/ggml/include/ggml-opt.h b/ggml/include/ggml-opt.h index da0c24b46fed9..74ec080a055ea 100644 --- a/ggml/include/ggml-opt.h +++ b/ggml/include/ggml-opt.h @@ -128,6 +128,8 @@ extern "C" { // set gradients to zero, initilize loss, and optionally reset the optimizer GGML_API void ggml_opt_reset(ggml_opt_context_t opt_ctx, bool optimizer); + GGML_API bool ggml_opt_static_graphs(ggml_opt_context_t opt_ctx); // whether the graphs are allocated_statically + // get underlying tensors that store data // if not using static graphs these pointers become invalid with the next call to ggml_opt_alloc GGML_API struct ggml_tensor * ggml_opt_inputs( ggml_opt_context_t opt_ctx); // forward graph input tensor diff --git a/ggml/include/ggml.h b/ggml/include/ggml.h index e91dedf14a1cb..2226aadcff893 100644 --- a/ggml/include/ggml.h +++ b/ggml/include/ggml.h @@ -536,6 +536,7 @@ extern "C" { GGML_UNARY_OP_HARDSWISH, GGML_UNARY_OP_HARDSIGMOID, GGML_UNARY_OP_EXP, + GGML_UNARY_OP_GELU_ERF, GGML_UNARY_OP_COUNT, }; @@ -934,6 +935,15 @@ extern "C" { struct ggml_tensor * a, struct ggml_tensor * b); + // repeat a to the specified shape + GGML_API struct ggml_tensor * ggml_repeat_4d( + struct ggml_context * ctx, + struct ggml_tensor * a, + int64_t ne0, + int64_t ne1, + int64_t ne2, + int64_t ne3); + // sums repetitions in a into shape of b GGML_API struct ggml_tensor * ggml_repeat_back( struct ggml_context * ctx, @@ -1024,6 +1034,16 @@ extern "C" { struct ggml_context * ctx, struct ggml_tensor * a); + // GELU using erf (error function) when possible + // some backends may fallback to approximation based on Abramowitz and Stegun formula + GGML_API struct ggml_tensor * ggml_gelu_erf( + struct ggml_context * ctx, + struct ggml_tensor * a); + + GGML_API struct ggml_tensor * ggml_gelu_erf_inplace( + struct ggml_context * ctx, + struct ggml_tensor * a); + GGML_API struct ggml_tensor * ggml_gelu_quick( struct ggml_context * ctx, struct ggml_tensor * a); @@ -2161,6 +2181,7 @@ extern "C" { // scheduling priorities enum ggml_sched_priority { + GGML_SCHED_PRIO_LOW = -1, GGML_SCHED_PRIO_NORMAL, GGML_SCHED_PRIO_MEDIUM, GGML_SCHED_PRIO_HIGH, diff --git a/ggml/src/CMakeLists.txt b/ggml/src/CMakeLists.txt index ddea5ad3891e5..e47169f230785 100644 --- a/ggml/src/CMakeLists.txt +++ b/ggml/src/CMakeLists.txt @@ -109,6 +109,8 @@ if (MSVC) else () set(CMAKE_GENERATOR_PLATFORM_LWR "") endif () +ggml_get_system_arch() +message(STATUS "GGML_SYSTEM_ARCH: ${GGML_SYSTEM_ARCH}") if (NOT MSVC) if (GGML_STATIC) @@ -287,16 +289,20 @@ if (GGML_CPU_ALL_VARIANTS) if (NOT GGML_BACKEND_DL) message(FATAL_ERROR "GGML_CPU_ALL_VARIANTS requires GGML_BACKEND_DL") endif() - ggml_add_cpu_backend_variant(x64) - ggml_add_cpu_backend_variant(sse42 SSE42) - ggml_add_cpu_backend_variant(sandybridge SSE42 AVX) - ggml_add_cpu_backend_variant(haswell SSE42 AVX F16C AVX2 BMI2 FMA) - ggml_add_cpu_backend_variant(skylakex SSE42 AVX F16C AVX2 BMI2 FMA AVX512) - ggml_add_cpu_backend_variant(icelake SSE42 AVX F16C AVX2 BMI2 FMA AVX512 AVX512_VBMI AVX512_VNNI) - ggml_add_cpu_backend_variant(alderlake SSE42 AVX F16C AVX2 BMI2 FMA AVX_VNNI) - if (NOT MSVC) - # MSVC doesn't support AMX - ggml_add_cpu_backend_variant(sapphirerapids SSE42 AVX F16C AVX2 BMI2 FMA AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16 AMX_TILE AMX_INT8) + if (GGML_SYSTEM_ARCH STREQUAL "x86") + ggml_add_cpu_backend_variant(x64) + ggml_add_cpu_backend_variant(sse42 SSE42) + ggml_add_cpu_backend_variant(sandybridge SSE42 AVX) + ggml_add_cpu_backend_variant(haswell SSE42 AVX F16C AVX2 BMI2 FMA) + ggml_add_cpu_backend_variant(skylakex SSE42 AVX F16C AVX2 BMI2 FMA AVX512) + ggml_add_cpu_backend_variant(icelake SSE42 AVX F16C AVX2 BMI2 FMA AVX512 AVX512_VBMI AVX512_VNNI) + ggml_add_cpu_backend_variant(alderlake SSE42 AVX F16C AVX2 BMI2 FMA AVX_VNNI) + if (NOT MSVC) + # MSVC doesn't support AMX + ggml_add_cpu_backend_variant(sapphirerapids SSE42 AVX F16C AVX2 BMI2 FMA AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16 AMX_TILE AMX_INT8) + endif() + else() + message(FATAL_ERROR "GGML_CPU_ALL_VARIANTS not yet supported on ${GGML_SYSTEM_ARCH}") endif() elseif (GGML_CPU) ggml_add_cpu_backend_variant_impl("") @@ -313,6 +319,7 @@ ggml_add_backend(RPC) ggml_add_backend(SYCL) ggml_add_backend(Vulkan) ggml_add_backend(OpenCL) +ggml_add_backend(HEXAGON) foreach (target ggml-base ggml) target_include_directories(${target} PUBLIC $ $) diff --git a/ggml/src/ggml-backend-reg.cpp b/ggml/src/ggml-backend-reg.cpp index 405d8e31514b5..e2e334c1de002 100644 --- a/ggml/src/ggml-backend-reg.cpp +++ b/ggml/src/ggml-backend-reg.cpp @@ -65,6 +65,10 @@ #include "ggml-kompute.h" #endif +#ifdef GGML_USE_HEXAGON +#include "ggml-hexagon.h" +#endif + // disable C++17 deprecation warning for std::codecvt_utf8 #if defined(__clang__) # pragma clang diagnostic push @@ -187,6 +191,9 @@ struct ggml_backend_registry { #ifdef GGML_USE_KOMPUTE register_backend(ggml_backend_kompute_reg()); #endif +#ifdef GGML_USE_HEXAGON + register_backend(ggml_backend_hexagon_reg()); +#endif #ifdef GGML_USE_CPU register_backend(ggml_backend_cpu_reg()); #endif @@ -577,6 +584,7 @@ void ggml_backend_load_all_from_path(const char * dir_path) { ggml_backend_load_best("vulkan", silent, dir_path); ggml_backend_load_best("opencl", silent, dir_path); ggml_backend_load_best("musa", silent, dir_path); + ggml_backend_load_best("hexagon", silent, dir_path); ggml_backend_load_best("cpu", silent, dir_path); // check the environment variable GGML_BACKEND_PATH to load an out-of-tree backend const char * backend_path = std::getenv("GGML_BACKEND_PATH"); diff --git a/ggml/src/ggml-backend.cpp b/ggml/src/ggml-backend.cpp index b30b4cb386f9f..b1050ad59c26a 100644 --- a/ggml/src/ggml-backend.cpp +++ b/ggml/src/ggml-backend.cpp @@ -1340,7 +1340,10 @@ static bool ggml_backend_sched_alloc_splits(ggml_backend_sched_t sched) { // allocate graph if (backend_ids_changed || !ggml_gallocr_alloc_graph(sched->galloc, &sched->graph)) { // the re-allocation may cause the split inputs to be moved to a different address - ggml_backend_sched_synchronize(sched); + // synchronize without ggml_backend_sched_synchronize to avoid changing cur_copy + for (int i = 0; i < sched->n_backends; i++) { + ggml_backend_synchronize(sched->backends[i]); + } #ifndef NDEBUG GGML_LOG_DEBUG("%s: failed to allocate graph, reserving (backend_ids_changed = %d)\n", __func__, backend_ids_changed); #endif @@ -1564,7 +1567,6 @@ bool ggml_backend_sched_alloc_graph(ggml_backend_sched_t sched, struct ggml_cgra ggml_backend_sched_split_graph(sched, graph); - if (!ggml_backend_sched_alloc_splits(sched)) { return false; } @@ -1598,6 +1600,12 @@ void ggml_backend_sched_synchronize(ggml_backend_sched_t sched) { for (int i = 0; i < sched->n_backends; i++) { ggml_backend_synchronize(sched->backends[i]); } + if (!sched->is_alloc) { + // if the graph is not already allocated, always use copy 0 after a synchronization + // this ensures that during generation the same copy is used every time, + // which avoids changes in the graph that could cause CUDA or other graphs to be disabled + sched->cur_copy = 0; + } } void ggml_backend_sched_set_eval_callback(ggml_backend_sched_t sched, ggml_backend_sched_eval_callback callback, void * user_data) { diff --git a/ggml/src/ggml-cann/CMakeLists.txt b/ggml/src/ggml-cann/CMakeLists.txt old mode 100644 new mode 100755 index 0d8e483b291c7..7742b39153f88 --- a/ggml/src/ggml-cann/CMakeLists.txt +++ b/ggml/src/ggml-cann/CMakeLists.txt @@ -30,6 +30,7 @@ string(TOLOWER ${SOC_TYPE} SOC_VERSION) # SOC_VERSION need lower string(REGEX MATCH "[0-9]+[a-zA-Z]" SOC_TYPE_MAJOR_SN "${SOC_VERSION}") set(SOC_TYPE_COMPILE_OPTION "ASCEND_${SOC_TYPE_MAJOR_SN}") string(TOUPPER ${SOC_TYPE_COMPILE_OPTION} SOC_TYPE_COMPILE_OPTION) +message(STATUS "CANN: SOC_VERSION = ${SOC_VERSION}") if (CANN_INSTALL_DIR) # Only Support Linux. diff --git a/ggml/src/ggml-cann/Doxyfile b/ggml/src/ggml-cann/Doxyfile old mode 100644 new mode 100755 diff --git a/ggml/src/ggml-cann/acl_tensor.cpp b/ggml/src/ggml-cann/acl_tensor.cpp old mode 100644 new mode 100755 index f5462c5a18e37..f311864d486f7 --- a/ggml/src/ggml-cann/acl_tensor.cpp +++ b/ggml/src/ggml-cann/acl_tensor.cpp @@ -31,6 +31,8 @@ aclDataType ggml_cann_type_mapping(ggml_type type) { return ACL_FLOAT; case GGML_TYPE_F16: return ACL_FLOAT16; + case GGML_TYPE_BF16: + return ACL_BF16; case GGML_TYPE_I8: return ACL_INT8; case GGML_TYPE_I16: diff --git a/ggml/src/ggml-cann/acl_tensor.h b/ggml/src/ggml-cann/acl_tensor.h old mode 100644 new mode 100755 diff --git a/ggml/src/ggml-cann/aclnn_ops.cpp b/ggml/src/ggml-cann/aclnn_ops.cpp old mode 100644 new mode 100755 index cbf9783b744d1..437ece2d4a3cf --- a/ggml/src/ggml-cann/aclnn_ops.cpp +++ b/ggml/src/ggml-cann/aclnn_ops.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -74,11 +75,13 @@ #include #include "ggml-impl.h" +#include "ggml.h" #define GGML_COMMON_DECL_C #include "../ggml-common.h" + void bcast_shape(ggml_tensor * src0, ggml_tensor * src1, ggml_tensor * dst, aclTensor ** acl_src0, aclTensor ** acl_src1, aclTensor ** acl_dst) { GGML_ASSERT(ggml_are_same_shape(src0, dst) && ggml_can_repeat(src1, src0)); @@ -2697,14 +2700,10 @@ static void ggml_cann_mul_mat_id_fp(ggml_backend_cann_context& ctx, ggml_tensor* } } - // GroupedMatmulV2 required tensor_list.size < 128 size_t GROUP_SIZE = 128; - std::vector> src0_tensor_vec_vec; - std::vector> src1_tensor_vec_vec; - std::vector> dst_tensor_vec_vec; - - // split and call GroupedMatmulV2 + // GroupedMatmulV2 required tensor_list.size < 128 for (size_t i = 0; i < src0_tensor_vec.size(); i += GROUP_SIZE) { + // split and call GroupedMatmulV2 size_t end = std::min(i + GROUP_SIZE, src0_tensor_vec.size()); std::vector src0_tensor_vec_split(src0_tensor_vec.begin() + i, src0_tensor_vec.begin() + end); std::vector src1_tensor_vec_split(src1_tensor_vec.begin() + i, src1_tensor_vec.begin() + end); @@ -2722,6 +2721,133 @@ static void ggml_cann_mul_mat_id_fp(ggml_backend_cann_context& ctx, ggml_tensor* return; } +/** + * @brief Performs expert-specific matrix multiplication (MoE) with + * quantized precision using the CANN backend. + * + * This function executes a matrix multiplication operation tailored for + * Mixture of Experts (MoE) models, where the input tensor is multiplied + * with expert-specific quantized weight matrices. It leverages the CANN + * backend to perform efficient low-precision computations and stores the + * quantized result in the destination tensor `dst`. + * + * Quantization techniques reduce memory footprint and improve performance + * by using lower-bit representations (e.g., int8) instead of floating-point. + * This function is designed to work with such formats and may incorporate + * optimizations like identity-based fast paths or routing masks for sparse + * expert selection. + * + * @param ctx The context for executing CANN backend operations. + * @param dst The destination tensor where the quantized MoE multiplication result + * will be stored. + * + * @note This function assumes quantized data types and is designed for + * MoE architectures with potential sparse expert routing. + */ +static void ggml_cann_mul_mat_id_quant(ggml_backend_cann_context& ctx, ggml_tensor* dst) { + // TODO: Use aclnnGroupedMatMul + //dst [M, K, N, 1] + ggml_tensor * src0 = dst->src[0]; //src0 [D, M, A, 1] + ggml_tensor * src1 = dst->src[1]; //src1 [D, B, N, 1], B = K or B = 1 + ggml_tensor * ids = dst->src[2]; //ids [K, N] + + GGML_TENSOR_BINARY_OP_LOCALS + + // copy index from npu to cpu + int64_t n_as = ne02; // A + int64_t n_ids = ids->ne[0]; // K + + std::vector ids_host(ggml_nbytes(ids)); + ggml_cann_async_memcpy(ctx, ids_host.data(), ids->data, ggml_nbytes(ids), + ACL_MEMCPY_DEVICE_TO_HOST); + ACL_CHECK(aclrtSynchronizeStream(ctx.stream())); + + char * src0_original = (char *) src0->data; + char * src1_original = (char *) src1->data; + char * dst_original = (char *) dst->data; + + ggml_tensor src0_row = *src0; + ggml_tensor src1_row = *src1; + ggml_tensor dst_row = *dst; + + const enum ggml_type type = dst->src[0]->type; + float weight_elem_size; + if (type == GGML_TYPE_Q4_0) { + weight_elem_size = float(sizeof(uint8_t)) / 2; + } else if (type == GGML_TYPE_Q8_0) { + weight_elem_size = float(sizeof(uint8_t)); + } else { + GGML_ABORT("MUL_MAT_ID only support quant type Q4_0 and Q8_0 "); + } + + // src0_row [D, M, 1, 1] weight without permute + src0_row.ne[2] = 1; + src0_row.ne[3] = 1; + src0_row.nb[0] = weight_elem_size; + src0_row.nb[1] = weight_elem_size * ne00; + src0_row.nb[2] = weight_elem_size * ne00; + src0_row.nb[3] = weight_elem_size * ne00; + size_t weight_stride = ne00 * ne01 * weight_elem_size; + size_t weight_size = weight_stride * ne02 * ne03; + + // scale [D, M, 1, 1] -> scale && permute + size_t scale_elem_size = sizeof(uint16_t); + size_t scale_stride = src0->ne[1] * src0->ne[0] / QK8_0 * scale_elem_size; + + // src1_row [D, 1, 1, 1] -> input + src1_row.ne[1] = 1; + src1_row.ne[2] = 1; + src1_row.ne[3] = 1; + src1_row.nb[2] = nb11; + src1_row.nb[3] = nb11; + + // dst_row [M, 1, 1, 1] -> out + dst_row.ne[1] = 1; + dst_row.ne[2] = 1; + dst_row.ne[3] = 1; + dst_row.nb[2] = nb1; + dst_row.nb[3] = nb1; + + //create weight for one row + ggml_cann_pool_alloc weight_allocator(ctx.pool()); + void* weight_buffer = weight_allocator.alloc(nb02); + for (int64_t iid1 = 0; iid1 < ids->ne[1]; iid1++) { + for (int64_t id = 0; id < n_ids; id++) { + // expert index + int32_t i02 = *(int32_t *) (ids_host.data() + iid1*ids->nb[1] + id*ids->nb[0]); + GGML_ASSERT(i02 >= 0 && i02 < n_as); + + // If B = 1 (broadcast), always use 0; otherwise, use id. + int64_t i11 = (ne11 == 1 ? 0 : id); + int64_t i12 = iid1; + + int64_t i1 = id; + int64_t i2 = i12; + + void* src0_tmp_ptr = src0_original + i02*weight_stride; + void* scale_tmp_ptr = src0_original + weight_size + i02*scale_stride; + void* src1_tmp_ptr = src1_original + i11*nb11 + i12*nb12; + void* dst_tmp_ptr = dst_original + i1*nb1 + i2*nb2; + + // mem cpy + ggml_cann_async_memcpy(ctx, weight_buffer, src0_tmp_ptr, weight_stride, + ACL_MEMCPY_DEVICE_TO_DEVICE); + void* scale_buffer = (char*)weight_buffer + weight_stride; + ggml_cann_async_memcpy(ctx, scale_buffer, scale_tmp_ptr, scale_stride, + ACL_MEMCPY_DEVICE_TO_DEVICE); + + src0_row.data = weight_buffer; + src1_row.data = src1_tmp_ptr; + dst_row.data = dst_tmp_ptr; + dst_row.src[0] = &src0_row; + dst_row.src[1] = &src1_row; + + ggml_cann_mul_mat(ctx, &dst_row); + } + } + return; +} + void ggml_cann_mul_mat_id(ggml_backend_cann_context& ctx, ggml_tensor* dst) { const enum ggml_type type = dst->src[0]->type; switch (type) { @@ -2729,8 +2855,339 @@ void ggml_cann_mul_mat_id(ggml_backend_cann_context& ctx, ggml_tensor* dst) { case GGML_TYPE_F16: ggml_cann_mul_mat_id_fp(ctx, dst); break; + case GGML_TYPE_Q4_0: + case GGML_TYPE_Q8_0: + ggml_cann_mul_mat_id_quant(ctx, dst); + break; default: GGML_ABORT("Unsupported type for mul_mat_id"); break; } } + +void ggml_cann_flash_attn_ext(ggml_backend_cann_context& ctx, ggml_tensor* dst){ + + ggml_tensor* src0 = dst->src[0]; // q, fp32 + ggml_tensor* src1 = dst->src[1]; // k, fp16 + ggml_tensor* src2 = dst->src[2]; // v, fp16 + ggml_tensor* src3 = dst->src[3]; // mask, fp16 + + float maxBias = 0.0f; + float scaleValue = 1.0f; + float logitSoftcap = 0.0f; + memcpy(&scaleValue, (float*)dst->op_params + 0, sizeof(float)); + memcpy(&maxBias, (float*)dst->op_params + 1, sizeof(float)); + memcpy(&logitSoftcap, (float*)dst->op_params + 2, sizeof(float)); + + if(logitSoftcap == 0.0f){ + size_t faElemSize = sizeof(uint16_t); + auto faDataType = ACL_FLOAT16; //ACL_BF16; + + aclTensor* acl_src0_f16_tensor = nullptr; + aclTensor* acl_src1_f16_tensor = nullptr; + aclTensor* acl_src2_f16_tensor = nullptr; + aclTensor* acl_dst_f16_tensor = nullptr; + + // Step 1: cast the src0 (Query) to fp16 if needed + ggml_cann_pool_alloc src0_f16_allocator(ctx.pool()); + void* src0_f16_buffer = nullptr; + + if(ggml_cann_type_mapping(src0->type) != faDataType){ + aclTensor* acl_src0_f32_tensor = ggml_cann_create_tensor(src0); + src0_f16_buffer = src0_f16_allocator.alloc( + ggml_nelements(src0) * faElemSize); + + int64_t* src0_f16_ne = src0->ne; + size_t src0_f16_nb[GGML_MAX_DIMS]; + src0_f16_nb[0] = sizeof(uint16_t); + for(int i = 1; i < GGML_MAX_DIMS; ++i){ + src0_f16_nb[i] = src0_f16_nb[i - 1] * src0_f16_ne[i - 1]; + } + + acl_src0_f16_tensor = ggml_cann_create_tensor( + src0_f16_buffer, faDataType, faElemSize, + src0_f16_ne, src0_f16_nb, GGML_MAX_DIMS + ); + aclnn_cast(ctx, acl_src0_f32_tensor, acl_src0_f16_tensor, faDataType); + ggml_cann_release_resources(ctx, acl_src0_f32_tensor); + }else{ + acl_src0_f16_tensor = ggml_cann_create_tensor(src0); + } + + // Step 2: create the acl tensors for src1 (Key), src2 (Value), + // and the direct output from FusedInferAttention + + acl_src1_f16_tensor = ggml_cann_create_tensor(src1); + acl_src2_f16_tensor = ggml_cann_create_tensor(src2); + + ggml_cann_pool_alloc out_f16_allocator(ctx.pool()); + void* out_f16_buffer = out_f16_allocator.alloc( + ggml_nelements(dst) * faElemSize); + + int64_t* out_f16_ne = src0->ne; + size_t out_f16_nb[GGML_MAX_DIMS]; + out_f16_nb[0] = faElemSize; + for(int i = 1; i < GGML_MAX_DIMS; ++i){ + out_f16_nb[i] = out_f16_nb[i - 1] * out_f16_ne[i - 1]; + } + + acl_dst_f16_tensor = ggml_cann_create_tensor( + out_f16_buffer, faDataType, faElemSize, + out_f16_ne, out_f16_nb, GGML_MAX_DIMS + ); + + // Step 3: create the PSEShift tensor if needed + // this tensor is considered as mask (f16) in the llama.cpp + + aclTensor* bcast_pse_tensor = nullptr; + int64_t bcast_pse_ne[GGML_MAX_DIMS]; + size_t bcast_pse_nb[GGML_MAX_DIMS]; + ggml_cann_pool_alloc bcast_pse_allocator(ctx.pool()); + void* bcast_pse_buffer = nullptr; + + if(src3 != nullptr){ + bcast_pse_buffer = bcast_pse_allocator.alloc( + ggml_nelements(src3) * src0->ne[2] * sizeof(uint16_t)); + + if(src0->ne[1] > 1){ + // Case 1: broadcast pse for prefill stage with multiple head + aclTensor* acl_mask_f16_tensor = ggml_cann_create_tensor(src3); + bcast_pse_ne[0] = src3->ne[0]; + bcast_pse_ne[1] = src3->ne[1]; + bcast_pse_ne[2] = src0->ne[2]; + bcast_pse_ne[3] = src3->ne[3]; + + bcast_pse_nb[0] = sizeof(uint16_t); + for(int i = 1; i < GGML_MAX_DIMS; ++i){ + bcast_pse_nb[i] = bcast_pse_nb[i - 1] * bcast_pse_ne[i - 1]; + } + + bcast_pse_tensor = ggml_cann_create_tensor( + bcast_pse_buffer, ACL_FLOAT16, sizeof(uint16_t), + bcast_pse_ne, bcast_pse_nb, GGML_MAX_DIMS); + + int64_t repeats[] = {1, src0->ne[2], 1, 1}; + aclnn_repeat(ctx, acl_mask_f16_tensor, bcast_pse_tensor, repeats); + + ggml_cann_release_resources(ctx, acl_mask_f16_tensor); + }else{ + // Case 2: trunc the first row and broadcast pse for decode stage with multiple head + int64_t trunc_pse_ne[GGML_MAX_DIMS] = {src3->ne[0], src0->ne[1], src3->ne[2], src3->ne[3]}; + size_t* trunc_pse_nb = src3->nb; + + aclTensor* acl_mask_f16_trunc_tensor = ggml_cann_create_tensor( + src3->data, ACL_FLOAT16, sizeof(uint16_t), + trunc_pse_ne, trunc_pse_nb, GGML_MAX_DIMS); + + bcast_pse_ne[0] = src3->ne[0]; + bcast_pse_ne[1] = src0->ne[1]; + bcast_pse_ne[2] = src0->ne[2]; + bcast_pse_ne[3] = src3->ne[3]; + + bcast_pse_nb[0] = sizeof(uint16_t); + for(int i = 1; i < GGML_MAX_DIMS; ++i){ + bcast_pse_nb[i] = bcast_pse_nb[i - 1] * bcast_pse_ne[i - 1]; + } + + bcast_pse_tensor = ggml_cann_create_tensor( + bcast_pse_buffer, ACL_FLOAT16, sizeof(uint16_t), + bcast_pse_ne, bcast_pse_nb, GGML_MAX_DIMS); + + int64_t repeats[] = {1, src0->ne[2], 1, 1}; + aclnn_repeat(ctx, acl_mask_f16_trunc_tensor, bcast_pse_tensor, repeats); + + ggml_cann_release_resources(ctx, acl_mask_f16_trunc_tensor); + } + + // Compute the slope if needed. Derived from ggml_cann_softmax(). + if(maxBias != 0.0f){ + // alibi + const int64_t ne2_ne3 = src0->ne[2] * src0->ne[3]; + const int64_t n_head = src0->ne[2]; + const int n_heads_log2_floor = 1u << (uint32_t)floor(log2(n_head)); + float m0 = powf(2.0f, -(maxBias) / n_heads_log2_floor); + float m1 = powf(2.0f, -(maxBias / 2.0f) / n_heads_log2_floor); + // init arange + ggml_cann_pool_alloc arange_allocator(ctx.pool(), + ne2_ne3 * faElemSize); + void* tmp_arange_buffer = arange_allocator.get(); + + // arange1: [1, ..., n_heads_log2_floor+1) + float start = 1; + float stop = n_heads_log2_floor + 1; + float step = 1; + int64_t n_elements_arange = n_heads_log2_floor; + + int64_t tmp_arange1_ne[] = {n_heads_log2_floor}; + size_t tmp_arange1_nb[] = {faElemSize}; + aclTensor* tmp_arange1_tensor = ggml_cann_create_tensor( + tmp_arange_buffer, faDataType, faElemSize, + tmp_arange1_ne, tmp_arange1_nb, + GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + + aclnn_arange(ctx, tmp_arange1_tensor, start, stop, step, n_elements_arange); + + aclTensor* tmp_arange2_tensor = nullptr; + if (n_heads_log2_floor < ne2_ne3) { + // arange2: [1, ..., 2 * (k - n_heads_log2_floor) + 1) + start = 1; + stop = 2 * (ne2_ne3 - n_heads_log2_floor) + 1; + step = 2; + n_elements_arange = ne2_ne3 - n_heads_log2_floor; + int64_t tmp_arange2_ne[] = {ne2_ne3 - n_heads_log2_floor}; + size_t tmp_arange2_nb[] = {faElemSize}; + + aclTensor* tmp_arange2_tensor = ggml_cann_create_tensor( + (char*)tmp_arange_buffer + + n_heads_log2_floor * faElemSize, + faDataType, faElemSize, + tmp_arange2_ne, tmp_arange2_nb, GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + aclnn_arange(ctx, tmp_arange2_tensor, start, stop, step, + n_elements_arange); + } + + // init mk_base + ggml_cann_pool_alloc mk_base_allocator(ctx.pool(), + ne2_ne3 * faElemSize); + void* tmp_mk_base_buffer = mk_base_allocator.get(); + int64_t tmp_mk_base1_ne[] = {n_heads_log2_floor}; + size_t tmp_mk_base1_nb[] = {faElemSize}; + aclTensor* tmp_mk_base1_tensor = ggml_cann_create_tensor( + tmp_mk_base_buffer, faDataType, faElemSize, + tmp_mk_base1_ne, tmp_mk_base1_nb, + GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + + aclnn_fill_scalar(ctx, m0, tmp_mk_base1_tensor); + + aclTensor* tmp_mk_base2_tensor = nullptr; + if (n_heads_log2_floor < ne2_ne3) { + int64_t tmp_mk_base2_ne[] = {ne2_ne3 - n_heads_log2_floor}; + size_t tmp_mk_base2_nb[] = {faElemSize}; + aclTensor* tmp_mk_base2_tensor = ggml_cann_create_tensor( + (char*)tmp_mk_base_buffer + + n_heads_log2_floor * faElemSize, + faDataType, faElemSize, + tmp_mk_base2_ne, tmp_mk_base2_nb, GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + aclnn_fill_scalar(ctx, m1, tmp_mk_base2_tensor); + } + + // init mk + int64_t tmp_mk_base_ne[] = {ne2_ne3}; + size_t tmp_mk_base_nb[] = {faElemSize}; + aclTensor* tmp_mk_base_tensor = ggml_cann_create_tensor( + tmp_mk_base_buffer, faDataType, faElemSize, + tmp_mk_base_ne, tmp_mk_base_nb, + GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + aclTensor* tmp_arange_tensor = ggml_cann_create_tensor( + tmp_arange_buffer, faDataType, faElemSize, + tmp_mk_base_ne, tmp_mk_base_nb, + GGML_MAX_DIMS - 3, ACL_FORMAT_ND); + aclnn_pow_tensor_tensor(ctx, tmp_mk_base_tensor, tmp_arange_tensor); + + // reshape mk + int64_t tmp_mk_ne[] = {1, 1, src0->ne[2], src0->ne[3]}; + size_t tmp_mk_nb[GGML_MAX_DIMS]; + tmp_mk_nb[0] = faElemSize; + for (int i = 1; i < GGML_MAX_DIMS; i++) { + tmp_mk_nb[i] = tmp_mk_nb[i - 1] * tmp_mk_ne[i - 1]; + } + aclTensor* tmp_mk_tensor = ggml_cann_create_tensor( + tmp_mk_base_buffer, faDataType, faElemSize, + tmp_mk_ne, tmp_mk_nb, GGML_MAX_DIMS, + ACL_FORMAT_ND); + GGML_CANN_CALL_ACLNN_OP(ctx, InplaceMul, bcast_pse_tensor, tmp_mk_tensor); + + ggml_cann_release_resources(ctx, tmp_arange1_tensor, tmp_arange2_tensor, + tmp_mk_base1_tensor, tmp_mk_base2_tensor, tmp_mk_base_tensor, + tmp_arange_tensor, tmp_mk_tensor); + } + } + + // Step 4: set the inputs for FusedInferAttention. + int kvTensorNum = 1; + aclTensor* acl_q_tensor = acl_src0_f16_tensor; + aclTensor* acl_k_tensors[] = {acl_src1_f16_tensor}; + aclTensor* acl_v_tensors[] = {acl_src2_f16_tensor}; + auto acl_k_tensor_list = aclCreateTensorList(acl_k_tensors, kvTensorNum); + auto acl_v_tensor_list = aclCreateTensorList(acl_v_tensors, kvTensorNum); + + int64_t numHeads = src0->ne[2]; // N + int64_t numKeyValueHeads = src1->ne[2]; + // double scaleValue = 1 / sqrt(src0->ne[0]); // 1/sqrt(d) + int64_t preTokens = 65535; + int64_t nextTokens = 65535; + char layout[5] = {'B', 'N', 'S', 'D', 0}; + int64_t sparseMode = 0; + int64_t innerPrecise = (src0->ne[1] == 1) ? 0 : 2; + int64_t blockSize = 0; + int64_t antiquantMode = 0; + bool softmaxLseFlag = false; + int64_t keyAntiquantMode = 0; + int64_t valueAntiquantMode = 0; + + // Step 5: launch the FusedInferAttentionScoreV2 kernel. + // Refer to https://gitee.com/ascend/cann-ops-adv/blob/master/docs/FusedInferAttentionScoreV2.md + + GGML_CANN_CALL_ACLNN_OP(ctx, FusedInferAttentionScoreV2, + acl_q_tensor, acl_k_tensor_list, acl_v_tensor_list, // q, k, v + bcast_pse_tensor, nullptr, // pse, mask + nullptr, nullptr, // actSeqLen, actSeqLenkv + nullptr, nullptr, // deqScale1, quantScale1 + nullptr, nullptr, nullptr, // deqScale2, quantScale2, quantOffset2 + nullptr, nullptr, // antiquantScale, antiquantOffset + nullptr, // blockTable + nullptr, nullptr, // qPadSize, kvPadSize + nullptr, nullptr, // kAntiquantScale, kAntiQuantOffset + nullptr, nullptr, // vAntiquantScale, vAntiQuantOffset + nullptr, nullptr, nullptr, // kSharedPrefix, vSharedPrefix, actSharedLen + numHeads, scaleValue, // heads, scaleValue + preTokens, nextTokens, // preTokens, nextTokens + layout, // inputLayout + numKeyValueHeads, // numKVHeads + sparseMode, innerPrecise, // sparseMode, innerPrecise + blockSize, antiquantMode, // blockSize, antiquantMode + softmaxLseFlag, // softmaxLseFlag + keyAntiquantMode, valueAntiquantMode, // keyAntiqMode, valueAntiqMode + acl_dst_f16_tensor, // attentionOut + nullptr // softmaxLse + ); + + // Step 6: post-processing, permute and cast to f32 + + int64_t new_dim[] = {0, 2, 1, 3}; + aclTensor* acl_dst_tensor = ggml_cann_create_tensor(dst); + + if(ggml_cann_type_mapping(dst->type) != faDataType){ + ggml_cann_pool_alloc perm_out_f16_allocator(ctx.pool()); + perm_out_f16_allocator.alloc(ggml_nelements(dst) * faElemSize); + void* perm_out_f16_buffer = perm_out_f16_allocator.get(); + + int64_t* perm_out_f16_ne = dst->ne; + size_t perm_out_f16_nb[GGML_MAX_DIMS]; + perm_out_f16_nb[0] = faElemSize; + for(int i = 1; i < GGML_MAX_DIMS; ++i){ + perm_out_f16_nb[i] = perm_out_f16_nb[i - 1] * perm_out_f16_ne[i - 1]; + } + aclTensor* acl_perm_out_f16_tensor = ggml_cann_create_tensor( + perm_out_f16_buffer, faDataType, faElemSize, + perm_out_f16_ne, perm_out_f16_nb, GGML_MAX_DIMS); + aclnn_permute(ctx, acl_dst_f16_tensor, acl_perm_out_f16_tensor, new_dim, GGML_MAX_DIMS); + aclnn_cast(ctx, + acl_perm_out_f16_tensor, acl_dst_tensor, ggml_cann_type_mapping(dst->type)); + ggml_cann_release_resources(ctx, acl_perm_out_f16_tensor); + }else{ + // only need to permute + aclnn_permute(ctx, acl_dst_f16_tensor, acl_dst_tensor, new_dim, GGML_MAX_DIMS); + } + ggml_cann_release_resources(ctx, acl_src0_f16_tensor, + acl_src1_f16_tensor, + acl_src2_f16_tensor, + acl_dst_f16_tensor, + acl_dst_tensor); + if(src3 != nullptr){ + ggml_cann_release_resources(ctx, bcast_pse_tensor); + } + }else{ + GGML_ABORT("Function is not implemented."); + } +} diff --git a/ggml/src/ggml-cann/aclnn_ops.h b/ggml/src/ggml-cann/aclnn_ops.h old mode 100644 new mode 100755 index 15993cce66f2f..80ce80baea02c --- a/ggml/src/ggml-cann/aclnn_ops.h +++ b/ggml/src/ggml-cann/aclnn_ops.h @@ -714,6 +714,21 @@ void ggml_cann_count_equal(ggml_backend_cann_context& ctx, ggml_tensor* dst); */ void ggml_cann_step(ggml_backend_cann_context& ctx, ggml_tensor* dst); +/** + * @brief Performs the Flash Attention extended operator using the CANN backend. + * + * @details This function implements the memory-efficient Flash Attention algorithm + * for computing scaled dot-product attention with hardware acceleration. + * The result is stored in the destination tensor `dst`. + * + * This operation is accelerated using the CANN backend to improve runtime performance. + * + * @param ctx The CANN context used for operations. + * @param dst The destination tensor where the result will be stored. + * dst->op is expected to be `GGML_OP_FLASH_ATTN_EXT`. + */ +void ggml_cann_flash_attn_ext(ggml_backend_cann_context& ctx, ggml_tensor* dst); + /* * @brief A generic wrapper for ACL resources with custom deleter support. */ diff --git a/ggml/src/ggml-cann/common.h b/ggml/src/ggml-cann/common.h old mode 100644 new mode 100755 diff --git a/ggml/src/ggml-cann/ggml-cann.cpp b/ggml/src/ggml-cann/ggml-cann.cpp old mode 100644 new mode 100755 index 0cb7bbf17cca5..c0ea26002196f --- a/ggml/src/ggml-cann/ggml-cann.cpp +++ b/ggml/src/ggml-cann/ggml-cann.cpp @@ -36,6 +36,7 @@ #include "ggml-backend-impl.h" #include "ggml-cann/aclnn_ops.h" #include "ggml-cann/common.h" +#include "ggml.h" #define GGML_COMMON_DECL_C @@ -1748,6 +1749,9 @@ static bool ggml_cann_compute_forward(ggml_backend_cann_context& ctx, case GGML_OP_COUNT_EQUAL: ggml_cann_count_equal(ctx, dst); break; + case GGML_OP_FLASH_ATTN_EXT: + ggml_cann_flash_attn_ext(ctx, dst); + break; default: return false; } @@ -2035,6 +2039,15 @@ static bool ggml_backend_cann_supports_op(ggml_backend_dev_t dev, case GGML_TYPE_F16: case GGML_TYPE_F32: return true; + case GGML_TYPE_Q8_0: + case GGML_TYPE_Q4_0: +#ifdef ASCEND_310P + // Q4 && Q8 per group is not suppor on 310p device + return false; +#endif + // only support contiguous for quantized types. + return ggml_is_contiguous(op->src[0]) && + ggml_is_contiguous(op->src[1]); default: return false; } @@ -2168,6 +2181,38 @@ static bool ggml_backend_cann_supports_op(ggml_backend_dev_t dev, case GGML_OP_PAD_REFLECT_1D: case GGML_OP_COUNT_EQUAL: return true; + case GGML_OP_FLASH_ATTN_EXT:{ + // derived from [ggml-cuda.cu] + if(op->src[1]->type != GGML_TYPE_F16 || op->src[2]->type != GGML_TYPE_F16){ + return false; + } + if(op->src[1]->type != GGML_TYPE_F16 && op->src[1]->type != GGML_TYPE_F32 && op->src[1]->type != GGML_TYPE_BF16){ + return false; + } + if(op->type != GGML_TYPE_F16 && op->type != GGML_TYPE_F32 && op->type != GGML_TYPE_BF16){ + return false; + } + if (op->src[1]->ne[0] != op->src[2]->ne[0]) { + // different head sizes of K and V are not supported yet + return false; + } + if (op->src[0]->ne[0] == 192) { + return false; + } + if (op->src[0]->ne[0] == 576) { + // DeepSeek MLA + return false; + } + if (op->src[0]->ne[3] != 1) { + return false; + } + float logitSoftcap = 0.0f; + memcpy(&logitSoftcap, (float*)op->op_params + 2, sizeof(float)); + if(logitSoftcap != 0.0f) { + return false; + } + return true; + } default: return false; } diff --git a/ggml/src/ggml-cpu/CMakeLists.txt b/ggml/src/ggml-cpu/CMakeLists.txt index 1d4259dae5ba7..b3237eeadd22b 100644 --- a/ggml/src/ggml-cpu/CMakeLists.txt +++ b/ggml/src/ggml-cpu/CMakeLists.txt @@ -82,13 +82,8 @@ function(ggml_add_cpu_backend_variant_impl tag_name) target_link_libraries(${GGML_CPU_NAME} PUBLIC memkind) endif() - if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64" OR - CMAKE_GENERATOR_PLATFORM_LWR STREQUAL "arm64" OR - (NOT CMAKE_OSX_ARCHITECTURES AND NOT CMAKE_GENERATOR_PLATFORM_LWR AND - CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm.*|ARM64)$")) - + if (GGML_SYSTEM_ARCH STREQUAL "ARM") message(STATUS "ARM detected") - if (MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "MSVC is not supported for ARM, use clang") else() @@ -170,12 +165,8 @@ function(ggml_add_cpu_backend_variant_impl tag_name) endforeach() endif() endif() - elseif (CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64" OR CMAKE_GENERATOR_PLATFORM_LWR MATCHES "^(x86_64|i686|amd64|x64|win32)$" OR - (NOT CMAKE_OSX_ARCHITECTURES AND NOT CMAKE_GENERATOR_PLATFORM_LWR AND - CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|i686|AMD64|amd64)$")) - + elseif (GGML_SYSTEM_ARCH STREQUAL "x86") message(STATUS "x86 detected") - if (MSVC) # instruction set detection for MSVC only if (GGML_NATIVE) @@ -299,7 +290,26 @@ function(ggml_add_cpu_backend_variant_impl tag_name) endif() endif() endif() - elseif ("${CMAKE_SYSTEM_PROCESSOR} " STREQUAL "ppc64le " OR "${CMAKE_SYSTEM_PROCESSOR} " STREQUAL "powerpc ") + + if (GGML_BACKEND_DL) + if (GGML_NATIVE) + # the feature check relies on ARCH_DEFINITIONS, but it is not set with GGML_NATIVE + message(FATAL_ERROR "GGML_NATIVE is not compatible with GGML_BACKEND_DL, consider using GGML_CPU_ALL_VARIANTS") + endif() + + # The feature detection code is compiled as a separate target so that + # it can be built without the architecture flags + # Since multiple variants of the CPU backend may be included in the same + # build, using set_source_files_properties() to set the arch flags is not possible + set(GGML_CPU_FEATS_NAME ${GGML_CPU_NAME}-feats) + add_library(${GGML_CPU_FEATS_NAME} OBJECT ggml-cpu/cpu-feats-x86.cpp) + target_include_directories(${GGML_CPU_FEATS_NAME} PRIVATE . .. ../include) + target_compile_definitions(${GGML_CPU_FEATS_NAME} PRIVATE ${ARCH_DEFINITIONS}) + target_compile_definitions(${GGML_CPU_FEATS_NAME} PRIVATE GGML_BACKEND_DL GGML_BACKEND_BUILD GGML_BACKEND_SHARED) + set_target_properties(${GGML_CPU_FEATS_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) + target_link_libraries(${GGML_CPU_NAME} PRIVATE ${GGML_CPU_FEATS_NAME}) + endif() + elseif (GGML_SYSTEM_ARCH STREQUAL "PowerPC") message(STATUS "PowerPC detected") if (GGML_NATIVE) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64") @@ -325,9 +335,8 @@ function(ggml_add_cpu_backend_variant_impl tag_name) list(APPEND ARCH_FLAGS -mcpu=${GGML_CPU_POWERPC_CPUTYPE}) endif() endif() - elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64") + elseif (GGML_SYSTEM_ARCH STREQUAL "loongarch64") message(STATUS "loongarch64 detected") - list(APPEND ARCH_FLAGS -march=loongarch64) if (GGML_LASX) list(APPEND ARCH_FLAGS -mlasx) @@ -335,16 +344,18 @@ function(ggml_add_cpu_backend_variant_impl tag_name) if (GGML_LSX) list(APPEND ARCH_FLAGS -mlsx) endif() - elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") - message(STATUS "RISC-V detected") + elseif (GGML_SYSTEM_ARCH STREQUAL "riscv64") + message(STATUS "riscv64 detected") if (GGML_RVV) - if (GGML_RV_ZFH) - list(APPEND ARCH_FLAGS -march=rv64gcv_zfhmin -DGGML_RV_ZFH -mabi=lp64d) + if (GGML_XTHEADVECTOR) + list(APPEND ARCH_FLAGS -march=rv64gc_xtheadvector -mabi=lp64d) + elseif (GGML_RV_ZFH) + list(APPEND ARCH_FLAGS -march=rv64gcv_zfhmin -mabi=lp64d) else() list(APPEND ARCH_FLAGS -march=rv64gcv -mabi=lp64d) endif() endif() - elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "s390x") + elseif (GGML_SYSTEM_ARCH STREQUAL "s390x") message(STATUS "s390x detected") file(READ "/proc/cpuinfo" CPUINFO_CONTENTS) string(REGEX REPLACE "machine[ \t\r\n]*=[ \t\r\n]*([0-9]+)" "\\1" S390X_M ${CPUINFO_CONTENTS}) @@ -477,25 +488,6 @@ function(ggml_add_cpu_backend_variant_impl tag_name) target_compile_options(${GGML_CPU_NAME} PRIVATE ${ARCH_FLAGS}) target_compile_definitions(${GGML_CPU_NAME} PRIVATE ${ARCH_DEFINITIONS}) - if (GGML_BACKEND_DL) - if (GGML_NATIVE) - # the feature check relies on ARCH_DEFINITIONS, but it is not set with GGML_NATIVE - message(FATAL_ERROR "GGML_NATIVE is not compatible with GGML_BACKEND_DL, consider using GGML_CPU_ALL_VARIANTS") - endif() - - # The feature detection code is compiled as a separate target so that - # it can be built without the architecture flags - # Since multiple variants of the CPU backend may be included in the same - # build, using set_source_files_properties() to set the arch flags is not possible - set(GGML_CPU_FEATS_NAME ${GGML_CPU_NAME}-feats) - add_library(${GGML_CPU_FEATS_NAME} OBJECT ggml-cpu/cpu-feats-x86.cpp) - target_include_directories(${GGML_CPU_FEATS_NAME} PRIVATE . .. ../include) - target_compile_definitions(${GGML_CPU_FEATS_NAME} PRIVATE ${ARCH_DEFINITIONS}) - target_compile_definitions(${GGML_CPU_FEATS_NAME} PRIVATE GGML_BACKEND_DL GGML_BACKEND_BUILD GGML_BACKEND_SHARED) - set_target_properties(${GGML_CPU_FEATS_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) - target_link_libraries(${GGML_CPU_NAME} PRIVATE ${GGML_CPU_FEATS_NAME}) - endif() - if (EMSCRIPTEN) set_target_properties(${GGML_CPU_NAME} PROPERTIES COMPILE_FLAGS "-msimd128") endif() diff --git a/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp b/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp index 8ff6d64a4d0d1..0a3ff867cfeca 100644 --- a/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp +++ b/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp @@ -1191,7 +1191,7 @@ static void ggml_gemv_q4_0_8x8_q8_0(int n, float * GGML_RESTRICT s, size_t bs, c } } return; -#elif defined(__riscv_v_intrinsic) +#elif defined __riscv_v if (__riscv_vlenb() >= QK4_0) { const size_t vl = QK4_0; @@ -3783,7 +3783,7 @@ static void ggml_gemm_q4_0_8x8_q8_0(int n, float * GGML_RESTRICT s, size_t bs, c } return; } -#elif defined(__riscv_v_intrinsic) +#elif defined __riscv_v if (__riscv_vlenb() >= QK4_0) { const size_t vl = QK4_0; diff --git a/ggml/src/ggml-cpu/ggml-cpu-impl.h b/ggml/src/ggml-cpu/ggml-cpu-impl.h index e4af07635c157..b3f1b5ca79092 100644 --- a/ggml/src/ggml-cpu/ggml-cpu-impl.h +++ b/ggml/src/ggml-cpu/ggml-cpu-impl.h @@ -320,21 +320,17 @@ inline static int32x4_t ggml_vdotq_s32(int32x4_t acc, int8x16_t a, int8x16_t b) #ifdef __wasm_simd128__ #include -#else +#endif + #ifdef __POWER9_VECTOR__ #include -#else +#endif + #if defined(_MSC_VER) || defined(__MINGW32__) #include -#else -#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) || defined(__SSE3__) || defined(__SSE__) -#if !defined(__riscv) +#elif defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) || defined(__SSE3__) || defined(__SSE__) #include #endif -#endif -#endif -#endif -#endif #ifdef __riscv_v_intrinsic #include diff --git a/ggml/src/ggml-cpu/ggml-cpu-quants.c b/ggml/src/ggml-cpu/ggml-cpu-quants.c index a89ce9bb1e93c..40bded4767b47 100644 --- a/ggml/src/ggml-cpu/ggml-cpu-quants.c +++ b/ggml/src/ggml-cpu/ggml-cpu-quants.c @@ -883,7 +883,7 @@ void quantize_row_q8_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, i _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4); #endif } -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl = QK8_0; @@ -1221,7 +1221,7 @@ void quantize_row_q8_1(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, i _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4); #endif } -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl = QK8_1; @@ -2384,7 +2384,7 @@ void ggml_vec_dot_q4_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const voi } sumf = hsum_float_4x4(acc_0, acc_1, acc_2, acc_3); -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl = qk / 2; for (; ib < nb; ++ib) { @@ -2774,7 +2774,7 @@ void ggml_vec_dot_q4_1_q8_1(int n, float * GGML_RESTRICT s, size_t bs, const voi } sumf = hsum_float_8(acc) + summs; -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl = qk / 2; for (; ib < nb; ++ib) { @@ -3121,7 +3121,7 @@ void ggml_vec_dot_q5_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const voi } sumf = hsum_float_8(acc); -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl; size_t vlenb = __riscv_vlenb(); @@ -3460,7 +3460,7 @@ void ggml_vec_dot_q5_1_q8_1(int n, float * GGML_RESTRICT s, size_t bs, const voi } sumf = hsum_float_8(acc) + summs; -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl; size_t vlenb = __riscv_vlenb(); @@ -3897,7 +3897,7 @@ void ggml_vec_dot_q8_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const voi } sumf = hsum_float_8(accum); -#elif defined(__riscv_v_intrinsic) +#elif defined(__riscv_v) size_t vl = qk; for (; ib < nb; ++ib) { @@ -5100,14 +5100,111 @@ void ggml_vec_dot_q2_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi *s = sumf; -#elif defined __riscv_v_intrinsic +#elif defined __riscv_xtheadvector + + float sumf = 0; + uint8_t atmp[16]; + + for (int i = 0; i < nb; ++i) { + const uint8_t * q2 = x[i].qs; + const int8_t * q8 = y[i].qs; + const uint8_t * sc = x[i].scales; + const float dall = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + uint8_t *patmp = atmp; + int vsums; + int tmp; + __asm__ __volatile__( + "th.vsetvli zero, %[vl16], e8, m1\n\t" + "th.vmv.v.x v8, zero\n\t" + "th.vlb.v v1, (%[sc])\n\t" + "th.vand.vi v0, v1, 0xF\n\t" + "th.vsrl.vi v1, v1, 4\n\t" + "th.vsb.v v0, (%[scale])\n\t" + "th.vwaddu.vx v16, v1, zero\n\t" + "th.vsetvli zero, %[vl16], e16, m2\n\t" + "th.vlh.v v2, (%[bsums])\n\t" + "th.vwmul.vv v4, v16, v2\n\t" + "th.vsetvli zero, %[vl16], e32, m4\n\t" + "th.vredsum.vs v8, v4, v8\n\t" + "th.vmv.x.s %[vsums], v8" + : [tmp] "=&r" (tmp), [vsums] "=&r" (vsums) + : [sc] "r" (sc), [scale] "r" (atmp), [bsums] "r" (y[i].bsums) + , [vl16] "r" (16) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + sumf += dmin * vsums; + int isum = 0; + + for (int j = 0; j < QK_K/128; ++j) { + __asm__ __volatile__( + "th.vsetvli zero, %[vl32], e8, m2\n\t" + "th.vlb.v v0, (%[q2])\n\t" + "th.vsrl.vi v2, v0, 2\n\t" + "th.vsrl.vi v4, v0, 4\n\t" + "th.vsrl.vi v6, v0, 6\n\t" + "th.vand.vi v0, v0, 0x3\n\t" + "th.vand.vi v2, v2, 0x3\n\t" + "th.vand.vi v4, v4, 0x3\n\t" + "th.vsetvli zero, %[vl128], e8, m8\n\t" + "th.vlb.v v8, (%[q8])\n\t" + "th.vsetvli zero, %[vl64], e8, m4\n\t" + "th.vwmul.vv v16, v0, v8\n\t" + "th.vwmul.vv v24, v4, v12\n\t" + "th.vsetvli zero, %[vl16], e16, m2\n\t" + "th.vmv.v.x v0, zero\n\t" + "th.vwredsum.vs v10, v16, v0\n\t" + "th.vwredsum.vs v9, v18, v0\n\t" + "th.vwredsum.vs v8, v20, v0\n\t" + "th.vwredsum.vs v7, v22, v0\n\t" + "th.vwredsum.vs v11, v24, v0\n\t" + "th.vwredsum.vs v12, v26, v0\n\t" + "th.vwredsum.vs v13, v28, v0\n\t" + "th.vwredsum.vs v14, v30, v0\n\t" + "li %[tmp], 4\n\t" + "th.vsetvli zero, %[tmp], e32, m1\n\t" + "th.vslideup.vi v10, v9, 1\n\t" + "th.vslideup.vi v8, v7, 1\n\t" + "th.vslideup.vi v11, v12, 1\n\t" + "th.vslideup.vi v13, v14, 1\n\t" + "th.vslideup.vi v10, v8, 2\n\t" + "th.vslideup.vi v11, v13, 2\n\t" + "li %[tmp], 8\n\t" + "th.vsetvli zero, %[tmp], e32, m2\n\t" + "th.vlbu.v v12, (%[scale])\n\t" + "th.vmul.vv v10, v10, v12\n\t" + "th.vredsum.vs v0, v10, v0\n\t" + "th.vmv.x.s %[tmp], v0\n\t" + "add %[isum], %[isum], %[tmp]" + : [tmp] "=&r" (tmp), [isum] "+&r" (isum) + : [q2] "r" (q2), [scale] "r" (patmp), [q8] "r" (q8) + , [vl16] "r" (16), [vl32] "r" (32), [vl64] "r" (64), [vl128] "r" (128) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + q2 += 32; q8 += 128; patmp += 8; + } + + sumf += dall * isum; + } + + *s = sumf; + +#elif defined __riscv_v - const int vector_length = __riscv_vlenb() * 8; float sumf = 0; + uint8_t atmp[16]; + const int vector_length = __riscv_vlenb() * 8; uint8_t temp_01[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - uint8_t atmp[16]; switch (vector_length) { case 256: @@ -6137,13 +6234,140 @@ void ggml_vec_dot_q3_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi *s = sumf; -#elif defined __riscv_v_intrinsic +#elif defined __riscv_xtheadvector - uint32_t aux[3]; uint32_t utmp[4]; + float sumf = 0; - const int vector_length = __riscv_vlenb() * 8; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q3 = x[i].qs; + const uint8_t * restrict qh = x[i].hmask; + const int8_t * restrict q8 = y[i].qs; + + int8_t * scale = (int8_t *)utmp; + int tmp; + __asm__ __volatile__( + "li %[tmp], 12\n\t" + "th.vsetvli zero, %[tmp], e8, m1\n\t" + "th.vlb.v v0, (%[s6b])\n\t" + "th.vmv.v.v v2, v0\n\t" + "li %[tmp], 2\n\t" + "th.vsetvli zero, %[tmp], e64, m1\n\t" + "th.vmv.v.x v9, %[sh]\n\t"\ + "th.vslidedown.vi v1, v0, 1\n\t" + "th.vslide1up.vx v8, v9, zero\n\t" // {0, 0, 4, 4} + "th.vslideup.vi v0, v2, 1\n\t" // {aux[0], aux[1], aux[0], aux[1]} + "li %[tmp], 4\n\t" + "th.vsetvli zero, %[tmp], e32, m1\n\t" + "th.vid.v v9\n\t" + "th.vmv.x.s %[tmp], v1\n\t" + "th.vsll.vi v9, v9, 1\n\t" // {0, 2, 4, 6} + "th.vmv.v.x v1, %[tmp]\n\t" // {aux[2], aux[2], aux[2], aux[2]} + "th.vsrl.vv v4, v1, v9\n\t" + "th.vsrl.vv v2, v0, v8\n\t" + "th.vand.vx v5, v4, %[kmask1]\n\t" + "th.vand.vx v3, v2, %[kmask2]\n\t" + "th.vsll.vi v6, v5, 4\n\t" + "th.vor.vv v7, v6, v3\n\t" + "li %[tmp], 16\n\t" + "th.vsetvli zero, %[tmp], e8, m1\n\t" + "th.vsub.vx v0, v7, %[c]\n\t" + "th.vsb.v v0, (%[scale])" + : [tmp] "=&r" (tmp) + : [sh] "r" (0x0000000400000004), [s6b] "r" (x[i].scales), [c] "r" (32) + , [scale] "r" (scale), [kmask1] "r" (kmask1), [kmask2] "r" (kmask2) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + + uint8_t m = 1; + int isum = 0; + for (int j = 0; j < QK_K; j += 128) { + __asm__ __volatile__( + // fixme: use v0p7 mask layout directly + "th.vsetvli zero, %[vl32], e8, m2\n\t" + "th.vlb.v v8, (%[q3])\n\t" + "th.vsrl.vi v10, v8, 2\n\t" + "th.vsrl.vi v12, v8, 4\n\t" + "th.vsrl.vi v14, v8, 6\n\t" + "th.vand.vi v8, v8, 3\n\t" + "th.vand.vi v10, v10, 3\n\t" + "th.vand.vi v12, v12, 3\n\t" + "th.vlb.v v2, (%[qh])\n\t" + "th.vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "th.vmseq.vx v0, v4, zero\n\t" + "th.vadd.vi v8, v8, -4, v0.t\n\t" + "th.vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "th.vmseq.vx v0, v4, zero\n\t" + "th.vadd.vi v10, v10, -4, v0.t\n\t" + "th.vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "th.vmseq.vx v0, v4, zero\n\t" + "th.vadd.vi v12, v12, -4, v0.t\n\t" + "th.vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "th.vmseq.vx v0, v4, zero\n\t" + "th.vadd.vi v14, v14, -4, v0.t\n\t" + "th.vsetvli zero, %[vl128], e8, m8\n\t" + "th.vlb.v v0, (%[q8])\n\t" + "th.vsetvli zero, %[vl64], e8, m4\n\t" + "th.vwmul.vv v16, v0, v8\n\t" + "th.vwmul.vv v24, v4, v12\n\t" + "li %[tmp], 16\n\t" + "th.vsetvli zero, %[tmp], e16, m2\n\t" + "th.vmv.v.x v0, zero\n\t" + "th.vwredsum.vs v10, v16, v0\n\t" + "th.vwredsum.vs v9, v18, v0\n\t" + "th.vwredsum.vs v8, v20, v0\n\t" + "th.vwredsum.vs v7, v22, v0\n\t" + "th.vwredsum.vs v11, v24, v0\n\t" + "th.vwredsum.vs v12, v26, v0\n\t" + "th.vwredsum.vs v13, v28, v0\n\t" + "th.vwredsum.vs v14, v30, v0\n\t" + "li %[tmp], 4\n\t" + "th.vsetvli zero, %[tmp], e32, m1\n\t" + "th.vslideup.vi v10, v9, 1\n\t" + "th.vslideup.vi v8, v7, 1\n\t" + "th.vslideup.vi v11, v12, 1\n\t" + "th.vslideup.vi v13, v14, 1\n\t" + "th.vslideup.vi v10, v8, 2\n\t" + "th.vslideup.vi v11, v13, 2\n\t" + "li %[tmp], 8\n\t" + "th.vsetvli zero, %[tmp], e32, m2\n\t" + "th.vlb.v v12, (%[scale])\n\t" + "th.vmul.vv v10, v10, v12\n\t" + "th.vredsum.vs v0, v10, v0\n\t" + "th.vmv.x.s %[tmp], v0\n\t" + "add %[isum], %[isum], %[tmp]" + : [tmp] "=&r" (tmp), [m] "+&r" (m), [isum] "+&r" (isum) + : [vl128] "r" (128), [vl64] "r" (64), [vl32] "r" (32) + , [q3] "r" (q3), [qh] "r" (qh), [scale] "r" (scale), [q8] "r" (q8) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + q3 += 32; q8 += 128; scale += 8; + } + + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + sumf += d * isum; + } + + *s = sumf; + +#elif defined __riscv_v + + uint32_t utmp[4]; float sumf = 0; + uint32_t aux[3]; + const int vector_length = __riscv_vlenb() * 8; switch (vector_length) { case 256: @@ -6331,7 +6555,7 @@ void ggml_vec_dot_q3_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi "vslideup.vi v13, v14, 1\n\t" "vslideup.vi v10, v8, 2\n\t" "vslideup.vi v11, v13, 2\n\t" - "vsetivli zero, 8, e32, m2\n\t"\ + "vsetivli zero, 8, e32, m2\n\t" "vle8.v v15, (%[scale])\n\t" "vsext.vf4 v12, v15\n\t" "vmul.vv v10, v10, v12\n\t" @@ -6771,7 +6995,11 @@ void ggml_vec_dot_q3_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi void ggml_vec_dot_q4_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) { assert(n % QK_K == 0); +#ifdef __ARM_FEATURE_MATMUL_INT8 + assert((nrc == 2) || (nrc == 1)); +#else assert(nrc == 1); +#endif UNUSED(nrc); UNUSED(bx); UNUSED(by); @@ -6788,6 +7016,146 @@ void ggml_vec_dot_q4_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi uint32_t utmp[4]; +#if defined(__ARM_FEATURE_MATMUL_INT8) + if (nrc == 2) { + const block_q4_K * GGML_RESTRICT x0 = x; + const block_q4_K * GGML_RESTRICT x1 = (const block_q4_K *) ((const uint8_t *)vx + bx); + const block_q8_K * GGML_RESTRICT y0 = y; + const block_q8_K * GGML_RESTRICT y1 = (const block_q8_K *) ((const uint8_t *)vy + by); + + const uint8x16_t m4b = vdupq_n_u8(0x0f); + + float32x4_t vfsum = vdupq_n_f32(0.0f); + + for (int i = 0; i < nb; ++i, ++x0, ++x1, ++y0, ++y1) { + const uint8_t * GGML_RESTRICT qx0 = x0->qs; + const uint8_t * GGML_RESTRICT qx1 = x1->qs; + const int8_t * GGML_RESTRICT qy0 = y0->qs; + const int8_t * GGML_RESTRICT qy1 = y1->qs; + + // decode scales and mins + int8_t x0_scales[8], x1_scales[8]; + int16x8_t x0_mins, x1_mins; + { + uint32_t scales_mins[3]; + memcpy(scales_mins, x0->scales, 12); + const uint32_t mins_0_3 = scales_mins[1] & kmask1; + const uint32_t mins_4_7 = ((scales_mins[2] >> 4) & kmask2) | (((scales_mins[1] >> 6) & kmask3) << 4); + const uint32x2_t mins = {mins_0_3, mins_4_7}; + x0_mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins))); + uint32_t scales[2]; + scales[0] = scales_mins[0] & kmask1; // scales 0~3 + scales[1] = (scales_mins[2] & kmask2) | (((scales_mins[0] >> 6) & kmask3) << 4); // scales 4~7 + memcpy(x0_scales, scales, 8); + } + { + uint32_t scales_mins[3]; + memcpy(scales_mins, x1->scales, 12); + const uint32_t mins_0_3 = scales_mins[1] & kmask1; + const uint32_t mins_4_7 = ((scales_mins[2] >> 4) & kmask2) | (((scales_mins[1] >> 6) & kmask3) << 4); + const uint32x2_t mins = {mins_0_3, mins_4_7}; + x1_mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins))); + uint32_t scales[2]; + scales[0] = scales_mins[0] & kmask1; // scales 0~3 + scales[1] = (scales_mins[2] & kmask2) | (((scales_mins[0] >> 6) & kmask3) << 4); // scales 4~7 + memcpy(x1_scales, scales, 8); + } + + int32x4_t visum = {0}; + + // process 64 data points per iteration, totally 256 data points + for (int j = 0; j < QK_K / 64; ++j, qx0 += 32, qx1 += 32, qy0 += 64, qy1 += 64) { + const int8x16x4_t vy0 = vld1q_s8_x4(qy0); + const int8x16x4_t vy1 = vld1q_s8_x4(qy1); + + int8x16_t vx0[4], vx1[4]; + { + const uint8x16x2_t vv = vld1q_u8_x2(qx0); + vx0[0] = vreinterpretq_s8_u8(vandq_u8(vv.val[0], m4b)); + vx0[1] = vreinterpretq_s8_u8(vandq_u8(vv.val[1], m4b)); + vx0[2] = vreinterpretq_s8_u8(vshrq_n_u8(vv.val[0], 4)); + vx0[3] = vreinterpretq_s8_u8(vshrq_n_u8(vv.val[1], 4)); + } + { + const uint8x16x2_t vv = vld1q_u8_x2(qx1); + vx1[0] = vreinterpretq_s8_u8(vandq_u8(vv.val[0], m4b)); + vx1[1] = vreinterpretq_s8_u8(vandq_u8(vv.val[1], m4b)); + vx1[2] = vreinterpretq_s8_u8(vshrq_n_u8(vv.val[0], 4)); + vx1[3] = vreinterpretq_s8_u8(vshrq_n_u8(vv.val[1], 4)); + } + + // process 32 data points (share same block scale) per iteration + for (int k = 0; k < 2; ++k) { + const int blk = j * 2 + k; + const int32x4_t block_scale = { + x0_scales[blk], + x0_scales[blk], + x1_scales[blk], + x1_scales[blk], + }; + + int32x4_t vr = {0}; + for (int l = 0; l < 2; ++l) { + const int idx = k * 2 + l; + const int64x2_t vx0_s64 = vreinterpretq_s64_s8(vx0[idx]); + const int64x2_t vx1_s64 = vreinterpretq_s64_s8(vx1[idx]); + const int64x2_t vy0_s64 = vreinterpretq_s64_s8(vy0.val[idx]); + const int64x2_t vy1_s64 = vreinterpretq_s64_s8(vy1.val[idx]); + const int8x16_t vx_l = vreinterpretq_s8_s64(vzip1q_s64(vx0_s64, vx1_s64)); + const int8x16_t vx_h = vreinterpretq_s8_s64(vzip2q_s64(vx0_s64, vx1_s64)); + const int8x16_t vy_l = vreinterpretq_s8_s64(vzip1q_s64(vy0_s64, vy1_s64)); + const int8x16_t vy_h = vreinterpretq_s8_s64(vzip2q_s64(vy0_s64, vy1_s64)); + vr = vmmlaq_s32(vr, vx_l, vy_l); + vr = vmmlaq_s32(vr, vx_h, vy_h); + } + // apply block scale, will NOT overflow + // block_scale * sum_256(int4*int8) <= 2^(8+8+4+8) = 28 bits + visum = vmlaq_s32(visum, vr, block_scale); + } + } + + // adjust bias, apply superblock scale + { + int32_t bias[4]; + // no obvious uplift from sve sdot-16, just use neon mul add + const int16x8_t y0_sums = vpaddq_s16(vld1q_s16(y0->bsums), vld1q_s16(y0->bsums+8)); + const int16x8_t y1_sums = vpaddq_s16(vld1q_s16(y1->bsums), vld1q_s16(y1->bsums+8)); + bias[0] = vaddvq_s32(vaddq_s32(vmull_s16(vget_low_s16(y0_sums), vget_low_s16(x0_mins)), + vmull_s16(vget_high_s16(y0_sums), vget_high_s16(x0_mins)))); + bias[1] = vaddvq_s32(vaddq_s32(vmull_s16(vget_low_s16(y1_sums), vget_low_s16(x0_mins)), + vmull_s16(vget_high_s16(y1_sums), vget_high_s16(x0_mins)))); + bias[2] = vaddvq_s32(vaddq_s32(vmull_s16(vget_low_s16(y0_sums), vget_low_s16(x1_mins)), + vmull_s16(vget_high_s16(y0_sums), vget_high_s16(x1_mins)))); + bias[3] = vaddvq_s32(vaddq_s32(vmull_s16(vget_low_s16(y1_sums), vget_low_s16(x1_mins)), + vmull_s16(vget_high_s16(y1_sums), vget_high_s16(x1_mins)))); + const float32x4_t dmins = { + GGML_FP16_TO_FP32(x0->dmin) * y0->d, + GGML_FP16_TO_FP32(x0->dmin) * y1->d, + GGML_FP16_TO_FP32(x1->dmin) * y0->d, + GGML_FP16_TO_FP32(x1->dmin) * y1->d, + }; + vfsum = vmlsq_f32(vfsum, vcvtq_f32_s32(vld1q_s32(bias)), dmins); + + const float32x4_t superblock_scale = { + GGML_FP16_TO_FP32(x0->d) * y0->d, + GGML_FP16_TO_FP32(x0->d) * y1->d, + GGML_FP16_TO_FP32(x1->d) * y0->d, + GGML_FP16_TO_FP32(x1->d) * y1->d, + }; + vfsum = vmlaq_f32(vfsum, vcvtq_f32_s32(visum), superblock_scale); + } + } + + // vfsum = ABCD -> ACBD + // AC -> s, BD -> (s+bs) + vfsum = vzip1q_f32(vfsum, vextq_f32(vfsum, vfsum, 2)); + vst1_f32(s, vget_low_f32 (vfsum)); + vst1_f32(s + bs, vget_high_f32(vfsum)); + + return; + } +#endif + #ifdef __ARM_FEATURE_SVE float sumf = 0; for (int i = 0; i < nb; ++i) { @@ -7180,13 +7548,129 @@ void ggml_vec_dot_q4_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m); -#elif defined __riscv_v_intrinsic +#elif defined __riscv_xtheadvector + + const uint8_t * scales = (const uint8_t*)&utmp[0]; + const uint8_t * mins = (const uint8_t*)&utmp[2]; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + int tmp, tmp2, sumi; + __asm__ __volatile__( + "li %[t1], 12\n\t" + "th.vsetvli zero, %[t1], e8, m1\n\t" + "th.vlb.v v1, (%[s6b])\n\t" // {aux[0], aux[1], aux[2]} + "li %[t1], 4\n\t" + "th.vsetvli zero, %[t1], e32, m1\n\t" + "th.vslidedown.vi v2, v1, 2\n\t" + "th.vmv.v.v v3, v2\n\t" + "th.vslideup.vi v2, v3, 1\n\t" // {aux[2], aux[2]} + "li %[t1], 2\n\t" + "th.vsetvli zero, %[t1], e32, m1\n\t" + "th.vmv.v.i v4, 4\n\t" + "th.vand.vx v8, v1, %[kmask1]\n\t" + "th.vslide1up.vx v5, v4, zero\n\t" // {0, 4} + "th.vsrl.vi v6, v1, 6\n\t" + "th.vsrl.vv v7, v2, v5\n\t" + "th.vand.vx v0, v6, %[kmask3]\n\t" + "th.vand.vx v2, v7, %[kmask2]\n\t" + "th.vsll.vi v6, v0, 4\n\t" + "li %[t2], 8\n\t" + "addi %[t1], %[utmp], 4\n\t" + "th.vor.vv v1, v6, v2\n\t" + "th.vssw.v v8, (%[utmp]), %[t2]\n\t" + "th.vssw.v v1, (%[t1]), %[t2]\n\t" + "th.vsetvli zero, zero, e32, m2\n\t" // vl == 8 + "th.vlw.v v2, (%[bsums])\n\t" + "th.vsetvli zero, %[t2], e16, m1\n\t" + "th.vnsrl.vi v0, v2, 0\n\t" + "th.vnsrl.vi v1, v2, 16\n\t" + "th.vadd.vv v2, v0, v1\n\t" + "th.vlbu.v v4, (%[mins])\n\t" + "th.vwmul.vv v6, v4, v2\n\t" + "th.vmv.v.x v0, zero\n\t" + "th.vsetvli zero, %[t2], e32, m2\n\t" + "th.vredsum.vs v0, v6, v0\n\t" + "th.vmv.x.s %[sumi], v0" + : [t1] "=&r" (tmp), [t2] "=&r" (tmp2), [sumi] "=&r" (sumi) + : [bsums] "r" (y[i].bsums), [mins] "r" (mins), [utmp] "r" (utmp) + , [s6b] "r" (x[i].scales), [kmask1] "r" (kmask1) + , [kmask2] "r" (kmask2), [kmask3] "r" (kmask3) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + sumf -= dmin * sumi; + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + sumi = 0; + const uint8_t * scale = scales; + + for (int j = 0; j < QK_K/128; ++j) { + int vl128 = 128, vl64 = 64, vl32 = 32; + __asm__ __volatile__( + "th.vsetvli zero, %[vl128], e8, m8\n\t" + "th.vlb.v v8, (%[q8])\n\t" + "th.vsetvli zero, %[vl64], e8, m4\n\t" + "th.vlb.v v0, (%[q4])\n\t" + "th.vsrl.vi v4, v0, 4\n\t" + "th.vand.vi v0, v0, 0xF\n\t" + "th.vsetvli zero, %[vl32], e8, m2\n\t" + "th.vwmul.vv v28, v6, v14\n\t" + "th.vwmul.vv v20, v4, v10\n\t" + "th.vwmul.vv v24, v2, v12\n\t" + "th.vwmul.vv v16, v0, v8\n\t" + "li %[tmp], 4\n\t" + "th.vsetvli zero, %[tmp], e32, m1\n\t" + "th.vlbu.v v1, (%[scale])\n\t" + "th.vmv.v.x v0, zero\n\t" + "th.vsetvli zero, %[vl32], e16, m4\n\t" + "th.vwredsum.vs v6, v24, v0\n\t" + "th.vwredsum.vs v7, v28, v0\n\t" + "th.vwredsum.vs v4, v16, v0\n\t" + "th.vwredsum.vs v5, v20, v0\n\t" + "th.vsetvli zero, %[tmp], e32, m1\n\t" + "th.vslideup.vi v6, v7, 1\n\t" + "th.vslideup.vi v4, v5, 1\n\t" + "th.vslideup.vi v4, v6, 2\n\t" + "th.vmul.vv v8, v4, v1\n\t" + "th.vredsum.vs v0, v8, v0\n\t" + "th.vmv.x.s %[tmp], v0\n\t" + "add %[sumi], %[sumi], %[tmp]" + : [tmp] "=&r" (tmp), [sumi] "+&r" (sumi) + : [vl128] "r" (vl128), [vl64] "r" (vl64), [vl32] "r" (vl32) + , [q4] "r" (q4), [q8] "r" (q8), [scale] "r" (scale) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + + q4 += 64; q8 += 128; scale += 4; + } + + sumf += d * sumi; + + } + + *s = sumf; + +#elif defined __riscv_v const uint8_t * scales = (const uint8_t*)&utmp[0]; const uint8_t * mins = (const uint8_t*)&utmp[2]; - const int vector_length = __riscv_vlenb() * 8; float sumf = 0; + const int vector_length = __riscv_vlenb() * 8; switch (vector_length) { case 256: @@ -8074,7 +8558,7 @@ void ggml_vec_dot_q5_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi *s = sumf; -#elif defined __riscv_v_intrinsic +#elif defined __riscv_v const uint8_t * scales = (const uint8_t*)&utmp[0]; const uint8_t * mins = (const uint8_t*)&utmp[2]; @@ -9232,10 +9716,91 @@ void ggml_vec_dot_q6_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const voi } *s = sumf; -#elif defined __riscv_v_intrinsic +#elif defined __riscv_xtheadvector + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + + const uint8_t * restrict q6 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const int8_t * restrict scale = x[i].scales; + + int sum_t = 0; + int t0; + + for (int j = 0; j < QK_K/128; ++j) { + __asm__ __volatile__( + "th.vsetvli zero, %[vl32], e8, m2\n\t" // vl == 32 + "th.vlb.v v4, (%[qh])\n\t" + "th.vsll.vi v0, v4, 4\n\t" + "th.vsll.vi v2, v4, 2\n\t" + "th.vsrl.vi v6, v4, 2\n\t" + "th.vsetvli zero, %[vl64], e8, m4\n\t" // vl == 64 + "th.vlb.v v8, (%[q6])\n\t" + "th.vsrl.vi v12, v8, 4\n\t" + "th.vand.vi v8, v8, 0xF\n\t" + "th.vsetvli zero, %[vl128], e8, m8\n\t" // vl == 128 + "th.vand.vx v0, v0, %[mask]\n\t" + "th.vor.vv v8, v8, v0\n\t" + "th.vlb.v v0, (%[q8])\n\t" + "th.vsub.vx v8, v8, %[vl32]\n\t" + "th.vsetvli zero, %[vl64], e8, m4\n\t" // vl == 64 + "th.vwmul.vv v16, v0, v8\n\t" + "th.vwmul.vv v24, v4, v12\n\t" + "li %[t0], 16\n\t" + "th.vsetvli zero, %[t0], e16, m2\n\t" // vl == 16 + "th.vmv.v.x v0, zero\n\t" + "th.vwredsum.vs v10, v16, v0\n\t" + "th.vwredsum.vs v9, v18, v0\n\t" + "th.vwredsum.vs v8, v20, v0\n\t" + "th.vwredsum.vs v7, v22, v0\n\t" + "th.vwredsum.vs v11, v24, v0\n\t" + "th.vwredsum.vs v12, v26, v0\n\t" + "th.vwredsum.vs v13, v28, v0\n\t" + "th.vwredsum.vs v14, v30, v0\n\t" + "li %[t0], 4\n\t" + "th.vsetvli zero, %[t0], e32, m1\n\t" // vl == 4 + "th.vslideup.vi v10, v9, 1\n\t" + "th.vslideup.vi v8, v7, 1\n\t" + "th.vslideup.vi v11, v12, 1\n\t" + "th.vslideup.vi v13, v14, 1\n\t" + "th.vslideup.vi v10, v8, 2\n\t" + "th.vslideup.vi v11, v13, 2\n\t" + "li %[t0], 8\n\t" + "th.vsetvli zero, %[t0], e32, m2\n\t" // vl == 8 + "th.vlb.v v4, (%[scale])\n\t" + "th.vmul.vv v2, v4, v10\n\t" + "th.vredsum.vs v0, v2, v0\n\t" + "th.vmv.x.s %[t0], v0\n\t" + "add %[sumi], %[sumi], %[t0]" + : [sumi] "+&r" (sum_t), [t0] "=&r" (t0) + : [qh] "r" (qh), [q6] "r" (q6), [q8] "r" (q8), [scale] "r" (scale) + , [vl32] "r" (32), [vl64] "r" (64), [vl128] "r" (128) + , [mask] "r" (0x30) + : "memory" + , "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" + , "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" + , "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" + , "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + ); + q6 += 64; qh += 32; q8 += 128; scale += 8; + } + + sumf += d * sum_t; + + } + + *s = sumf; + +#elif defined __riscv_v - const int vector_length = __riscv_vlenb() * 8; float sumf = 0; + const int vector_length = __riscv_vlenb() * 8; switch (vector_length) { case 256: diff --git a/ggml/src/ggml-cpu/ggml-cpu.c b/ggml/src/ggml-cpu/ggml-cpu.c index 133b50606bcd1..c7426df2b851b 100644 --- a/ggml/src/ggml-cpu/ggml-cpu.c +++ b/ggml/src/ggml-cpu/ggml-cpu.c @@ -270,7 +270,11 @@ static const struct ggml_type_traits_cpu type_traits_cpu[GGML_TYPE_COUNT] = { .from_float = quantize_row_q4_K, .vec_dot = ggml_vec_dot_q4_K_q8_K, .vec_dot_type = GGML_TYPE_Q8_K, +#if defined (__ARM_FEATURE_MATMUL_INT8) + .nrows = 2, +#else .nrows = 1, +#endif }, [GGML_TYPE_Q5_K] = { .from_float = quantize_row_q5_K, @@ -2202,6 +2206,7 @@ static int ggml_get_n_tasks(struct ggml_tensor * node, int n_threads) { } break; case GGML_UNARY_OP_GELU: + case GGML_UNARY_OP_GELU_ERF: case GGML_UNARY_OP_GELU_QUICK: case GGML_UNARY_OP_SILU: { @@ -2413,12 +2418,32 @@ static bool ggml_thread_apply_priority(int32_t prio) { // This is up to the applications. DWORD p = THREAD_PRIORITY_NORMAL; switch (prio) { + case GGML_SCHED_PRIO_LOW: p = THREAD_PRIORITY_BELOW_NORMAL; break; case GGML_SCHED_PRIO_NORMAL: p = THREAD_PRIORITY_NORMAL; break; case GGML_SCHED_PRIO_MEDIUM: p = THREAD_PRIORITY_ABOVE_NORMAL; break; case GGML_SCHED_PRIO_HIGH: p = THREAD_PRIORITY_HIGHEST; break; case GGML_SCHED_PRIO_REALTIME: p = THREAD_PRIORITY_TIME_CRITICAL; break; } + if (prio != GGML_SCHED_PRIO_LOW) { + // Tell Windows that this thread should not be throttled (needs its own CPU core). + // Newer Windows 11 versions aggresively park (offline) CPU cores and often place + // all our threads onto the first 4 cores which results in terrible performance with + // n_threads > 4 + #if _WIN32_WINNT >= 0x0602 + THREAD_POWER_THROTTLING_STATE t; + ZeroMemory(&t, sizeof(t)); + t.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION; + t.ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED; + t.StateMask = 0; + + if (!SetThreadInformation(GetCurrentThread(), ThreadPowerThrottling, &t, sizeof(t))) { + GGML_LOG_DEBUG("failed to disable thread power throttling %d : (%d)\n", prio, (int) GetLastError()); + return false; + } + #endif + } + if (prio == GGML_SCHED_PRIO_NORMAL) { // Keep inherited policy/priority return true; @@ -2446,6 +2471,8 @@ static bool ggml_thread_apply_priority(int32_t prio) { struct sched_param p; int32_t policy = SCHED_OTHER; switch (prio) { + // TODO: there seems to be no way to set lower prio on Apple platforms + case GGML_SCHED_PRIO_LOW: policy = SCHED_OTHER; p.sched_priority = 0; break; case GGML_SCHED_PRIO_NORMAL: policy = SCHED_OTHER; p.sched_priority = 0; break; case GGML_SCHED_PRIO_MEDIUM: policy = SCHED_FIFO; p.sched_priority = 40; break; case GGML_SCHED_PRIO_HIGH: policy = SCHED_FIFO; p.sched_priority = 80; break; @@ -2502,6 +2529,7 @@ static bool ggml_thread_apply_priority(int32_t prio) { struct sched_param p; int32_t policy = SCHED_OTHER; switch (prio) { + case GGML_SCHED_PRIO_LOW: policy = SCHED_BATCH; p.sched_priority = 0; break; case GGML_SCHED_PRIO_NORMAL: policy = SCHED_OTHER; p.sched_priority = 0; break; case GGML_SCHED_PRIO_MEDIUM: policy = SCHED_FIFO; p.sched_priority = 40; break; case GGML_SCHED_PRIO_HIGH: policy = SCHED_FIFO; p.sched_priority = 80; break; @@ -3483,6 +3511,19 @@ void ggml_cpu_init(void) { const uint64_t t_end = ggml_time_us(); UNUSED(t_end); GGML_PRINT_DEBUG("%s: GELU, Quick GELU, SILU and EXP tables initialized in %f ms\n", __func__, (t_end - t_start)/1000.0); + +#ifdef GGML_USE_OPENMP + //if (!getenv("OMP_WAIT_POLICY")) { + // // set the wait policy to active, so that OpenMP threads don't sleep + // putenv("OMP_WAIT_POLICY=active"); + //} + + if (!getenv("KMP_BLOCKTIME")) { + // set the time to wait before sleeping a thread + // this is less aggressive than setting the wait policy to active, but should achieve similar results in most cases + putenv("KMP_BLOCKTIME=200"); // 200ms + } +#endif } #if defined(__ARM_ARCH) diff --git a/ggml/src/ggml-cpu/ops.cpp b/ggml/src/ggml-cpu/ops.cpp index 955fec59a6e93..d8de7531b0e5f 100644 --- a/ggml/src/ggml-cpu/ops.cpp +++ b/ggml/src/ggml-cpu/ops.cpp @@ -2691,6 +2691,109 @@ static void ggml_compute_forward_gelu( } } +// ggml_compute_forward_gelu_erf + +static void ggml_compute_forward_gelu_erf_f32( + const ggml_compute_params * params, + ggml_tensor * dst) { + + const ggml_tensor * src0 = dst->src[0]; + + assert(ggml_is_contiguous_1(src0)); + assert(ggml_is_contiguous_1(dst)); + assert(ggml_are_same_shape(src0, dst)); + + const int ith = params->ith; + const int nth = params->nth; + + const int nc = src0->ne[0]; + const int nr = ggml_nrows(src0); + + // rows per thread + const int dr = (nr + nth - 1)/nth; + + // row range for this thread + const int ir0 = dr*ith; + const int ir1 = MIN(ir0 + dr, nr); + + for (int i1 = ir0; i1 < ir1; i1++) { + ggml_vec_gelu_erf_f32(nc, + (float *) ((char *) dst->data + i1*( dst->nb[1])), + (float *) ((char *) src0->data + i1*(src0->nb[1]))); + +#ifndef NDEBUG + for (int k = 0; k < nc; k++) { + const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k]; + GGML_UNUSED(x); + assert(!isnan(x)); + assert(!isinf(x)); + } +#endif + } +} + +static void ggml_compute_forward_gelu_erf_f16( + const ggml_compute_params * params, + ggml_tensor * dst) { + + const ggml_tensor * src0 = dst->src[0]; + + assert(ggml_is_contiguous_1(src0)); + assert(ggml_is_contiguous_1(dst)); + assert(ggml_are_same_shape(src0, dst)); + + const int ith = params->ith; + const int nth = params->nth; + + const int nc = src0->ne[0]; + const int nr = ggml_nrows(src0); + + // rows per thread + const int dr = (nr + nth - 1)/nth; + + // row range for this thread + const int ir0 = dr*ith; + const int ir1 = MIN(ir0 + dr, nr); + + for (int i1 = ir0; i1 < ir1; i1++) { + ggml_vec_gelu_erf_f16(nc, + (ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])), + (ggml_fp16_t *) ((char *) src0->data + i1*(src0->nb[1]))); + +#ifndef NDEBUG + for (int k = 0; k < nc; k++) { + const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k]; + const float v = GGML_FP16_TO_FP32(x); + GGML_UNUSED(v); + assert(!isnan(v)); + assert(!isinf(v)); + } +#endif + } +} + +static void ggml_compute_forward_gelu_erf( + const ggml_compute_params * params, + ggml_tensor * dst) { + + const ggml_tensor * src0 = dst->src[0]; + + switch (src0->type) { + case GGML_TYPE_F32: + { + ggml_compute_forward_gelu_erf_f32(params, dst); + } break; + case GGML_TYPE_F16: + { + ggml_compute_forward_gelu_erf_f16(params, dst); + } break; + default: + { + GGML_ABORT("fatal error"); + } + } +} + // ggml_compute_forward_gelu_quick static void ggml_compute_forward_gelu_quick_f32( @@ -7530,39 +7633,83 @@ static void ggml_compute_forward_ssm_scan_f32( const int ir1 = MIN(ir0 + dr, nr); const int ir = ir1 - ir0; - for (int i3 = 0; i3 < n_s; ++i3) { - for (int i2 = 0; i2 < n_t; ++i2) { - const float * s0 = (const float *) ((const char *) src0->data + ir0*(src0->nb[1]) + i3*(src0->nb[2])); // {d_state, d_inner, n_s} - const float * x = (const float *) ((const char *) src1->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} - const float * dt = (const float *) ((const char *) src2->data + ir0*(src2->nb[0]) + i2*(src2->nb[1]) + i3*(src2->nb[2])); // {d_inner, n_t, n_s} - const float * A = (const float *) ((const char *) src3->data + ir0*(src3->nb[1])); // {d_state, d_inner} - const float * B = (const float *) ((const char *) src4->data + i2*(src4->nb[1]) + i3*(src4->nb[2])); // {d_state, n_t, n_s} - const float * C = (const float *) ((const char *) src5->data + i2*(src5->nb[1]) + i3*(src5->nb[2])); // {d_state, n_t, n_s} - float * y = ( float *) (( char *) dst->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} - float * s = ( float *) (( char *) dst->data + ir0*(src0->nb[1]) + i3*(src0->nb[2]) + src1->nb[3]); // {d_state, d_inner, n_s} - - // use the output as the source for the next token-wise iterations - if (i2 > 0) { s0 = s; } - - // d_inner - for (int i1 = 0; i1 < ir; ++i1) { - // ref: https://github.com/state-spaces/mamba/blob/34076d664838588a3c97727b263478ab9f621a07/mamba_ssm/ops/triton/selective_state_update.py#L78 - float dt_soft_plus = dt[i1] <= 20.0f ? log1pf(expf(dt[i1])) : dt[i1]; - float x_dt = x[i1] * dt_soft_plus; - float sumf = 0.0f; - // d_state - for (int i0 = 0; i0 < nc; ++i0) { - int i = i0 + i1*nc; - // state = prev_state * dA + dB * x - float state = (s0[i] * expf(dt_soft_plus * A[i])) + (B[i0] * x_dt); - // y = rowwise_dotprod(state, C) - sumf += state * C[i0]; - s[i] = state; + #ifdef __ARM_FEATURE_SVE + for (int i3 = 0; i3 < n_s; ++i3) { + for (int i2 = 0; i2 < n_t; ++i2) { + const float * s0 = (const float *) ((const char *) src0->data + ir0*(src0->nb[1]) + i3*(src0->nb[2])); // {d_state, d_inner, n_s} + const float * x = (const float *) ((const char *) src1->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} + const float * dt = (const float *) ((const char *) src2->data + ir0*(src2->nb[0]) + i2*(src2->nb[1]) + i3*(src2->nb[2])); // {d_inner, n_t, n_s} + const float * A = (const float *) ((const char *) src3->data + ir0*(src3->nb[1])); // {d_state, d_inner} + const float * B = (const float *) ((const char *) src4->data + i2*(src4->nb[1]) + i3*(src4->nb[2])); // {d_state, n_t, n_s} + const float * C = (const float *) ((const char *) src5->data + i2*(src5->nb[1]) + i3*(src5->nb[2])); // {d_state, n_t, n_s} + float * y = ( float *) (( char *) dst->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} + float * s = ( float *) (( char *) dst->data + ir0*(src0->nb[1]) + i3*(src0->nb[2]) + src1->nb[3]); // {d_state, d_inner, n_s} + + // use the output as the source for the next token-wise iterations + if (i2 > 0) { s0 = s; } + + // d_inner + for (int i1 = 0; i1 < ir; ++i1) { + float dt_soft_plus = dt[i1] <= 20.0f ? log1pf(expf(dt[i1])) : dt[i1]; + float x_dt = x[i1] * dt_soft_plus; + svfloat32_t vx_dt = GGML_F32_VEC_SET1(x_dt); + svfloat32_t vdt_soft_plus = GGML_F32_VEC_SET1(dt_soft_plus); + svfloat32_t r1_vector = GGML_F32_VEC_ZERO; + + for (int64_t k = 0; k < nc; k += svcntw()) { + svfloat32_t vA = GGML_F32_VEC_LOAD(&A[i1*nc + k]); + svfloat32_t vB = GGML_F32_VEC_LOAD(&B[k]); + svfloat32_t vC = GGML_F32_VEC_LOAD(&C[k]); + svfloat32_t vs0 = GGML_F32_VEC_LOAD(&s0[i1*nc + k]); + + svfloat32_t t1 = GGML_F32_VEC_MUL(vdt_soft_plus, vA); + t1 = exp_ps_sve(svptrue_b32(), t1); + svfloat32_t t2 = GGML_F32_VEC_MUL(vx_dt, vB); + + vs0 = GGML_F32_VEC_FMA(vs0, t1, t2); + r1_vector = GGML_F32_VEC_ADD(GGML_F32_VEC_MUL(vs0, vC), r1_vector); + + GGML_F32_VEC_STORE(&s[i1*nc + k], vs0); + } + y[i1] = GGML_F32xt_REDUCE_ONE(r1_vector); } - y[i1] = sumf; } } - } + #else + for (int i3 = 0; i3 < n_s; ++i3) { + for (int i2 = 0; i2 < n_t; ++i2) { + const float * s0 = (const float *) ((const char *) src0->data + ir0*(src0->nb[1]) + i3*(src0->nb[2])); // {d_state, d_inner, n_s} + const float * x = (const float *) ((const char *) src1->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} + const float * dt = (const float *) ((const char *) src2->data + ir0*(src2->nb[0]) + i2*(src2->nb[1]) + i3*(src2->nb[2])); // {d_inner, n_t, n_s} + const float * A = (const float *) ((const char *) src3->data + ir0*(src3->nb[1])); // {d_state, d_inner} + const float * B = (const float *) ((const char *) src4->data + i2*(src4->nb[1]) + i3*(src4->nb[2])); // {d_state, n_t, n_s} + const float * C = (const float *) ((const char *) src5->data + i2*(src5->nb[1]) + i3*(src5->nb[2])); // {d_state, n_t, n_s} + float * y = ( float *) (( char *) dst->data + ir0*(src1->nb[0]) + i2*(src1->nb[1]) + i3*(src1->nb[2])); // {d_inner, n_t, n_s} + float * s = ( float *) (( char *) dst->data + ir0*(src0->nb[1]) + i3*(src0->nb[2]) + src1->nb[3]); // {d_state, d_inner, n_s} + + // use the output as the source for the next token-wise iterations + if (i2 > 0) { s0 = s; } + + // d_inner + for (int i1 = 0; i1 < ir; ++i1) { + // ref: https://github.com/state-spaces/mamba/blob/34076d664838588a3c97727b263478ab9f621a07/mamba_ssm/ops/triton/selective_state_update.py#L78 + float dt_soft_plus = dt[i1] <= 20.0f ? log1pf(expf(dt[i1])) : dt[i1]; + float x_dt = x[i1] * dt_soft_plus; + float sumf = 0.0f; + // d_state + for (int i0 = 0; i0 < nc; ++i0) { + int i = i0 + i1*nc; + // state = prev_state * dA + dB * x + float state = (s0[i] * expf(dt_soft_plus * A[i])) + (B[i0] * x_dt); + // y = rowwise_dotprod(state, C) + sumf += state * C[i0]; + s[i] = state; + } + y[i1] = sumf; + } + } + } + #endif } void ggml_compute_forward_ssm_scan( @@ -7749,6 +7896,10 @@ void ggml_compute_forward_unary( { ggml_compute_forward_gelu(params, dst); } break; + case GGML_UNARY_OP_GELU_ERF: + { + ggml_compute_forward_gelu_erf(params, dst); + } break; case GGML_UNARY_OP_GELU_QUICK: { ggml_compute_forward_gelu_quick(params, dst); @@ -7963,6 +8114,14 @@ static void ggml_compute_forward_rwkv_wkv6_f32( #define GGML_F32X_MUL GGML_F32x16_MUL #define GGML_F32X_FMA GGML_F32x16_FMA #define WKV_VECTOR_SIZE 16 + #elif defined(__ARM_FEATURE_SVE) && defined(__aarch64__) + #define GGML_F32X GGML_F32xt + #define GGML_F32X_SET1 GGML_F32xt_SET1 + #define GGML_F32X_LOAD GGML_F32xt_LOAD + #define GGML_F32X_STORE GGML_F32xt_STORE + #define GGML_F32X_MUL GGML_F32xt_MUL + #define GGML_F32X_FMA GGML_F32xt_FMA + #define WKV_VECTOR_SIZE 8 #elif defined(__ARM_NEON) && defined(__aarch64__) #define GGML_F32X GGML_F32x4 #define GGML_F32X_SET1 GGML_F32x4_SET1 @@ -7973,8 +8132,14 @@ static void ggml_compute_forward_rwkv_wkv6_f32( #define WKV_VECTOR_SIZE 4 #endif + int wkv_vector_size; #ifdef WKV_VECTOR_SIZE - const int64_t vec_count = head_size / WKV_VECTOR_SIZE; + #if defined(__ARM_FEATURE_SVE) + wkv_vector_size = svcntw(); + #else + wkv_vector_size = WKV_VECTOR_SIZE; + #endif + const int64_t vec_count = head_size / wkv_vector_size; for (int64_t t = 0; t < T; t++) { size_t t_offset = t * t_stride; @@ -8004,7 +8169,7 @@ static void ggml_compute_forward_rwkv_wkv6_f32( GGML_F32X time_decay_vec = GGML_F32X_SET1(time_decay_val); for (int64_t j = 0; j < vec_count; j++) { - size_t base_j = j * WKV_VECTOR_SIZE; + size_t base_j = j * wkv_vector_size; size_t t_h_j_offset = t_h_offset + base_j; size_t h_2d_i_j_offset = h_2d_i_offset + base_j; @@ -8029,7 +8194,7 @@ static void ggml_compute_forward_rwkv_wkv6_f32( } // Handle remaining elements, this will not be used. - for (int64_t j = vec_count * WKV_VECTOR_SIZE; j < head_size; j++) { + for (int64_t j = vec_count * wkv_vector_size; j < head_size; j++) { size_t t_h_j_offset = t_h_offset + j; size_t h_2d_i_j_offset = h_2d_i_offset + j; float v_val = v[t_h_j_offset]; @@ -8165,6 +8330,14 @@ static void ggml_compute_forward_gla_f32( #define GGML_F32X_MUL GGML_F32x16_MUL #define GGML_F32X_FMA GGML_F32x16_FMA #define GLA_VECTOR_SIZE 16 + #elif defined(__ARM_FEATURE_SVE) && defined(__aarch64__) + #define GGML_F32X GGML_F32xt + #define GGML_F32X_SET1 GGML_F32xt_SET1 + #define GGML_F32X_LOAD GGML_F32xt_LOAD + #define GGML_F32X_STORE GGML_F32xt_STORE + #define GGML_F32X_MUL GGML_F32xt_MUL + #define GGML_F32X_FMA GGML_F32xt_FMA + #define GLA_VECTOR_SIZE 8 #elif defined(__ARM_NEON) && defined(__aarch64__) #define GGML_F32X GGML_F32x4 #define GGML_F32X_SET1 GGML_F32x4_SET1 @@ -8175,8 +8348,14 @@ static void ggml_compute_forward_gla_f32( #define GLA_VECTOR_SIZE 4 #endif + int gla_vector_size; #ifdef GLA_VECTOR_SIZE - const int64_t vec_count = head_size / GLA_VECTOR_SIZE; + #if defined(__ARM_FEATURE_SVE) + gla_vector_size = svcntw(); + #else + gla_vector_size = GLA_VECTOR_SIZE; + #endif + const int64_t vec_count = head_size / gla_vector_size; for (int64_t t = 0; t < T; t++) { size_t t_offset = t * t_stride; @@ -8203,7 +8382,7 @@ static void ggml_compute_forward_gla_f32( GGML_F32X g_vec = GGML_F32X_SET1(g_val); for (int64_t j = 0; j < vec_count; j++) { - size_t base_j = j * GLA_VECTOR_SIZE; + size_t base_j = j * gla_vector_size; size_t t_h_j_offset = t_h_offset + base_j; size_t h_2d_i_j_offset = h_2d_i_offset + base_j; @@ -8227,7 +8406,7 @@ static void ggml_compute_forward_gla_f32( } // Handle remaining elements, this will not be used. - for (int64_t j = vec_count * GLA_VECTOR_SIZE; j < head_size; j++) { + for (int64_t j = vec_count * gla_vector_size; j < head_size; j++) { size_t t_h_j_offset = t_h_offset + j; size_t h_2d_i_j_offset = h_2d_i_offset + j; float v_val = v[t_h_j_offset]; @@ -8336,83 +8515,126 @@ static void ggml_compute_forward_rwkv_wkv7_f32( int64_t h_stride_2d = head_size * head_size; #if defined(GGML_SIMD) - for (int64_t t = 0; t < T; t++) { - int64_t t_offset = t * t_stride; - int64_t state_offset = head_size * C * (t / (T / n_seqs)); - float * state_cur = state + state_offset; - float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset; - - for (int64_t h = h_start; h < h_end; h++) { - int64_t h_offset = h * h_stride; - int64_t t_h_offset = t_offset + h_offset; - int64_t h_2d_offset = h * h_stride_2d; - - for (int64_t ii = 0; ii < head_size; ii++) { - int64_t t_h_i_offset = t_h_offset + ii; - int64_t h_2d_i_offset = h_2d_offset + ii * h_stride; - - GGML_F32_VEC v_vec = GGML_F32_VEC_SET1(v[t_h_i_offset]); + #if defined(__ARM_FEATURE_SVE) + // scalar Route to scalar implementation //TODO: Write SVE code + for (int64_t t = 0; t < T; t++) { + int64_t t_offset = t * t_stride; + int64_t state_offset = head_size * C * (t / (T / n_seqs)); + float * state_cur = state + state_offset; + float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset; + + for (int64_t h = h_start; h < h_end; h++) { + int64_t h_offset = h * h_stride; + int64_t t_h_offset = t_offset + h_offset; + int64_t h_2d_offset = h * h_stride_2d; + + for (int64_t i = 0; i < head_size; i++) { + int64_t t_h_i_offset = t_h_offset + i; + int64_t h_2d_i_offset = h_2d_offset + i * h_stride; + + float v_val = v[t_h_i_offset]; + + float sa = 0, result = 0; + for (int64_t j = 0; j < head_size; j++) { + sa += a[t_h_offset + j] * state_prev[h_2d_i_offset + j]; + } - float sa = 0; - { - GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; - GGML_F32_VEC ax[GGML_F32_ARR]; - GGML_F32_VEC ay[GGML_F32_ARR]; - for (int64_t j = 0; j < head_size; j += GGML_F32_STEP) { - for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) { - ax[kk] = GGML_F32_VEC_LOAD(&a[t_h_offset + j + kk * GGML_F32_EPR]); - ay[kk] = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_offset + j + kk * GGML_F32_EPR]); - sum[kk] = GGML_F32_VEC_FMA(sum[kk], ax[kk], ay[kk]); - } + for (int64_t j = 0; j < head_size; j++) { + int64_t t_h_j_offset = t_h_offset + j; + int64_t h_2d_i_j_offset = h_2d_i_offset + j; + + float r_val = r[t_h_j_offset]; + float w_val = w[t_h_j_offset]; + float k_val = k[t_h_j_offset]; + float b_val = b[t_h_j_offset]; + float kv_val = v_val * k_val; + float prev_state_val = state_prev[h_2d_i_j_offset]; + state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val; + result += state_cur[h_2d_i_j_offset] * r_val; } - GGML_F32_VEC_REDUCE(sa, sum); + dst_data[t_h_i_offset] = result; } + } + } + #else + for (int64_t t = 0; t < T; t++) { + int64_t t_offset = t * t_stride; + int64_t state_offset = head_size * C * (t / (T / n_seqs)); + float * state_cur = state + state_offset; + float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset; + + for (int64_t h = h_start; h < h_end; h++) { + int64_t h_offset = h * h_stride; + int64_t t_h_offset = t_offset + h_offset; + int64_t h_2d_offset = h * h_stride_2d; + + for (int64_t ii = 0; ii < head_size; ii++) { + int64_t t_h_i_offset = t_h_offset + ii; + int64_t h_2d_i_offset = h_2d_offset + ii * h_stride; + + GGML_F32_VEC v_vec = GGML_F32_VEC_SET1(v[t_h_i_offset]); + + float sa = 0; + { + GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; + GGML_F32_VEC ax[GGML_F32_ARR]; + GGML_F32_VEC ay[GGML_F32_ARR]; + for (int64_t j = 0; j < head_size; j += GGML_F32_STEP) { + for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) { + ax[kk] = GGML_F32_VEC_LOAD(&a[t_h_offset + j + kk * GGML_F32_EPR]); + ay[kk] = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_offset + j + kk * GGML_F32_EPR]); + sum[kk] = GGML_F32_VEC_FMA(sum[kk], ax[kk], ay[kk]); + } + } + GGML_F32_VEC_REDUCE(sa, sum); + } - GGML_F32_VEC sa_vec = GGML_F32_VEC_SET1(sa); + GGML_F32_VEC sa_vec = GGML_F32_VEC_SET1(sa); - int64_t j = 0; - GGML_F32_VEC result_vec[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; - for (; j < head_size; j += GGML_F32_STEP) { - for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) { - int64_t t_h_j_offset = t_h_offset + j + kk * GGML_F32_EPR; - int64_t h_2d_i_j_offset = h_2d_i_offset + j + kk * GGML_F32_EPR; + int64_t j = 0; + GGML_F32_VEC result_vec[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; + for (; j < head_size; j += GGML_F32_STEP) { + for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) { + int64_t t_h_j_offset = t_h_offset + j + kk * GGML_F32_EPR; + int64_t h_2d_i_j_offset = h_2d_i_offset + j + kk * GGML_F32_EPR; - GGML_F32_VEC r_vec = GGML_F32_VEC_LOAD(&r[t_h_j_offset]); - GGML_F32_VEC w_vec = GGML_F32_VEC_LOAD(&w[t_h_j_offset]); - GGML_F32_VEC k_vec = GGML_F32_VEC_LOAD(&k[t_h_j_offset]); - GGML_F32_VEC b_vec = GGML_F32_VEC_LOAD(&b[t_h_j_offset]); + GGML_F32_VEC r_vec = GGML_F32_VEC_LOAD(&r[t_h_j_offset]); + GGML_F32_VEC w_vec = GGML_F32_VEC_LOAD(&w[t_h_j_offset]); + GGML_F32_VEC k_vec = GGML_F32_VEC_LOAD(&k[t_h_j_offset]); + GGML_F32_VEC b_vec = GGML_F32_VEC_LOAD(&b[t_h_j_offset]); - k_vec = GGML_F32_VEC_MUL(v_vec, k_vec); + k_vec = GGML_F32_VEC_MUL(v_vec, k_vec); - GGML_F32_VEC state_vec = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_j_offset]); - // kv + s * decay + sa * b - state_vec = GGML_F32_VEC_FMA(k_vec, state_vec, w_vec); - state_vec = GGML_F32_VEC_FMA(state_vec, sa_vec, b_vec); - GGML_F32_VEC_STORE(&state_cur[h_2d_i_j_offset], state_vec); + GGML_F32_VEC state_vec = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_j_offset]); + // kv + s * decay + sa * b + state_vec = GGML_F32_VEC_FMA(k_vec, state_vec, w_vec); + state_vec = GGML_F32_VEC_FMA(state_vec, sa_vec, b_vec); + GGML_F32_VEC_STORE(&state_cur[h_2d_i_j_offset], state_vec); - result_vec[kk] = GGML_F32_VEC_FMA(result_vec[kk], state_vec, r_vec); + result_vec[kk] = GGML_F32_VEC_FMA(result_vec[kk], state_vec, r_vec); + } + } + GGML_F32_VEC_REDUCE(dst_data[t_h_i_offset], result_vec); + + // There shouldn't be left-overs though. + for (; j < head_size; j++) { + int64_t t_h_j_offset = t_h_offset + j; + int64_t h_2d_i_j_offset = h_2d_i_offset + j; + + float r_val = r[t_h_j_offset]; + float w_val = w[t_h_j_offset]; + float k_val = k[t_h_j_offset]; + float b_val = b[t_h_j_offset]; + float kv_val = v[t_h_i_offset] * k_val; + + float prev_state_val = state_prev[h_2d_i_j_offset]; + state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val; + dst_data[t_h_i_offset] += state_cur[h_2d_i_j_offset] * r_val; } - } - GGML_F32_VEC_REDUCE(dst_data[t_h_i_offset], result_vec); - - // There shouldn't be left-overs though. - for (; j < head_size; j++) { - int64_t t_h_j_offset = t_h_offset + j; - int64_t h_2d_i_j_offset = h_2d_i_offset + j; - - float r_val = r[t_h_j_offset]; - float w_val = w[t_h_j_offset]; - float k_val = k[t_h_j_offset]; - float b_val = b[t_h_j_offset]; - float kv_val = v[t_h_i_offset] * k_val; - - float prev_state_val = state_prev[h_2d_i_j_offset]; - state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val; - dst_data[t_h_i_offset] += state_cur[h_2d_i_j_offset] * r_val; } } } - } + #endif #else for (int64_t t = 0; t < T; t++) { int64_t t_offset = t * t_stride; diff --git a/ggml/src/ggml-cpu/simd-mappings.h b/ggml/src/ggml-cpu/simd-mappings.h index 45c31cf1faffe..2e3669c0186c9 100644 --- a/ggml/src/ggml-cpu/simd-mappings.h +++ b/ggml/src/ggml-cpu/simd-mappings.h @@ -17,7 +17,123 @@ // number of elements to fit in a single register // -#if defined(__ARM_NEON) && defined(__ARM_FEATURE_FMA) +#if defined(__ARM_FEATURE_SVE) && defined(__ARM_FEATURE_FMA) + +#define GGML_SIMD + +// F32 SVE +#define GGML_F32_EPR 8 +#define DEFAULT_PG svptrue_b32() + +#define GGML_F32xt svfloat32_t +#define GGML_F32xt_ZERO svdup_n_f32(0.0f) +#define GGML_F32xt_SET1(x) svdup_n_f32(x) +#define GGML_F32xt_LOAD_IMPL(pg, a, ...) svld1_f32(pg, a) +#define GGML_F32xt_LOAD(...) GGML_F32xt_LOAD_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_STORE_IMPL(pg,a,b) svst1_f32(pg, a, b) +#define GGML_F32xt_STORE(...) GGML_F32xt_STORE_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_FMA_IMPL(pg, a, b, c) svmad_f32_m(pg, a, b, c) +#define GGML_F32xt_FMA(...) GGML_F32xt_FMA_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_ADD_IMPL(pg, a, b) svadd_f32_m(pg, a, b) +#define GGML_F32xt_ADD(...) GGML_F32xt_ADD_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_MUL_IMPL(pg, a, b) svmul_f32_m(pg, a, b) +#define GGML_F32xt_MUL(...) GGML_F32xt_MUL_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_REDUCE_ONE_IMPL(pg, a) svaddv(pg, a) +#define GGML_F32xt_REDUCE_ONE(...) GGML_F32xt_REDUCE_ONE_IMPL(DEFAULT_PG, __VA_ARGS__) +#define GGML_F32xt_REDUCE_IMPL(pg, res, sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8) \ +{ \ + sum1 = svadd_f32_m(DEFAULT_PG, sum1, sum2); \ + sum3 = svadd_f32_m(DEFAULT_PG, sum3, sum4); \ + sum5 = svadd_f32_m(DEFAULT_PG, sum5, sum6); \ + sum7 = svadd_f32_m(DEFAULT_PG, sum7, sum8); \ + sum1 = svadd_f32_m(DEFAULT_PG, sum1, sum3); \ + sum5 = svadd_f32_m(DEFAULT_PG, sum5, sum7); \ + sum1 = svadd_f32_m(DEFAULT_PG, sum1, sum5); \ + (res) = (ggml_float) GGML_F32xt_REDUCE_ONE(sum1); \ +} +#define GGML_F32xt_REDUCE(...) GGML_F32xt_REDUCE_IMPL(DEFAULT_PG, __VA_ARGS__) + +#define GGML_F32_VEC GGML_F32xt +#define GGML_F32_VEC_ZERO GGML_F32xt_ZERO +#define GGML_F32_VEC_SET1 GGML_F32xt_SET1 +#define GGML_F32_VEC_LOAD GGML_F32xt_LOAD +#define GGML_F32_VEC_STORE GGML_F32xt_STORE +#define GGML_F32_VEC_FMA GGML_F32xt_FMA +#define GGML_F32_VEC_ADD GGML_F32xt_ADD +#define GGML_F32_VEC_MUL GGML_F32xt_MUL +#define GGML_F32_VEC_REDUCE GGML_F32xt_REDUCE + +// F16 NEON + +#if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) + #define GGML_F16_STEP 32 + #define GGML_F16_EPR 8 + + #define GGML_F16x8 float16x8_t + #define GGML_F16x8_ZERO vdupq_n_f16(0.0f) + #define GGML_F16x8_SET1(x) vdupq_n_f16(x) + #define GGML_F16x8_LOAD(x) vld1q_f16((const __fp16 *)(x)) + #define GGML_F16x8_STORE vst1q_f16 + #define GGML_F16x8_FMA(a, b, c) vfmaq_f16(a, b, c) + #define GGML_F16x8_ADD vaddq_f16 + #define GGML_F16x8_MUL vmulq_f16 + #define GGML_F16x8_REDUCE(res, x) \ + do { \ + int offset = GGML_F16_ARR >> 1; \ + for (int i = 0; i < offset; ++i) { \ + (x)[i] = vaddq_f16((x)[i], (x)[offset+i]); \ + } \ + offset >>= 1; \ + for (int i = 0; i < offset; ++i) { \ + (x)[i] = vaddq_f16((x)[i], (x)[offset+i]); \ + } \ + offset >>= 1; \ + for (int i = 0; i < offset; ++i) { \ + (x)[i] = vaddq_f16((x)[i], (x)[offset+i]); \ + } \ + const float32x4_t t0 = vcvt_f32_f16(vget_low_f16 ((x)[0])); \ + const float32x4_t t1 = vcvt_f32_f16(vget_high_f16((x)[0])); \ + (res) = (ggml_float) vaddvq_f32(vaddq_f32(t0, t1)); \ + } while (0) + + #define GGML_F16_VEC GGML_F16x8 + #define GGML_F16_VEC_ZERO GGML_F16x8_ZERO + #define GGML_F16_VEC_SET1 GGML_F16x8_SET1 + #define GGML_F16_VEC_LOAD(p, i) GGML_F16x8_LOAD(p) + #define GGML_F16_VEC_STORE(p, r, i) GGML_F16x8_STORE((__fp16 *)(p), (r)[i]) + #define GGML_F16_VEC_FMA GGML_F16x8_FMA + #define GGML_F16_VEC_ADD GGML_F16x8_ADD + #define GGML_F16_VEC_MUL GGML_F16x8_MUL + #define GGML_F16_VEC_REDUCE GGML_F16x8_REDUCE +#else + // if FP16 vector arithmetic is not supported, we use FP32 instead + // and take advantage of the vcvt_ functions to convert to/from FP16 + + #define GGML_F16_STEP 16 + #define GGML_F16_EPR 4 + + #define GGML_F32Cx4 float32x4_t + #define GGML_F32Cx4_ZERO vdupq_n_f32(0.0f) + #define GGML_F32Cx4_SET1(x) vdupq_n_f32(x) + #define GGML_F32Cx4_LOAD(x) vcvt_f32_f16(vld1_f16((const __fp16 *)(x))) + #define GGML_F32Cx4_STORE(x, y) vst1_f16(x, vcvt_f16_f32(y)) + #define GGML_F32Cx4_FMA(a, b, c) vfmaq_f32(a, b, c) + #define GGML_F32Cx4_ADD vaddq_f32 + #define GGML_F32Cx4_MUL vmulq_f32 + #define GGML_F32Cx4_REDUCE GGML_F32x4_REDUCE + + #define GGML_F16_VEC GGML_F32Cx4 + #define GGML_F16_VEC_ZERO GGML_F32Cx4_ZERO + #define GGML_F16_VEC_SET1 GGML_F32Cx4_SET1 + #define GGML_F16_VEC_LOAD(p, i) GGML_F32Cx4_LOAD(p) + #define GGML_F16_VEC_STORE(p, r, i) GGML_F32Cx4_STORE((__fp16 *)(p), r[i]) + #define GGML_F16_VEC_FMA GGML_F32Cx4_FMA + #define GGML_F16_VEC_ADD GGML_F32Cx4_ADD + #define GGML_F16_VEC_MUL GGML_F32Cx4_MUL + #define GGML_F16_VEC_REDUCE GGML_F32Cx4_REDUCE +#endif + +#elif defined(__ARM_NEON) && defined(__ARM_FEATURE_FMA) #define GGML_SIMD diff --git a/ggml/src/ggml-cpu/vec.cpp b/ggml/src/ggml-cpu/vec.cpp index 02d4061822624..f7614568ea388 100644 --- a/ggml/src/ggml-cpu/vec.cpp +++ b/ggml/src/ggml-cpu/vec.cpp @@ -17,29 +17,98 @@ void ggml_vec_dot_f32(int n, float * GGML_RESTRICT s, size_t bs, const float * G #if defined(GGML_SIMD) float sumf = 0.0f; - const int np = (n & ~(GGML_F32_STEP - 1)); - GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; + #if defined(__ARM_FEATURE_SVE) + const int sve_register_length = ggml_cpu_get_sve_cnt() * 8; + const int ggml_f32_epr = sve_register_length / 32;//8;//svcntw(); // SVE128:4, SVE256:8, SVE512:16 + const int ggml_f32_step = 8 * ggml_f32_epr; // choose 8 SVE registers + + const int np = (n & ~(ggml_f32_step - 1)); + svfloat32_t sum1 = svdup_n_f32(0.0f); + svfloat32_t sum2 = svdup_n_f32(0.0f); + svfloat32_t sum3 = svdup_n_f32(0.0f); + svfloat32_t sum4 = svdup_n_f32(0.0f); + svfloat32_t sum5 = svdup_n_f32(0.0f); + svfloat32_t sum6 = svdup_n_f32(0.0f); + svfloat32_t sum7 = svdup_n_f32(0.0f); + svfloat32_t sum8 = svdup_n_f32(0.0f); + svfloat32_t ax1,ax2,ax3,ax4,ax5,ax6,ax7,ax8; + svfloat32_t ay1,ay2,ay3,ay4,ay5,ay6,ay7,ay8; + for (int i = 0; i < np; i += ggml_f32_step) { + ax1 = GGML_F32_VEC_LOAD(x + i); + ay1 = GGML_F32_VEC_LOAD(y + i); + sum1 = GGML_F32_VEC_FMA(ax1, ay1, sum1); + + ax2 = GGML_F32_VEC_LOAD(x + i + 1*ggml_f32_epr); + ay2 = GGML_F32_VEC_LOAD(y + i + 1*ggml_f32_epr); + sum2 = GGML_F32_VEC_FMA(ax2, ay2, sum2); + + ax3 = GGML_F32_VEC_LOAD(x + i + 2*ggml_f32_epr); + ay3 = GGML_F32_VEC_LOAD(y + i + 2*ggml_f32_epr); + sum3 = GGML_F32_VEC_FMA(ax3, ay3, sum3); + + ax4 = GGML_F32_VEC_LOAD(x + i + 3*ggml_f32_epr); + ay4 = GGML_F32_VEC_LOAD(y + i + 3*ggml_f32_epr); + sum4 = GGML_F32_VEC_FMA(ax4, ay4, sum4); + + ax5 = GGML_F32_VEC_LOAD(x + i + 4*ggml_f32_epr); + ay5 = GGML_F32_VEC_LOAD(y + i + 4*ggml_f32_epr); + sum5 = GGML_F32_VEC_FMA(ax5, ay5, sum5); + + ax6 = GGML_F32_VEC_LOAD(x + i + 5*ggml_f32_epr); + ay6 = GGML_F32_VEC_LOAD(y + i + 5*ggml_f32_epr); + sum6 = GGML_F32_VEC_FMA(ax6, ay6, sum6); + + ax7 = GGML_F32_VEC_LOAD(x + i + 6*ggml_f32_epr); + ay7 = GGML_F32_VEC_LOAD(y + i + 6*ggml_f32_epr); + sum7 = GGML_F32_VEC_FMA(ax7, ay7, sum7); + + ax8 = GGML_F32_VEC_LOAD(x + i + 7*ggml_f32_epr); + ay8 = GGML_F32_VEC_LOAD(y + i + 7*ggml_f32_epr); + sum8 = GGML_F32_VEC_FMA(ax8, ay8, sum8); + } + // leftovers + // Since 8 unrolls are done in above loop, leftovers lie in range [0, ggml_f32_step] which is handled in below loop + const int np2 = (n & ~(ggml_f32_epr - 1)); + for (int i = np; i < np2; i += ggml_f32_epr) { + ax1 = GGML_F32_VEC_LOAD(x + i); + ay1 = GGML_F32_VEC_LOAD(y + i); + sum1 = GGML_F32_VEC_FMA(ax1, ay1, sum1); + } + // maximum number of leftover elements will be less that ggml_f32_epr. Apply predicated svmad on available elements only + if (np2 < n) { + svbool_t pg = svwhilelt_b32(np2, n); + ax1 = svld1_f32(pg, x + np2); + ay1 = svld1_f32(pg, y + np2); + sum1 = svmad_f32_m(pg, ax1, ay1, sum1); + } + // reduce sum1,sum2 to sum1 + GGML_F32_VEC_REDUCE(sumf, sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8); + #else + const int np = (n & ~(GGML_F32_STEP - 1)); - GGML_F32_VEC ax[GGML_F32_ARR]; - GGML_F32_VEC ay[GGML_F32_ARR]; + GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO }; - for (int i = 0; i < np; i += GGML_F32_STEP) { - for (int j = 0; j < GGML_F32_ARR; j++) { - ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR); - ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); + GGML_F32_VEC ax[GGML_F32_ARR]; + GGML_F32_VEC ay[GGML_F32_ARR]; - sum[j] = GGML_F32_VEC_FMA(sum[j], ax[j], ay[j]); + for (int i = 0; i < np; i += GGML_F32_STEP) { + for (int j = 0; j < GGML_F32_ARR; j++) { + ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR); + ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); + + sum[j] = GGML_F32_VEC_FMA(sum[j], ax[j], ay[j]); + } } - } - // reduce sum0..sum3 to sum0 - GGML_F32_VEC_REDUCE(sumf, sum); + // reduce sum0..sum3 to sum0 + GGML_F32_VEC_REDUCE(sumf, sum); - // leftovers - for (int i = np; i < n; ++i) { - sumf += x[i]*y[i]; - } + // leftovers + for (int i = np; i < n; ++i) { + sumf += x[i]*y[i]; + } + #endif #else // scalar ggml_float sumf = 0.0; diff --git a/ggml/src/ggml-cpu/vec.h b/ggml/src/ggml-cpu/vec.h index 23cbb3051f2c8..09dbade2179fb 100644 --- a/ggml/src/ggml-cpu/vec.h +++ b/ggml/src/ggml-cpu/vec.h @@ -5,6 +5,7 @@ #include "ggml-impl.h" #include "simd-mappings.h" #include "ggml.h" +#include "ggml-cpu.h" #if defined(GGML_USE_ACCELERATE) #include @@ -148,27 +149,108 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG inline static void ggml_vec_mad_f32(const int n, float * GGML_RESTRICT y, const float * GGML_RESTRICT x, const float v) { #if defined(GGML_SIMD) - const int np = (n & ~(GGML_F32_STEP - 1)); + #if defined(__ARM_FEATURE_SVE) - GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); + const int sve_register_length = ggml_cpu_get_sve_cnt() * 8; + const int ggml_f32_epr = sve_register_length / 32;//8;//svcntw(); // SVE128:4, SVE256:8, SVE512:16 + const int ggml_f32_step = 8 * ggml_f32_epr; // choose 8 SVE registers + GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); - GGML_F32_VEC ax[GGML_F32_ARR]; - GGML_F32_VEC ay[GGML_F32_ARR]; + const int np = (n & ~(ggml_f32_step - 1)); + svfloat32_t ax1, ax2, ax3, ax4, ax5, ax6, ax7, ax8; + svfloat32_t ay1, ay2, ay3, ay4, ay5, ay6, ay7, ay8; + for (int i = 0; i < np; i += ggml_f32_step) { - for (int i = 0; i < np; i += GGML_F32_STEP) { - for (int j = 0; j < GGML_F32_ARR; j++) { - ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR); - ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); - ay[j] = GGML_F32_VEC_FMA(ay[j], ax[j], vx); + ax1 = GGML_F32_VEC_LOAD(x + i); + ay1 = GGML_F32_VEC_LOAD(y + i); + ay1 = GGML_F32_VEC_FMA(ax1, vx, ay1); - GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + GGML_F32_VEC_STORE(y + i, ay1); + + ax2 = GGML_F32_VEC_LOAD(x + i + 1*ggml_f32_epr); + ay2 = GGML_F32_VEC_LOAD(y + i + 1*ggml_f32_epr); + ay2 = GGML_F32_VEC_FMA(ax2, vx, ay2); + + GGML_F32_VEC_STORE(y + i + 1*ggml_f32_epr, ay2); + + ax3 = GGML_F32_VEC_LOAD(x + i + 2*ggml_f32_epr); + ay3 = GGML_F32_VEC_LOAD(y + i + 2*ggml_f32_epr); + ay3 = GGML_F32_VEC_FMA(ax3, vx, ay3); + + GGML_F32_VEC_STORE(y + i + 2*ggml_f32_epr, ay3); + + ax4 = GGML_F32_VEC_LOAD(x + i + 3*ggml_f32_epr); + ay4 = GGML_F32_VEC_LOAD(y + i + 3*ggml_f32_epr); + ay4 = GGML_F32_VEC_FMA(ax4, vx, ay4); + + GGML_F32_VEC_STORE(y + i + 3*ggml_f32_epr, ay4); + + ax5 = GGML_F32_VEC_LOAD(x + i + 4*ggml_f32_epr); + ay5 = GGML_F32_VEC_LOAD(y + i + 4*ggml_f32_epr); + ay5 = GGML_F32_VEC_FMA(ax5, vx, ay5); + + GGML_F32_VEC_STORE(y + i + 4*ggml_f32_epr, ay5); + + ax6 = GGML_F32_VEC_LOAD(x + i + 5*ggml_f32_epr); + ay6 = GGML_F32_VEC_LOAD(y + i + 5*ggml_f32_epr); + ay6 = GGML_F32_VEC_FMA(ax6, vx, ay6); + + GGML_F32_VEC_STORE(y + i + 5*ggml_f32_epr, ay6); + + ax7 = GGML_F32_VEC_LOAD(x + i + 6*ggml_f32_epr); + ay7 = GGML_F32_VEC_LOAD(y + i + 6*ggml_f32_epr); + ay7 = GGML_F32_VEC_FMA(ax7, vx, ay7); + + GGML_F32_VEC_STORE(y + i + 6*ggml_f32_epr, ay7); + + ax8 = GGML_F32_VEC_LOAD(x + i + 7*ggml_f32_epr); + ay8 = GGML_F32_VEC_LOAD(y + i + 7*ggml_f32_epr); + ay8 = GGML_F32_VEC_FMA(ax8, vx, ay8); + + GGML_F32_VEC_STORE(y + i + 7*ggml_f32_epr, ay8); } - } + // leftovers + // Since 8 unrolls are done in above loop, leftovers lie in range [0, ggml_f32_step] which is handled in below loop + const int np2 = (n & ~(ggml_f32_epr - 1)); + for (int i = np; i < np2; i += ggml_f32_epr) { + ax1 = GGML_F32_VEC_LOAD(x + i); + ay1 = GGML_F32_VEC_LOAD(y + i); + ay1 = GGML_F32_VEC_FMA(ax1, vx, ay1); + + GGML_F32_VEC_STORE(y + i, ay1); + } + // maximum number of leftover elements will be less that ggml_f32_epr. Apply predicated svmad on available elements only + if (np2 < n) { + svbool_t pg =svwhilelt_b32(np2, n); + ax1 = svld1_f32(pg, x + np2); + ay1 = svld1_f32(pg, y + np2); + ay1 = svmad_f32_m(pg, ax1, vx, ay1); + + svst1_f32(pg, y + np2, ay1); + } + #else + const int np = (n & ~(GGML_F32_STEP - 1)); - // leftovers - for (int i = np; i < n; ++i) { - y[i] += x[i]*v; - } + GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); + + GGML_F32_VEC ax[GGML_F32_ARR]; + GGML_F32_VEC ay[GGML_F32_ARR]; + + for (int i = 0; i < np; i += GGML_F32_STEP) { + for (int j = 0; j < GGML_F32_ARR; j++) { + ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR); + ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); + ay[j] = GGML_F32_VEC_FMA(ay[j], ax[j], vx); + + GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + } + } + + // leftovers + for (int i = np; i < n; ++i) { + y[i] += x[i]*v; + } + #endif #else // scalar for (int i = 0; i < n; ++i) { @@ -220,36 +302,45 @@ inline static void ggml_vec_mad_f32_unroll(const int n, const int xs, const int } #if defined(GGML_SIMD) - const int np = (n & ~(GGML_F32_STEP - 1)); + #if defined(__ARM_FEATURE_SVE) + // scalar Route to scalar implementation //TODO: Write SVE code + for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { + for (int i = 0; i < n; ++i) { + y[i] += x[k][i]*v[k][0]; + } + } + #else + const int np = (n & ~(GGML_F32_STEP - 1)); - GGML_F32_VEC vx[GGML_VEC_MAD_UNROLL]; + GGML_F32_VEC vx[GGML_VEC_MAD_UNROLL]; - for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { - vx[k] = GGML_F32_VEC_SET1(v[k][0]); - } + for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { + vx[k] = GGML_F32_VEC_SET1(v[k][0]); + } - GGML_F32_VEC ax[GGML_VEC_MAD_UNROLL][GGML_F32_ARR]; - GGML_F32_VEC ay[GGML_F32_ARR]; + GGML_F32_VEC ax[GGML_VEC_MAD_UNROLL][GGML_F32_ARR]; + GGML_F32_VEC ay[GGML_F32_ARR]; - for (int i = 0; i < np; i += GGML_F32_STEP) { - for (int j = 0; j < GGML_F32_ARR; j++) { - ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); + for (int i = 0; i < np; i += GGML_F32_STEP) { + for (int j = 0; j < GGML_F32_ARR; j++) { + ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); - for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { - ax[k][j] = GGML_F32_VEC_LOAD(x[k] + i + j*GGML_F32_EPR); - ay[j] = GGML_F32_VEC_FMA(ay[j], ax[k][j], vx[k]); - } + for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { + ax[k][j] = GGML_F32_VEC_LOAD(x[k] + i + j*GGML_F32_EPR); + ay[j] = GGML_F32_VEC_FMA(ay[j], ax[k][j], vx[k]); + } - GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + } } - } - // leftovers - for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { - for (int i = np; i < n; ++i) { - y[i] += x[k][i]*v[k][0]; + // leftovers + for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { + for (int i = np; i < n; ++i) { + y[i] += x[k][i]*v[k][0]; + } } - } + #endif #else // scalar for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) { @@ -265,25 +356,53 @@ inline static void ggml_vec_scale_f32(const int n, float * y, const float v) { #if defined(GGML_USE_ACCELERATE) vDSP_vsmul(y, 1, &v, y, 1, n); #elif defined(GGML_SIMD) - const int np = (n & ~(GGML_F32_STEP - 1)); + #if defined(__ARM_FEATURE_SVE) + const int sve_register_length = ggml_cpu_get_sve_cnt() * 8; + const int ggml_f32_epr = sve_register_length / 32;//8;//svcntw(); // SVE128:4, SVE256:8, SVE512:16 + const int ggml_f32_step = 2 * ggml_f32_epr; + + GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); + const int np = (n & ~(ggml_f32_step - 1)); + svfloat32_t ay1; + svfloat32_t ay2; + for (int i = 0; i < np; i += ggml_f32_step) { + ay1 = GGML_F32_VEC_LOAD(y + i); + ay1 = GGML_F32_VEC_MUL(ay1, vx); + GGML_F32_VEC_STORE(y + i, ay1); + + ay2 = GGML_F32_VEC_LOAD(y + i + 1*ggml_f32_epr); + ay2 = GGML_F32_VEC_MUL(ay2, vx); + GGML_F32_VEC_STORE(y + i + 1*ggml_f32_epr, ay2); + } + // leftovers + // maximum number of leftover elements will be less that ggml_f32_epr. Apply predicated svmad on available elements only + if (np < n) { + svbool_t pg = svwhilelt_b32(np, n); + ay1 = svld1_f32(pg, y + np); + ay1 = svmul_f32_m(pg, ay1, vx); + svst1_f32(pg, y + np, ay1); + } + #else + const int np = (n & ~(GGML_F32_STEP - 1)); - GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); + GGML_F32_VEC vx = GGML_F32_VEC_SET1(v); - GGML_F32_VEC ay[GGML_F32_ARR]; + GGML_F32_VEC ay[GGML_F32_ARR]; - for (int i = 0; i < np; i += GGML_F32_STEP) { - for (int j = 0; j < GGML_F32_ARR; j++) { - ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); - ay[j] = GGML_F32_VEC_MUL(ay[j], vx); + for (int i = 0; i < np; i += GGML_F32_STEP) { + for (int j = 0; j < GGML_F32_ARR; j++) { + ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR); + ay[j] = GGML_F32_VEC_MUL(ay[j], vx); - GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + GGML_F32_VEC_STORE(y + i + j*GGML_F32_EPR, ay[j]); + } } - } - // leftovers - for (int i = np; i < n; ++i) { - y[i] *= v; - } + // leftovers + for (int i = np; i < n; ++i) { + y[i] *= v; + } + #endif #else // scalar for (int i = 0; i < n; ++i) { @@ -428,6 +547,7 @@ inline static void ggml_vec_exp_f16 (const int n, ggml_fp16_t * y, const ggml_fp static const float GELU_COEF_A = 0.044715f; static const float GELU_QUICK_COEF = -1.702f; static const float SQRT_2_OVER_PI = 0.79788456080286535587989211986876f; +static const float SQRT_2_INV = 0.70710678118654752440084436210484f; inline static float ggml_gelu_f32(float x) { return 0.5f*x*(1.0f + tanhf(SQRT_2_OVER_PI*x*(1.0f + GELU_COEF_A*x*x))); @@ -440,6 +560,14 @@ inline static void ggml_vec_gelu_f16(const int n, ggml_fp16_t * y, const ggml_fp } } +inline static void ggml_vec_gelu_erf_f16(const int n, ggml_fp16_t * y, const ggml_fp16_t * x) { + for (int i = 0; i < n; ++i) { + float xi = GGML_FP16_TO_FP32(x[i]); + float res = 0.5f*xi*(1.0f + erff(xi*SQRT_2_INV)); + y[i] = GGML_FP32_TO_FP16(res); + } +} + #ifdef GGML_GELU_FP16 inline static void ggml_vec_gelu_f32(const int n, float * y, const float * x) { uint16_t t; @@ -463,6 +591,13 @@ inline static void ggml_vec_gelu_f32(const int n, float * y, const float * x) { } #endif +inline static void ggml_vec_gelu_erf_f32(const int n, float * y, const float * x) { + for (int i = 0; i < n; ++i) { + float xi = x[i]; + y[i] = 0.5f*xi*(1.0f + erff(xi*SQRT_2_INV)); + } +} + inline static float ggml_gelu_quick_f32(float x) { return x*(1.0f/(1.0f+expf(GELU_QUICK_COEF*x))); } @@ -512,6 +647,42 @@ inline static ggml_fp16_t ggml_silu_f16(ggml_fp16_t x) { #error "ref: https://github.com/ggml-org/llama.cpp/pull/7154#issuecomment-2143844461" #endif +/* Below function was borrowed from the GitHub repository: +https://github.com/openvinotoolkit/openvino/blob/master/src/plugins/intel_cpu/src/nodes/kernels/scaled_attn/common.hpp */ +#if defined(__ARM_FEATURE_SVE) && defined(__aarch64__) + inline static svfloat32_t exp_ps_sve(svbool_t pg, svfloat32_t src) { + // Constants + const svfloat32_t log2_e = svdup_n_f32(1.4426950409f); + const svfloat32_t ln2 = svdup_n_f32(0.6931473921f); + const svfloat32_t half_ln2_sq = svdup_n_f32(0.2413862043f); + const svuint32_t not_mask17 = svdup_n_u32(~((1u << 17) - 1)); + const svfloat32_t one = svdup_n_f32(1.0f); + const svfloat32_t inactive1 = svdup_n_f32(0.0f); + const svint32_t inactive2 = svdup_n_s32(0); + + // Algorithm starts here + svfloat32_t t0 = svmul_f32_m(pg, src, log2_e); // y = x * log2(e) + svfloat32_t t1 = svrintm_f32_m(inactive1, pg, t0); // rount to int (float) + svint32_t t2 = svcvt_s32_f32_m(inactive2, pg, t1); // n + + t1 = svsub_f32_m(pg, t0, t1); // a = y - floor(y) + t1 = svadd_f32_m(pg, t1, one); // b = a + 1 + + svuint32_t t3 = svlsr_n_u32_m(pg, svreinterpret_u32_f32(t1), 17); // v = b >> 17 (u32) + svfloat32_t t4 = svexpa_f32(t3); // c = fexpa(v) + t4 = svscale_f32_m(pg, t4, t2); // fexpa(v) * 2^(n) + + // and_(t2.d, t1.d, not_mask17.d) + svfloat32_t t5 = svreinterpret_f32_u32(svand_u32_m(pg, svreinterpret_u32_f32(t1), not_mask17)); + t5 = svsub_f32_m(pg, t1, t5); // z + t0 = svmla_f32_m(pg, ln2, t5, half_ln2_sq); // ln2 + half_ln2_sq * z + t0 = svmla_f32_m(pg, one, t5, t0); // 1 + (ln2 * z) + (half_ln2_sq * z * z) + t0 = svmul_f32_m(pg, t0, t4); // Final result + + return t0; + } +#endif + #if defined(__ARM_NEON) && defined(__aarch64__) // adapted from arm limited optimized routine diff --git a/ggml/src/ggml-cuda/common.cuh b/ggml/src/ggml-cuda/common.cuh index 64fb4ff4cecc3..e1ce1d4cd1558 100644 --- a/ggml/src/ggml-cuda/common.cuh +++ b/ggml/src/ggml-cuda/common.cuh @@ -168,7 +168,7 @@ void ggml_cuda_error(const char * stmt, const char * func, const char * file, in #define CUBLAS_CHECK(err) CUDA_CHECK_GEN(err, CUBLAS_STATUS_SUCCESS, cublas_get_error_str) -#if !defined(GGML_USE_HIP) +#if !defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM) static const char * cu_get_error_str(CUresult err) { const char * err_str; cuGetErrorString(err, &err_str); @@ -635,6 +635,7 @@ struct ggml_cuda_device_info { int nsm; // number of streaming multiprocessors size_t smpb; // max. shared memory per block size_t smpbo; // max. shared memory per block (with opt-in) + bool integrated; // Device is integrated as opposed to discrete bool vmm; // virtual memory support size_t vmm_granularity; // granularity of virtual memory size_t total_vram; diff --git a/ggml/src/ggml-cuda/cpy.cu b/ggml/src/ggml-cuda/cpy.cu index d027271fcd932..2c55d2149b2d3 100644 --- a/ggml/src/ggml-cuda/cpy.cu +++ b/ggml/src/ggml-cuda/cpy.cu @@ -1,5 +1,8 @@ #include "cpy.cuh" #include "dequantize.cuh" +#ifdef GGML_USE_MUSA +#include "ggml-musa/mudnn.cuh" +#endif // GGML_USE_MUSA typedef void (*cpy_kernel_t)(const char * cx, char * cdst); @@ -597,7 +600,14 @@ void ggml_cuda_cpy(ggml_backend_cuda_context & ctx, const ggml_tensor * src0, gg #endif if (src0->type == src1->type && ggml_is_contiguous(src0) && ggml_is_contiguous(src1)) { GGML_ASSERT(ggml_nbytes(src0) == ggml_nbytes(src1)); - CUDA_CHECK(cudaMemcpyAsync(src1_ddc, src0_ddc, ggml_nbytes(src0), cudaMemcpyDeviceToDevice, main_stream)); +#ifdef GGML_USE_MUSA + if (src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16) { + CUDA_CHECK(mudnnMemcpyAsync(ctx, src1, src0)); + } else +#endif // GGML_USE_MUSA + { + CUDA_CHECK(cudaMemcpyAsync(src1_ddc, src0_ddc, ggml_nbytes(src0), cudaMemcpyDeviceToDevice, main_stream)); + } } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32) { ggml_cpy_f32_f32_cuda (src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10, nb11, nb12, nb13, main_stream, dest_ptrs_d, graph_cpynode_index); } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_BF16) { diff --git a/ggml/src/ggml-cuda/fattn-common.cuh b/ggml/src/ggml-cuda/fattn-common.cuh index a4fbd823638fa..cfab2b5ebaccc 100644 --- a/ggml/src/ggml-cuda/fattn-common.cuh +++ b/ggml/src/ggml-cuda/fattn-common.cuh @@ -623,8 +623,8 @@ static __global__ void flash_attn_combine_results( __builtin_assume(tid < D); extern __shared__ float2 meta[]; - if (tid < 2*parallel_blocks) { - ((float *) meta)[threadIdx.x] = ((const float *)VKQ_meta) [blockIdx.z*(2*parallel_blocks) + tid]; + for (int i = tid; i < 2*parallel_blocks; i += D) { + ((float *) meta)[i] = ((const float *)VKQ_meta) [blockIdx.z*(2*parallel_blocks) + i]; } __syncthreads(); diff --git a/ggml/src/ggml-cuda/fattn-mma-f16.cuh b/ggml/src/ggml-cuda/fattn-mma-f16.cuh index be0329d0e0c09..925f39e890db9 100644 --- a/ggml/src/ggml-cuda/fattn-mma-f16.cuh +++ b/ggml/src/ggml-cuda/fattn-mma-f16.cuh @@ -772,7 +772,7 @@ static __device__ __forceinline__ void flash_attn_ext_f16_iter( GGML_UNUSED(stride_mask); GGML_UNUSED(jt); GGML_UNUSED(tile_K); GGML_UNUSED(tile_V); GGML_UNUSED(tile_mask); GGML_UNUSED(Q_B); GGML_UNUSED(VKQ_C); GGML_UNUSED(KQ_max); GGML_UNUSED(KQ_rowsum); - GGML_UNUSED(kb0); + GGML_UNUSED(kb0); GGML_UNUSED(tile_Q); NO_DEVICE_CODE; #endif // NEW_MMA_AVAILABLE } @@ -1246,7 +1246,7 @@ static __global__ void flash_attn_ext_f16( NO_DEVICE_CODE; return; } -#endif __CUDA_ARCH__ == GGML_CUDA_CC_TURING +#endif // __CUDA_ARCH__ == GGML_CUDA_CC_TURING static_assert(!mla || DKQ >= DV, "MLA needs DKQ >= DV"); diff --git a/ggml/src/ggml-cuda/fattn-vec-f16.cuh b/ggml/src/ggml-cuda/fattn-vec-f16.cuh index d96e392129848..35e649cb3c81b 100644 --- a/ggml/src/ggml-cuda/fattn-vec-f16.cuh +++ b/ggml/src/ggml-cuda/fattn-vec-f16.cuh @@ -2,9 +2,9 @@ #include "fattn-common.cuh" template // D == head size -#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) +#ifndef GGML_USE_HIP __launch_bounds__(D, 1) -#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) +#endif // GGML_USE_HIP static __global__ void flash_attn_vec_ext_f16( const char * __restrict__ Q, const char * __restrict__ K, @@ -48,6 +48,12 @@ static __global__ void flash_attn_vec_ext_f16( NO_DEVICE_CODE; return; } +#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) + if (ncols > 1) { + NO_DEVICE_CODE; + return; + } +#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) //In this kernel Q, K, V are matrices while i, j, k are matrix indices. @@ -91,6 +97,13 @@ static __global__ void flash_attn_vec_ext_f16( kqsum_shared[j][threadIdx.x] = 0.0f; } } + + __shared__ half maskh_shared[ncols*D]; +#pragma unroll + for (int j = 0; j < ncols; ++j) { + maskh_shared[j*D + tid] = 0.0f; + } + __syncthreads(); // Convert Q to half2 (f16 K) or q8_1 (quantized K) and store in registers: @@ -175,6 +188,36 @@ static __global__ void flash_attn_vec_ext_f16( for (int k_VKQ_0 = blockIdx.y*D; k_VKQ_0 < ne11; k_VKQ_0 += gridDim.y*D) { // Calculate KQ tile and keep track of new maximum KQ values: + if (mask) { +#pragma unroll + for (int j = 0; j < ncols; ++j) { + maskh_shared[j*D + tid] = slopeh*maskh[j*ne11 + k_VKQ_0 + tid]; + } + + __syncthreads(); + + // When using multiple parallel sequences in llama.cpp, some KV slices can be fully masked out. + // In such cases, skip the KV slice. + // On AMD __all_sync would not work correctly because it assumes a warp size of 64. +#ifndef GGML_USE_HIP + bool skip = true; +#pragma unroll + for (int j = 0; j < ncols; ++j) { +#pragma unroll + for (int i0 = 0; i0 < D/2; i0 += WARP_SIZE) { + const int i = i0 + threadIdx.x; + + const float2 tmp = __half22float2(((const half2 *) maskh_shared)[j*(D/2) + i]); + skip = skip && isinf(tmp.x) && isinf(tmp.y); + } + } + if (__all_sync(0xFFFFFFFF, skip)) { + __syncthreads(); + continue; + } +#endif // GGML_USE_HIP + } + // For unknown reasons using a half array of size 1 for kqmax_new causes a performance regression, // see https://github.com/ggerganov/llama.cpp/pull/7061 . // Therefore this variable is defined twice but only used once (so that the compiler can optimize out the unused variable). @@ -202,7 +245,7 @@ static __global__ void flash_attn_vec_ext_f16( sum = logit_softcap*tanhf(sum); } - sum += mask ? slopeh*maskh[j*ne11 + k_VKQ_0 + i_KQ] : __float2half(0.0f); + sum += maskh_shared[j*D + i_KQ]; if (ncols == 1) { kqmax_new = ggml_cuda_hmax(kqmax_new, sum); @@ -335,7 +378,9 @@ void ggml_cuda_flash_attn_ext_vec_f16_case(ggml_backend_cuda_context & ctx, ggml float logit_softcap; memcpy(&logit_softcap, (const float *) KQV->op_params + 2, sizeof(float)); - if (Q->ne[1] == 1) { + const int cc = ggml_cuda_info().devices[ggml_cuda_get_device()].cc; + + if (Q->ne[1] == 1 || GGML_CUDA_CC_IS_NVIDIA(cc)) { constexpr int cols_per_block = 1; if (logit_softcap == 0.0f) { constexpr bool use_logit_softcap = false; diff --git a/ggml/src/ggml-cuda/fattn-vec-f32.cuh b/ggml/src/ggml-cuda/fattn-vec-f32.cuh index 7064675d5ab3f..9539679177969 100644 --- a/ggml/src/ggml-cuda/fattn-vec-f32.cuh +++ b/ggml/src/ggml-cuda/fattn-vec-f32.cuh @@ -2,9 +2,9 @@ #include "fattn-common.cuh" template // D == head size -#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) +#ifndef GGML_USE_HIP __launch_bounds__(D, 1) -#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) +#endif // GGML_USE_HIP static __global__ void flash_attn_vec_ext_f32( const char * __restrict__ Q, const char * __restrict__ K, @@ -60,6 +60,12 @@ static __global__ void flash_attn_vec_ext_f32( NO_DEVICE_CODE; return; } +#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) + if (ncols > 1) { + NO_DEVICE_CODE; + return; + } +#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) //In this kernel Q, K, V are matrices while i, j, k are matrix indices. @@ -104,6 +110,13 @@ static __global__ void flash_attn_vec_ext_f32( kqsum_shared[j][threadIdx.x] = 0.0f; } } + + __shared__ float maskf_shared[ncols*D]; +#pragma unroll + for (int j = 0; j < ncols; ++j) { + maskf_shared[j*D + tid] = 0.0f; + } + __syncthreads(); // Convert Q to float2 (f16 K) or q8_1 (quantized K) and store in registers: @@ -181,6 +194,35 @@ static __global__ void flash_attn_vec_ext_f32( for (int k_VKQ_0 = blockIdx.y*D; k_VKQ_0 < ne11; k_VKQ_0 += gridDim.y*D) { // Calculate KQ tile and keep track of new maximum KQ values: + if (mask) { +#pragma unroll + for (int j = 0; j < ncols; ++j) { + maskf_shared[j*D + tid] = slope*__half2float(maskh[j*ne11 + k_VKQ_0 + tid]); + } + + __syncthreads(); + + // When using multiple parallel sequences in llama.cpp, some KV slices can be fully masked out. + // In such cases, skip the KV slice. + // On AMD __all_sync would not work correctly because it assumes a warp size of 64. +#ifndef GGML_USE_HIP + bool skip = true; +#pragma unroll + for (int j = 0; j < ncols; ++j) { +#pragma unroll + for (int i0 = 0; i0 < D; i0 += WARP_SIZE) { + const int i = i0 + threadIdx.x; + + skip = skip && isinf(maskf_shared[j*D + i]); + } + } + if (__all_sync(0xFFFFFFFF, skip)) { + __syncthreads(); + continue; + } +#endif // GGML_USE_HIP + } + float kqmax_new_arr[ncols]; #pragma unroll for (int j = 0; j < ncols; ++j) { @@ -204,7 +246,7 @@ static __global__ void flash_attn_vec_ext_f32( sum = logit_softcap*tanhf(sum); } - sum += mask ? slope*__half2float(maskh[j*ne11 + k_VKQ_0 + i_KQ]) : 0.0f; + sum += maskf_shared[j*D + i_KQ]; kqmax_new_arr[j] = fmaxf(kqmax_new_arr[j], sum); @@ -326,7 +368,9 @@ void ggml_cuda_flash_attn_ext_vec_f32_case(ggml_backend_cuda_context & ctx, ggml float logit_softcap; memcpy(&logit_softcap, (const float *) KQV->op_params + 2, sizeof(float)); - if (Q->ne[1] == 1) { + const int cc = ggml_cuda_info().devices[ggml_cuda_get_device()].cc; + + if (Q->ne[1] == 1 || GGML_CUDA_CC_IS_NVIDIA(cc)) { constexpr int cols_per_block = 1; if (logit_softcap == 0.0f) { constexpr bool use_logit_softcap = false; diff --git a/ggml/src/ggml-cuda/ggml-cuda.cu b/ggml/src/ggml-cuda/ggml-cuda.cu index 02dc8c12dbd8c..2a6f7f108b3f8 100644 --- a/ggml/src/ggml-cuda/ggml-cuda.cu +++ b/ggml/src/ggml-cuda/ggml-cuda.cu @@ -243,10 +243,10 @@ static ggml_cuda_device_info ggml_cuda_init() { info.default_tensor_split[id] = total_vram; total_vram += prop.totalGlobalMem; - - info.devices[id].nsm = prop.multiProcessorCount; - info.devices[id].smpb = prop.sharedMemPerBlock; - info.devices[id].warp_size = prop.warpSize; + info.devices[id].integrated = prop.integrated; + info.devices[id].nsm = prop.multiProcessorCount; + info.devices[id].smpb = prop.sharedMemPerBlock; + info.devices[id].warp_size = prop.warpSize; #if defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__) info.devices[id].smpbo = prop.sharedMemPerBlock; @@ -1065,6 +1065,10 @@ static const char * ggml_backend_cuda_host_buffer_type_name(ggml_backend_buffer_ GGML_UNUSED(buft); } +static bool ggml_backend_buft_is_cuda_host(ggml_backend_buffer_type_t buft) { + return buft->iface.get_name == ggml_backend_cuda_host_buffer_type_name; +} + static void ggml_backend_cuda_host_buffer_free_buffer(ggml_backend_buffer_t buffer) { CUDA_CHECK(cudaFreeHost(buffer->context)); } @@ -2192,6 +2196,9 @@ static bool ggml_cuda_compute_forward(ggml_backend_cuda_context & ctx, struct gg case GGML_UNARY_OP_SILU: ggml_cuda_op_silu(ctx, dst); break; + case GGML_UNARY_OP_GELU_ERF: + ggml_cuda_op_gelu_erf(ctx, dst); + break; case GGML_UNARY_OP_GELU_QUICK: ggml_cuda_op_gelu_quick(ctx, dst); break; @@ -2638,6 +2645,8 @@ static void update_cuda_graph_executable(ggml_backend_cuda_context * cuda_ctx) { static void evaluate_and_capture_cuda_graph(ggml_backend_cuda_context * cuda_ctx, ggml_cgraph * cgraph, bool & graph_evaluated_or_captured, bool & use_cuda_graph, bool & cuda_graph_update_required) { + // flag used to determine whether it is an integrated_gpu + const bool integrated = ggml_cuda_info().devices[cuda_ctx->device].integrated; while (!graph_evaluated_or_captured) { // Only perform the graph execution if CUDA graphs are not enabled, or we are capturing the graph. @@ -2656,7 +2665,7 @@ static void evaluate_and_capture_cuda_graph(ggml_backend_cuda_context * cuda_ctx if (node->src[j] != nullptr) { assert(node->src[j]->buffer); assert(node->src[j]->buffer->buft == ggml_backend_cuda_buffer_type(cuda_ctx->device) || - ggml_backend_buft_is_cuda_split(node->src[j]->buffer->buft)); + ggml_backend_buft_is_cuda_split(node->src[j]->buffer->buft) || (integrated && ggml_backend_buft_is_cuda_host(node->src[j]->buffer->buft))); } } #endif @@ -2977,6 +2986,7 @@ static bool ggml_backend_cuda_device_supports_op(ggml_backend_dev_t dev, const g case GGML_UNARY_OP_SIGMOID: case GGML_UNARY_OP_HARDSIGMOID: case GGML_UNARY_OP_HARDSWISH: + case GGML_UNARY_OP_GELU_ERF: case GGML_UNARY_OP_GELU_QUICK: case GGML_UNARY_OP_TANH: case GGML_UNARY_OP_EXP: @@ -2990,9 +3000,12 @@ static bool ggml_backend_cuda_device_supports_op(ggml_backend_dev_t dev, const g { struct ggml_tensor * a = op->src[0]; struct ggml_tensor * b = op->src[1]; - // for small weight matrices the active device can end up without any rows, don't use row split in those cases - // this avoids some edge cases (and the performance would not be good anyways) if (a->buffer && ggml_backend_buft_is_cuda_split(a->buffer->buft)) { + if (a->ne[2] > 1 || a->ne[3] > 1) { + return false; + } + // for small weight matrices the active device can end up without any rows, don't use row split in those cases + // this avoids some edge cases (and the performance would not be good anyways) ggml_backend_cuda_split_buffer_type_context * buft_ctx = (ggml_backend_cuda_split_buffer_type_context *) a->buffer->buft->context; int64_t row_low; int64_t row_high; @@ -3259,7 +3272,9 @@ static bool ggml_backend_cuda_device_supports_op(ggml_backend_dev_t dev, const g } static bool ggml_backend_cuda_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) { - return (ggml_backend_buft_is_cuda(buft) || ggml_backend_buft_is_cuda_split(buft)) && buft->device == dev; + ggml_backend_cuda_device_context * dev_ctx = (ggml_backend_cuda_device_context *) dev->context; + const bool integrated = ggml_cuda_info().devices[dev_ctx->device].integrated; + return (((ggml_backend_buft_is_cuda(buft) || ggml_backend_buft_is_cuda_split(buft)) && buft->device == dev) || (integrated && ggml_backend_buft_is_cuda_host(buft))); } static int64_t get_op_batch_size(const ggml_tensor * op) { diff --git a/ggml/src/ggml-cuda/unary.cu b/ggml/src/ggml-cuda/unary.cu index ec5773e01637e..2c0375fbe3cf6 100644 --- a/ggml/src/ggml-cuda/unary.cu +++ b/ggml/src/ggml-cuda/unary.cu @@ -23,6 +23,12 @@ static __device__ __forceinline__ float op_gelu(float x) { return 0.5f*x*(1.0f + tanhf(SQRT_2_OVER_PI*x*(1.0f + GELU_COEF_A*x*x))); } +static __device__ __forceinline__ float op_gelu_erf(float x) { + const float SQRT_2_INV = 0.70710678118654752440084436210484f; + + return 0.5f*x*(1.0f + erff(x*SQRT_2_INV)); +} + static __device__ __forceinline__ float op_gelu_quick(float x) { const float GELU_QUICK_COEF = -1.702f; @@ -134,6 +140,10 @@ void ggml_cuda_op_gelu(ggml_backend_cuda_context & ctx, ggml_tensor * dst) { ggml_cuda_op_unary(ctx, dst); } +void ggml_cuda_op_gelu_erf(ggml_backend_cuda_context & ctx, ggml_tensor * dst) { + ggml_cuda_op_unary(ctx, dst); +} + void ggml_cuda_op_gelu_quick(ggml_backend_cuda_context & ctx, ggml_tensor * dst) { ggml_cuda_op_unary(ctx, dst); } diff --git a/ggml/src/ggml-cuda/unary.cuh b/ggml/src/ggml-cuda/unary.cuh index 940a1feed9a9c..6686fc17e9193 100644 --- a/ggml/src/ggml-cuda/unary.cuh +++ b/ggml/src/ggml-cuda/unary.cuh @@ -30,6 +30,8 @@ void ggml_cuda_op_silu(ggml_backend_cuda_context & ctx, ggml_tensor * dst); void ggml_cuda_op_silu_back(ggml_backend_cuda_context & ctx, ggml_tensor * dst); +void ggml_cuda_op_gelu_erf(ggml_backend_cuda_context & ctx, ggml_tensor * dst); + void ggml_cuda_op_gelu_quick(ggml_backend_cuda_context & ctx, ggml_tensor * dst); void ggml_cuda_op_tanh(ggml_backend_cuda_context & ctx, ggml_tensor * dst); diff --git a/ggml/src/ggml-hexagon/CMakeLists.txt b/ggml/src/ggml-hexagon/CMakeLists.txt new file mode 100644 index 0000000000000..942d4ee0e1efc --- /dev/null +++ b/ggml/src/ggml-hexagon/CMakeLists.txt @@ -0,0 +1,133 @@ +project(ggml-hexagon) +message(STATUS "Using HEXAGON backend") +message("CMAKE_SYSTEM_NAME : ${CMAKE_SYSTEM_NAME}") + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(NOT DEFINED QNN_SDK_PATH) + message(FATAL_ERROR "QNN_SDK_PATH not defined") +endif() + +if(NOT DEFINED HEXAGON_SDK_PATH) + message(FATAL_ERROR "HEXAGON_SDK_PATH not defined") +endif() + +message("QNN_SDK_PATH : ${QNN_SDK_PATH}") +message("HEXAGON_SDK_PATH: ${HEXAGON_SDK_PATH}") +message("HTP_ARCH_VERSION: ${HTP_ARCH_VERSION}") + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(DEBUG_FLAG "-DDEBUG -Wall") + message("Debug mode:${DEBUG_FLAG}") +else() + set(DEBUG_FLAG "-DNDEBUG -Wall") +#manually disable all verbose logs in ggml-hexagon/CMakeLists.txt to +#make compare NPU performance through llama-bench more clear +#set(DEBUG_FLAG "-DNDEBUG -Wall -DDISABLE_ALL_LOG") + message("Release mode:${DEBUG_FLAG}") +endif() + +#v68 --- Snapdragon 888 +#v69 --- Snapdragon 8 Gen1 +#v73 --- Snapdragon 8 Gen2 +#v75 --- Snapdragon 8 Gen3 +#v79 --- Snapdragon 8 Elite(aka Gen4) +if(NOT DEFINED HTP_ARCH_VERSION) + message(FATAL_ERROR "HTP_ARCH_VERSION not defined, valid htp arch: v68,v69,v73,v75,v79") +endif() + +#check whether user's specified htp arch is valid +set(CHECK_HTP_ARCH "WRONG") +foreach (feat v68 v69 v73 v75 v79) + if (${feat} STREQUAL ${HTP_ARCH_VERSION}) + set(CHECK_HTP_ARCH "GOOD") + endif() +endforeach() +if (${CHECK_HTP_ARCH} STREQUAL "WRONG") + message(FATAL_ERROR "ggml-hexagon backend only support htp arch v68,v69,v73,v75,v79") +endif() + +#check optimization flags +set(OPT_FLAG " ") +if (${HTP_ARCH_VERSION} STREQUAL "v75" OR ${HTP_ARCH_VERSION} STREQUAL "v79") + #works fine on Snapdragon 8Gen3&8Elite with 1.5x - 3x performance gains with the default ggml backend + set(OPT_FLAG " -O3 -march=armv8.7-a -mcpu=cortex-x1 -mtune=cortex-x1 -flto -D_GNU_SOURCE -fvectorize -ffp-model=fast -fno-finite-math-only") +endif() +message("OPT_FLAG:${OPT_FLAG}") + +if(CMAKE_SYSTEM_NAME STREQUAL "Android") + find_library(LOG_LIB log) + + add_library(cdsprpc + SHARED + IMPORTED) + set_target_properties(cdsprpc + PROPERTIES + IMPORTED_LOCATION + ${HEXAGON_SDK_PATH}/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc.so) + + set(QNN_LINK_LIBRARIES ${LOG_LIB} cdsprpc) + set(QNN_DEFAULT_LIB_SEARCH_PATH "/data/local/tmp/" CACHE STRING "customized library search path for QNN backend") + + include_directories(${HEXAGON_SDK_PATH}/incs) + include_directories(${HEXAGON_SDK_PATH}/incs/stddef) + include_directories(${HEXAGON_SDK_PATH}/ipc/fastrpc/incs) + include_directories(${HEXAGON_SDK_PATH}/ipc/fastrpc/rpcmem/inc) + include_directories(${HEXAGON_SDK_PATH}/ipc/fastrpc/remote/ship/android_Debug_aarch64) + include_directories(${HEXAGON_SDK_PATH}/utils/examples) + include_directories(${HEXAGON_SDK_PATH}/ipc/fastrpc/rtld/ship/android_aarch64) + include_directories(${HEXAGON_SDK_PATH}/libs/atomic/inc) + include_directories(${HEXAGON_SDK_PATH}/libs/atomic/android_Debug_aarch64/ship) + include_directories(${CMAKE_SOURCE_DIR}/ggml/src/ggml-hexagon/) + include_directories(${CMAKE_SOURCE_DIR}/ggml/src/ggml-hexagon/kernels/) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(QNN_DEFAULT_LIB_SEARCH_PATH "C:\\" CACHE STRING "customized library search path for QNN backend") +else() + message(FATAL_ERROR "ggml-hexagon now only available on Android and Windows(Windows on ARM)") +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DGGML_USE_HEXAGON ${DEBUG_FLAG} ${OPT_FLAG}") + +file(GLOB HEXAGON_SOURCES "${CMAKE_CURRENT_LIST_DIR}/*.cpp" "${CMAKE_CURRENT_LIST_DIR}/kernels/stub.c") +ggml_add_backend_library(ggml-hexagon ${HEXAGON_SOURCES}) + +target_include_directories(ggml-hexagon PRIVATE ${QNN_SDK_PATH}/include/QNN ${HEXAGON_SDK_PATH} ${CMAKE_CURRENT_LIST_DIR}) +target_link_libraries(ggml-hexagon PRIVATE ${QNN_LINK_LIBRARIES}) + +string(REGEX REPLACE "/$" "" QNN_DEFAULT_LIB_SEARCH_PATH "${QNN_DEFAULT_LIB_SEARCH_PATH}") +target_compile_definitions(ggml-hexagon PRIVATE QNN_DEFAULT_LIB_SEARCH_PATH="${QNN_DEFAULT_LIB_SEARCH_PATH}/") + +#cross compiling source codes of hexagon kernels which running on cDSP side +function(ggml_hexagon_build_kernel KNAME) + message(STATUS "ggml_hexagon: build hexagon-kernel ${KNAME}") + + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND echo "current working path:`pwd`\n" + COMMAND echo "${CMAKE_CURRENT_LIST_DIR}/kernels" + COMMAND make -C ${CMAKE_CURRENT_LIST_DIR}/kernels/ clean + COMMAND make -C ${CMAKE_CURRENT_LIST_DIR}/kernels/ HEXAGON_SDK_PATH=${HEXAGON_SDK_PATH} HTP_ARCH_VERSION=${HTP_ARCH_VERSION} DEBUG_FLAG=${DEBUG_FLAG} + COMMAND echo "current working path:`pwd`\n" + COMMAND ls -l ../../../bin/libggmlop-skel.so + COMMENT "build hexagon-kernel" + ) +endfunction() + +function(ggml_hexagon_setup_cfg KNAME) + message(STATUS "ggml_hexagon: setup runtime configuration file ${KNAME}") + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND echo "current working path:`pwd`\n" + COMMAND /bin/cp -fv ../../../../../scripts/${KNAME} ../../../bin/ + COMMENT "setup runtime configuration file" + ) +endfunction() + +ggml_hexagon_build_kernel("cdsp") +ggml_hexagon_setup_cfg("ggml-hexagon.cfg") diff --git a/ggml/src/ggml-hexagon/ggml-hexagon.cpp b/ggml/src/ggml-hexagon/ggml-hexagon.cpp new file mode 100644 index 0000000000000..8e4ab450eb07c --- /dev/null +++ b/ggml/src/ggml-hexagon/ggml-hexagon.cpp @@ -0,0 +1,6707 @@ +/* + * Copyright (c) 2024-2025 The ggml authors + * + * Qualcomm QNN SDK and reference tech guides could be found at: + * https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk + * Qualcomm Hexagon SDK and reference tech guides could be found at: + * https://developer.qualcomm.com/software/hexagon-dsp-sdk/tools + * + * this single-source-file or self-contained implementation of ggml-hexagon backend has 8 sections: + * section-1 forward/prototype declaration, global vars, macros, data structures + * section-2 internal troubleshooting function/class + * section-3 helper function for WoA(Windows on ARM) + * section-4 general helper function + * section-5 QNN helper function/class + * section-6 implementation of hwaccel approach through QNN: offload ggmlop to QNN + * section-7 cDSP helper function + * section-8 implementation of ggml-hexagon backend according to specification in ggml backend subsystem + * + * currently provide following ggml op' implementation through QNN: + * - GGML_OP_ADD/GGML_OP_SUB/GGML_OP_MUL/GGML_OP_DIV/GGML_OP_LOG/GGML_OP_SQRT: + * this is a simple hwaccel skeleton, can expand other ggml ops according to expertise + * - GGML_OP_MUL_MAT: + * this is a complicated hwaccel skeleton, can expand other ggml ops accordingly + * + * currently provide following ggml op' implementation through cDSP in hexagon-kernels: + * - GGML_OP_ADD & GGML_OP_MUL_MAT: + * this is a hwaccel skeleton, can expand other ggml ops accordingly + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__ANDROID__) || defined(__linux__) +#include +#include +#include +#include +#include +#include +#include +#endif + +#if !defined(__ANDROID__) && !defined(__linux__) +#include +#include +#include +#endif + +#if defined(__ANDROID__) +#include "android/log.h" + +#include "rpcmem.h" +#include "remote.h" +#include "os_defines.h" +#include "domain.h" +#include "AEEStdErr.h" +#include "HAP_power.h" +#include "HAP_farf.h" +#endif + +#include "QnnTypes.h" +#include "QnnCommon.h" +#include "QnnContext.h" +#include "QnnBackend.h" +#include "QnnGraph.h" +#include "QnnProperty.h" +#include "QnnTensor.h" +#include "QnnInterface.h" +#include "Saver/QnnSaver.h" +#include "System/QnnSystemInterface.h" +#include "HTP/QnnHtpDevice.h" +#include "HTP/QnnHtpGraph.h" + +#include "ggml-hexagon.h" +#include "ggml-impl.h" +#include "ggml-backend-impl.h" + +#include "kernels/skel.h" + +// ================================================================================================= +// section-1: forward/prototype declaration, global vars, macros, data structures +// ================================================================================================= +class qnn_instance; +class hexagon_profiler; +struct ggml_backend_hexagon_context; + +#ifdef NDEBUG +#define GGMLHEXAGON_DEBUG 0 +#else +#define GGMLHEXAGON_DEBUG 1 +#endif + +#ifndef PROJECT_NAME +#define PROJECT_NAME "ggml-hexagon" +#endif + +#define GGMLHEXAGON_LOGBUF_LEN 4096 +#define GGMLHEXAGON_TMPBUF_LEN 256 + +#define GGMLHEXAGON_LOG_ERROR(...) ggmlhexagon_log_internal(GGML_LOG_LEVEL_ERROR, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) +#define GGMLHEXAGON_LOG_WARN(...) ggmlhexagon_log_internal(GGML_LOG_LEVEL_WARN , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + +#if !defined (DISABLE_ALL_LOG) +#define GGMLHEXAGON_LOG_INFO(...) ggmlhexagon_log_internal(GGML_LOG_LEVEL_INFO , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) +#define GGMLHEXAGON_LOG_VERBOSE(...) ggmlhexagon_log_internal(GGML_LOG_LEVEL_CONT , __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) +#else +//manually disable all verbose logs in ggml-hexagon/CMakeLists.txt to +//make compare NPU performance through llama-bench more clear +#define GGMLHEXAGON_LOG_INFO(...) +#define GGMLHEXAGON_LOG_VERBOSE(...) +#endif + +#if GGMLHEXAGON_DEBUG +#define GGMLHEXAGON_LOG_DEBUG(...) ggmlhexagon_log_internal(GGML_LOG_LEVEL_DEBUG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) +#else +#define GGMLHEXAGON_LOG_DEBUG(...) +#endif + +#define QNN_VER_PTR(x) (&((x).v1)) +#define RPCMEM_DEFAULT_FLAGS 1 +#define RPCMEM_HEAP_ID_SYSTEM 25 +#define SIZE_IN_MB (1 << 20) +#define STATUS_CONTEXT 0x12345678 + +#if !defined (_WINDOWS) +#pragma weak remote_system_request +#endif + +#define CHECK_QNN_API(error, result) \ + do { \ + error = (result); \ + if (QNN_SUCCESS != error) { \ + if (error == QNN_COMMON_ERROR_NOT_SUPPORTED) { \ + GGMLHEXAGON_LOG_WARN("WARNING: QNN feature/API not supported\n"); \ + } else { \ + GGMLHEXAGON_LOG_INFO("QNN API error = %d(%s)\n", error, ggmlqnn_get_qnnerror_string(error)); \ + } \ + } \ + } while (0) + +#define GGMLQNN_CHECK_PARAMS(ctx, src0, src1, dst) \ + do { \ + if (g_hexagon_appcfg.hwaccel_approach != HWACCEL_CDSP) { \ + if (!ggmlqnn_is_valid_params((ctx), (src0), (src1), (dst))) { \ + return; \ + } \ + } \ + } while (0) \ + +// ================================================================================================= +// section-1: data type, data structure, global vars +// ================================================================================================= +using pfn_rpc_mem_init = void (*)(void); +using pfn_rpc_mem_deinit = void (*)(void); +using pfn_rpc_mem_alloc = void *(*)(int, uint32_t, int); +using pfn_rpc_mem_free = void (*)(void *); +using pfn_rpc_mem_to_fd = int (*)(void *); +using _pfn_QnnSaver_initialize = decltype(QnnSaver_initialize); +using _pfn_QnnInterface_getProviders = decltype(QnnInterface_getProviders); +using _pfn_QnnSystemInterface_getProviders = decltype(QnnSystemInterface_getProviders); + +//QNN resource management for the general approach through QNN +using qnn_tensors_t = std::vector< Qnn_Tensor_t >; +using qnn_ptensors_t = std::vector< Qnn_Tensor_t *>; +using qnn_singlenode_res_t = std::tuple; + +typedef void (* ggmlqnn_op_func_t)(ggml_backend_hexagon_context * ctx, ggml_tensor * op); +typedef int (* notify_callback_fn)(void * context, int domain, int session, remote_rpc_status_flags_t status); +typedef int (* ggmlhexagon_op_func_t)(remote_handle64 handle, const dsptensor * src0, const dsptensor * src1, dsptensor * dst); + +enum qnn_index_type { + QNN_TENSOR_INDEX = 0, + QNN_OPCFG_INDEX = 1, +}; + +enum qnn_profile_level { + PROFILE_OFF = 0, + PROFILE_BASIC = 1, + PROFILE_DETAIL = 2, +}; + +//0: general approach through QNN:offload ggmlop to QNN +//1: special approach through QNN-SINGLEGRAPH:mapping entire ggml cgraph to a single QNN graph +//2: general approach through Hexagon cDSP:offload ggmlop to Hexagon cDSP directly +enum hwaccel_approach_type { + HWACCEL_QNN = 0, + HWACCEL_QNN_SINGLEGRAPH = 1, + HWACCEL_CDSP = 2, +}; + +enum hexagon_dsp_type { + HEXAGON_ADSP = 0, + HEXAGON_MDSP = 1, + HEXAGON_SDSP = 2, + HEXAGON_CDSP = 3, + HEXAGON_CDSP1 = 4, +}; + +enum qcom_htp_arch { + NONE = 0, + V68 = 68, + V69 = 69, + V73 = 73, + V75 = 75, + V79 = 79, +}; + +enum qcom_chipset_soc_model { + UNKNOWN_SM = 0, + SM7450 = 41, // v69, 7 Gen1 + SM8350 = 30, // v68, 888 + SM8450 = 36, // v69, SD 8 Gen 1 + SM8475 = 42, // v69, SD 8+ Gen 1 + SM8550 = 43, // v73, SD 8 Gen 2 + SM8650 = 57, // v75, SD 8 Gen 3 + SM8750 = 69, // v79, SD 8 Elite(aka 8 Gen 4) +#if !defined(__ANDROID__) && !defined(__linux__) + SC7280X = 44, + SC8280X = 37, + SC8380XP = 60, +#endif +}; + +//borrowed from Android source code, might not be accurate +enum ion_heap_ids { + INVALID_HEAP_ID = -1, + ION_CP_MM_HEAP_ID = 8, + ION_SECURE_HEAP_ID = 9, + ION_SECURE_DISPLAY_HEAP_ID = 10, + ION_CP_MFC_HEAP_ID = 12, + ION_SPSS_HEAP_ID = 13, + ION_CP_WB_HEAP_ID = 16, + ION_CAMERA_HEAP_ID = 20, + ION_SYSTEM_CONTIG_HEAP_ID = 21, + ION_ADSP_HEAP_ID = 22, + ION_PIL1_HEAP_ID = 23, + ION_SF_HEAP_ID = 24, + ION_SYSTEM_HEAP_ID = 25, + ION_PIL2_HEAP_ID = 26, + ION_QSECOM_HEAP_ID = 27, + ION_AUDIO_HEAP_ID = 28, + ION_MM_FIRMWARE_HEAP_ID = 29, + ION_HEAP_ID_RESERVED = 31 +}; + +struct qcom_socinfo { + uint32_t soc_model; + size_t htp_arch; + size_t vtcm_size_in_mb; + char soc_desc[GGML_MAX_NAME]; +}; + +struct ggml_backend_hexagon_context { + int device; + char name[GGML_MAX_NAME]; + char desc[GGML_MAX_NAME]; + char lib[GGML_MAX_NAME]; + qnn_instance * instance; + struct ggml_backend * backend; + QNN_INTERFACE_VER_TYPE raw_interface; + QNN_SYSTEM_INTERFACE_VER_TYPE raw_system_interface; + struct qcom_socinfo socinfo; + + //QNN resource management for the general approach through QNN + std::map qnn_singlenode_graph_map; + + //quantize data -> fp32 + std::unique_ptr work_data; + std::vector> tasks; + size_t work_size; + size_t desired_size; + int n_threads; + + //Hexagon resource management for the general approach through Hexagaon cDSP + size_t rpc_mempool_capacity; + size_t rpc_mempool_len; + size_t rpc_mempool_usage; + void * rpc_mempool; + int rpc_mempool_handle; + remote_handle64 ggmlop_handle; + int domain_id; +}; + +struct qnn_op_caps { + bool supported; + ggml_op op; + const size_t input_param_count; + const char * qnn_op_name; +}; + +struct hexagon_op_caps { + bool supported; + ggml_op op; + const size_t input_param_count; + const char * hexagon_op_name; + ggmlhexagon_op_func_t dsp_op_func; +}; + +struct hexagon_appcfg_t { + int print_qnn_internal_log; // enable/disable QNN's internal log + int enable_perf; // enable/disable perf of a specified ggml op + int enable_profiler; // enable/disable profiler feature to visualization comparison between HWACCEL_CDSP and HWACCEL_QNN + int print_tensors_info; // enable/disable print tensors info in op function + int dump_op_info; // enable/disable dump op info in handle_op + int enable_q_mulmat; // enable/disable offload quantized mulmat + int enable_pinned_memory; // enable/disable pinned-memory feature + int precision_mode; // 0: default 1:fp16 + int hvx_threads; + int vtcm_size_in_mb; + int enable_dlbc; + int hwaccel_approach; // 0: HWACCEL_QNN 1: HWACCEL_QNN_SINGLEGRAPH 2: HWACCEL_CDSP + int hexagon_backend; // 0: HEXAGON_BACKEND_QNNCPU 1: HEXAGON_BACKEND_QNNGPU 2: HEXAGON_BACKEND_QNNNPU 3: HEXAGON_BACKEND_CDSP 4: ggml + int enable_rpc_ion_mempool; // enable/disable rpc ion memory pool + int enable_all_q_mulmat; // enable/disable offload all quantized type mulmat to cDSP + int profiler_duration; // threshold of duration in profiler, per seconds + int profiler_counts; // threshold of counts in profiler + int thread_counts; // thread_counts on cDSP side + const char * cfgfilename; + const char * runtime_libpath; + char ggml_hexagon_version[GGMLHEXAGON_TMPBUF_LEN]; + char ggml_dsp_version[GGMLHEXAGON_TMPBUF_LEN]; +}; + +static struct hexagon_appcfg_t g_hexagon_appcfg = { + .print_qnn_internal_log = 0, + .enable_perf = 1, + .enable_profiler = 0, + .print_tensors_info = 0, + .dump_op_info = 0, + .enable_q_mulmat = 0, + .enable_pinned_memory = 0, + .precision_mode = 0, + .hvx_threads = 4, + .vtcm_size_in_mb = 8, + .enable_dlbc = 1, + .hwaccel_approach = HWACCEL_CDSP, + .hexagon_backend = HEXAGON_BACKEND_CDSP, + .enable_rpc_ion_mempool = 0, + .enable_all_q_mulmat = 0, + .profiler_duration = 5, //seconds + .profiler_counts = 100, + .thread_counts = 4, + .cfgfilename = "ggml-hexagon.cfg", +#if defined(__ANDROID__) + #if defined(STANDARD_ANDROID_APP) + .runtime_libpath = "/data/data/com.kantvai.kantvplayer/", + #else + .runtime_libpath = "/data/local/tmp/", + #endif +#elif defined(__linux__) + .qnn_runtimelib_path = "/tmp/", +#elif defined(_WIN32) + .qnn_runtimelib_path = "C:\\", +#endif + .ggml_hexagon_version = {"1.08"}, + .ggml_dsp_version = {"0.63"}, +}; + +//file:///opt/qcom/aistack/qairt/2.31.0.250130/docs/QNN/general/overview.html#tbl-supported-snapdragon-devices +static struct qcom_socinfo g_qnn_soc_info_table[] = { + /* Qualcomm SnapDragon 7 Gen 1 */ + { + .soc_model = SM7450, + .htp_arch = V69, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 7 Gen 1"}, + + /* Qualcomm SnapDragon 888 */ + { + .soc_model = SM8350, + .htp_arch = V68, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 888 "}, + + /* Qualcomm SnapDragon 8 Gen 1 */ + { + .soc_model = SM8450, + .htp_arch = V69, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8 Gen 1"}, + + /* Qualcomm SnapDragon 8 Gen 1+ */ + { + .soc_model = SM8475, + .htp_arch = V69, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8 Gen 1+"}, + + /* Qualcomm SnapDragon 8 Gen 2 */ + { + .soc_model = SM8550, + .htp_arch = V73, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8 Gen 2"}, + + /* Qualcomm SnapDragon 8 Gen 3 */ + { + .soc_model = SM8650, + .htp_arch = V75, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8 Gen 3 "}, + + /* Qualcomm SnapDragon 8 Gen 4 */ + { + .soc_model = SM8750, + .htp_arch = V79, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8 Elite(aka 8 Gen 4)"}, + +#if !defined(__ANDROID__) && !defined(__linux__) + /* Qualcomm SnapDragon 7c Gen 2 */ + { + .soc_model = SC7280X, + .htp_arch = V68, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 7c Gen 2"}, + + /* Qualcomm SnapDragon 8cx Gen 3 */ + { + .soc_model = SC8280X, + .htp_arch = V68, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8cx Gen 3"}, + + /* Qualcomm SnapDragon 8cx Gen 4 */ + { + .soc_model = SC8380XP, + .htp_arch = V73, + .vtcm_size_in_mb = 8, + .soc_desc = "Qualcomm SnapDragon 8cx Gen 4"}, +#endif + +}; + +// file:///opt/qcom/aistack/qairt/2.31.0.250130/docs/QNN/general/quantization.html +// CPU - Choose a non-quantized model.Quantized models are currently incompatible with the CPU backend +// GPU - Choose a non-quantized model.Quantized models are currently incompatible with the GPU backend +// HTP - Choose a quantized model. Quantized models are required when running on the HTP backend +// DSP - Choose a quantized model. Quantized models are required when running on the DSP backend +// HTA - Choose a quantized model. Quantized models are required when running on the HTA backend +static struct ggml_backend_hexagon_context g_hexagon_mgr[GGML_HEXAGON_MAX_DEVICES] = { + { .device = 0, + .name = "qnn-cpu", + .desc = "Qualcomm Kryo CPU", +#if !defined(__ANDROID__) && !defined(__linux__) + .lib = "QnnCpu.dll", +#else + .lib = "libQnnCpu.so", +#endif + .instance = nullptr, + .backend = nullptr, + .raw_interface = {}, + .raw_system_interface = {}, + .socinfo = {}, + .qnn_singlenode_graph_map = {}, + .work_data = nullptr, + .tasks = {}, + .work_size = 0, + .desired_size = 0, + .n_threads = 8, + .rpc_mempool_capacity = 0, + .rpc_mempool_len = 0, + .rpc_mempool_usage = 0, + .rpc_mempool = nullptr, + .rpc_mempool_handle = 0, + .ggmlop_handle = 0, + .domain_id = -1, + }, + + { .device = 1, + .name = "qnn-gpu", + .desc = "Qualcomm Adreno GPU", +#if !defined(__ANDROID__) && !defined(__linux__) + .lib = "QnnGpu.dll", +#else + .lib = "libQnnGpu.so", +#endif + .instance = nullptr, + .backend = nullptr, + .raw_interface = {}, + .raw_system_interface = {}, + .socinfo = {}, + .qnn_singlenode_graph_map = {}, + .work_data = nullptr, + .tasks = {}, + .work_size = 0, + .desired_size = 0, + .n_threads = 8, + .rpc_mempool_capacity = 0, + .rpc_mempool_len = 0, + .rpc_mempool_usage = 0, + .rpc_mempool = nullptr, + .rpc_mempool_handle = 0, + .ggmlop_handle = 0, + .domain_id = -1, + }, + + { .device = 2, + .name = "qnn-npu", + .desc = "Qualcomm NPU(Hexagon Tensor Processor)", +#if !defined(__ANDROID__) && !defined(__linux__) + .lib = "QnnHtp.dll", +#else + .lib = "libQnnHtp.so", +#endif + .instance = nullptr, + .backend = nullptr, + .raw_interface = {}, + .raw_system_interface = {}, + .socinfo = {}, + .qnn_singlenode_graph_map = {}, + .work_data = nullptr, + .tasks = {}, + .work_size = 0, + .desired_size = 0, + .n_threads = 8, + .rpc_mempool_capacity = 0, + .rpc_mempool_len = 0, + .rpc_mempool_usage = 0, + .rpc_mempool = nullptr, + .rpc_mempool_handle = 0, + .ggmlop_handle = 0, + .domain_id = -1, + }, + { .device = 3, + .name = "Hexagon-cDSP", + .desc = "Qualcomm NPU(cDSP)", + .lib = "", + .instance = nullptr, + .backend = nullptr, + .raw_interface = {}, + .raw_system_interface = {}, + .socinfo = {}, + .qnn_singlenode_graph_map = {}, + .work_data = nullptr, + .tasks = {}, + .work_size = 0, + .desired_size = 0, + .n_threads = 8, + .rpc_mempool_capacity = 0, + .rpc_mempool_len = 0, + .rpc_mempool_usage = 0, + .rpc_mempool = nullptr, + .rpc_mempool_handle = 0, + .ggmlop_handle = 0, + .domain_id = HEXAGON_CDSP, + }, +}; + +static domain hexagon_supported_domains[] = { + {ADSP_DOMAIN_ID, ADSP_DOMAIN}, + {MDSP_DOMAIN_ID, MDSP_DOMAIN}, + {SDSP_DOMAIN_ID, SDSP_DOMAIN}, + {CDSP_DOMAIN_ID, CDSP_DOMAIN}, + {CDSP1_DOMAIN_ID, CDSP1_DOMAIN} +}; + +//supported ggml op by HWACCEL_QNN +static constexpr const qnn_op_caps ggmlqnn_k_op_caps[] = { + {true, GGML_OP_NONE, 0, nullptr}, + {false, GGML_OP_DUP, 0, nullptr}, + {true, GGML_OP_ADD, 2, QNN_OP_ELEMENT_WISE_ADD}, + {false, GGML_OP_ADD1, 0, nullptr}, + {false, GGML_OP_ACC, 0, nullptr}, + {true, GGML_OP_SUB, 2, QNN_OP_ELEMENT_WISE_SUBTRACT}, + {true, GGML_OP_MUL, 2, QNN_OP_ELEMENT_WISE_MULTIPLY}, + {true, GGML_OP_DIV, 2, QNN_OP_ELEMENT_WISE_DIVIDE}, + {false, GGML_OP_SQR, 0, nullptr}, + {true, GGML_OP_SQRT, 1, QNN_OP_ELEMENT_WISE_SQUARE_ROOT}, + {true, GGML_OP_LOG, 1, QNN_OP_ELEMENT_WISE_LOG}, + {false, GGML_OP_SIN, 0, nullptr}, + {false, GGML_OP_COS, 0, nullptr}, + {false, GGML_OP_SUM, 0, nullptr}, + {false, GGML_OP_SUM_ROWS, 0, nullptr}, + {false, GGML_OP_MEAN, 0, nullptr}, + {false, GGML_OP_ARGMAX, 0, nullptr}, + {false, GGML_OP_COUNT_EQUAL, 0, nullptr}, + {false, GGML_OP_REPEAT, 0, nullptr}, + {false, GGML_OP_REPEAT_BACK, 0, nullptr}, + {false, GGML_OP_CONCAT, 0, nullptr}, + {false, GGML_OP_SILU_BACK, 0, nullptr}, + {false, GGML_OP_NORM, 0, nullptr}, + {false, GGML_OP_RMS_NORM, 0, nullptr}, + {false, GGML_OP_RMS_NORM_BACK, 0, nullptr}, + {false, GGML_OP_GROUP_NORM, 0, nullptr}, + {false, GGML_OP_L2_NORM, 0, nullptr}, + {true, GGML_OP_MUL_MAT, 2, QNN_OP_MAT_MUL}, + {false, GGML_OP_MUL_MAT_ID, 0, nullptr}, + {false, GGML_OP_OUT_PROD, 0, nullptr}, + {false, GGML_OP_SCALE, 0, nullptr}, + {false, GGML_OP_SET, 0, nullptr}, + {false, GGML_OP_CPY, 0, nullptr}, + {false, GGML_OP_CONT, 0, nullptr}, + {false, GGML_OP_RESHAPE, 0, nullptr}, + {false, GGML_OP_VIEW, 0, nullptr}, + {false, GGML_OP_PERMUTE, 0, nullptr}, + {false, GGML_OP_TRANSPOSE, 0, nullptr}, + {false, GGML_OP_GET_ROWS, 0, nullptr}, + {false, GGML_OP_GET_ROWS_BACK, 0, nullptr}, + {false, GGML_OP_DIAG, 0, nullptr}, + {false, GGML_OP_DIAG_MASK_INF, 0, nullptr}, + {false, GGML_OP_DIAG_MASK_ZERO, 0, nullptr}, + {false, GGML_OP_SOFT_MAX, 0, nullptr}, + {false, GGML_OP_SOFT_MAX_BACK, 0, nullptr}, + {false, GGML_OP_ROPE, 0, nullptr}, + {false, GGML_OP_ROPE_BACK, 0, nullptr}, + {false, GGML_OP_CLAMP, 0, nullptr}, + {false, GGML_OP_CONV_TRANSPOSE_1D, 0, nullptr}, + {false, GGML_OP_IM2COL, 0, nullptr}, + {false, GGML_OP_IM2COL_BACK, 0, nullptr}, + {false, GGML_OP_CONV_2D_DW, 0, nullptr}, + {false, GGML_OP_CONV_TRANSPOSE_2D, 0, nullptr}, + {false, GGML_OP_POOL_1D, 0, nullptr}, + {false, GGML_OP_POOL_2D, 0, nullptr}, + {false, GGML_OP_POOL_2D_BACK, 0, nullptr}, + {false, GGML_OP_UPSCALE, 0, nullptr}, + {false, GGML_OP_PAD, 0, nullptr}, + {false, GGML_OP_PAD_REFLECT_1D, 0, nullptr}, + {false, GGML_OP_ARANGE, 0, nullptr}, + {false, GGML_OP_TIMESTEP_EMBEDDING, 0, nullptr}, + {false, GGML_OP_ARGSORT, 0, nullptr}, + {false, GGML_OP_LEAKY_RELU, 0, nullptr}, + {false, GGML_OP_FLASH_ATTN_EXT, 0, nullptr}, + {false, GGML_OP_FLASH_ATTN_BACK, 0, nullptr}, + {false, GGML_OP_SSM_CONV, 0, nullptr}, + {false, GGML_OP_SSM_SCAN, 0, nullptr}, + {false, GGML_OP_WIN_PART, 0, nullptr}, + {false, GGML_OP_WIN_UNPART, 0, nullptr}, + {false, GGML_OP_GET_REL_POS, 0, nullptr}, + {false, GGML_OP_ADD_REL_POS, 0, nullptr}, + {false, GGML_OP_RWKV_WKV6, 0, nullptr}, + {false, GGML_OP_GATED_LINEAR_ATTN, 0, nullptr}, + {false, GGML_OP_RWKV_WKV7, 0, nullptr}, + {false, GGML_OP_UNARY, 0, nullptr}, + {false, GGML_OP_MAP_CUSTOM1, 0, nullptr}, + {false, GGML_OP_MAP_CUSTOM2, 0, nullptr}, + {false, GGML_OP_MAP_CUSTOM3, 0, nullptr}, + {false, GGML_OP_CUSTOM, 0, nullptr}, + {false, GGML_OP_CROSS_ENTROPY_LOSS, 0, nullptr}, + {false, GGML_OP_CROSS_ENTROPY_LOSS_BACK, 0, nullptr}, + {false, GGML_OP_OPT_STEP_ADAMW, 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_ABS), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_SGN), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_NEG), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_STEP), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_TANH), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_ELU), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_RELU), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_SIGMOID), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU_ERF), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU_QUICK), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_SILU), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_HARDSWISH), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_HARDSIGMOID), 0, nullptr}, + {false, static_cast(GGML_UNARY_OP_EXP), 0, nullptr} +}; + +static_assert(ggmlqnn_k_op_caps[GGML_OP_NONE].supported, "GGML_OP_NONE is not true"); +static_assert(ggmlqnn_k_op_caps[GGML_OP_ADD].supported, "GGML_OP_ADD is not true"); +static_assert(ggmlqnn_k_op_caps[GGML_OP_MUL].supported, "GGML_OP_MUL is not true"); +static_assert(ggmlqnn_k_op_caps[GGML_OP_MUL_MAT].supported, "GGML_OP_MUL_MAT is not true"); +static_assert(std::size(ggmlqnn_k_op_caps) == (static_cast(GGML_OP_COUNT) + static_cast(GGML_UNARY_OP_COUNT)), + "pls check ggmlqnn_k_op_caps and ensure is corresponding to latest ggml.h"); + +//supported ggml op by HWACCEL_CDSP +static constexpr const hexagon_op_caps ggmlhexagon_k_op_caps[] = { + {true, GGML_OP_NONE, 0, nullptr, nullptr}, + {false, GGML_OP_DUP, 0, nullptr, nullptr}, + {true, GGML_OP_ADD, 2, "ggmlop_dsp_add", ggmlop_dsp_add}, + {false, GGML_OP_ADD1, 0, nullptr, nullptr}, + {false, GGML_OP_ACC, 0, nullptr, nullptr}, + {false, GGML_OP_SUB, 2, nullptr, nullptr}, + {false, GGML_OP_MUL, 2, nullptr, nullptr}, + {false, GGML_OP_DIV, 2, nullptr, nullptr}, + {false, GGML_OP_SQR, 0, nullptr, nullptr}, + {false, GGML_OP_SQRT, 0, nullptr, nullptr}, + {false, GGML_OP_LOG, 0, nullptr, nullptr}, + {false, GGML_OP_SIN, 0, nullptr, nullptr}, + {false, GGML_OP_COS, 0, nullptr, nullptr}, + {false, GGML_OP_SUM, 0, nullptr, nullptr}, + {false, GGML_OP_SUM_ROWS, 0, nullptr, nullptr}, + {false, GGML_OP_MEAN, 0, nullptr, nullptr}, + {false, GGML_OP_ARGMAX, 0, nullptr, nullptr}, + {false, GGML_OP_COUNT_EQUAL, 0, nullptr, nullptr}, + {false, GGML_OP_REPEAT, 0, nullptr, nullptr}, + {false, GGML_OP_REPEAT_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_CONCAT, 0, nullptr, nullptr}, + {false, GGML_OP_SILU_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_NORM, 0, nullptr, nullptr}, + {true, GGML_OP_RMS_NORM, 1, "ggmlop_dsp_rmsnorm", ggmlop_dsp_rmsnorm}, + {false, GGML_OP_RMS_NORM_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_GROUP_NORM, 0, nullptr, nullptr}, + {false, GGML_OP_L2_NORM, 0, nullptr, nullptr}, + {true, GGML_OP_MUL_MAT, 2, "ggmlop_dsp_mulmat", ggmlop_dsp_mulmat}, + {false, GGML_OP_MUL_MAT_ID, 0, nullptr, nullptr}, + {false, GGML_OP_OUT_PROD, 0, nullptr, nullptr}, + {false, GGML_OP_SCALE, 0, nullptr, nullptr}, + {false, GGML_OP_SET, 0, nullptr, nullptr}, + {false, GGML_OP_CPY, 0, nullptr, nullptr}, + {false, GGML_OP_CONT, 0, nullptr, nullptr}, + {false, GGML_OP_RESHAPE, 0, nullptr, nullptr}, + {false, GGML_OP_VIEW, 0, nullptr, nullptr}, + {false, GGML_OP_PERMUTE, 0, nullptr, nullptr}, + {false, GGML_OP_TRANSPOSE, 0, nullptr, nullptr}, + {false, GGML_OP_GET_ROWS, 0, nullptr, nullptr}, + {false, GGML_OP_GET_ROWS_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_DIAG, 0, nullptr, nullptr}, + {false, GGML_OP_DIAG_MASK_INF, 0, nullptr, nullptr}, + {false, GGML_OP_DIAG_MASK_ZERO, 0, nullptr, nullptr}, + {true, GGML_OP_SOFT_MAX, 1, "ggmlop_dsp_softmax", ggmlop_dsp_softmax}, + {false, GGML_OP_SOFT_MAX_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_ROPE, 0, nullptr, nullptr}, + {false, GGML_OP_ROPE_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_CLAMP, 0, nullptr, nullptr}, + {false, GGML_OP_CONV_TRANSPOSE_1D, 0, nullptr, nullptr}, + {false, GGML_OP_IM2COL, 0, nullptr, nullptr}, + {false, GGML_OP_IM2COL_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_CONV_2D_DW, 0, nullptr, nullptr}, + {false, GGML_OP_CONV_TRANSPOSE_2D, 0, nullptr, nullptr}, + {false, GGML_OP_POOL_1D, 0, nullptr, nullptr}, + {true, GGML_OP_POOL_2D, 1, "ggmlop_dsp_pool2d", ggmlop_dsp_pool2d}, + {false, GGML_OP_POOL_2D_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_UPSCALE, 0, nullptr, nullptr}, + {false, GGML_OP_PAD, 0, nullptr, nullptr}, + {false, GGML_OP_PAD_REFLECT_1D, 0, nullptr, nullptr}, + {false, GGML_OP_ARANGE, 0, nullptr, nullptr}, + {false, GGML_OP_TIMESTEP_EMBEDDING, 0, nullptr, nullptr}, + {false, GGML_OP_ARGSORT, 0, nullptr, nullptr}, + {false, GGML_OP_LEAKY_RELU, 0, nullptr, nullptr}, + {false, GGML_OP_FLASH_ATTN_EXT, 0, nullptr, nullptr}, + {false, GGML_OP_FLASH_ATTN_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_SSM_CONV, 0, nullptr, nullptr}, + {false, GGML_OP_SSM_SCAN, 0, nullptr, nullptr}, + {false, GGML_OP_WIN_PART, 0, nullptr, nullptr}, + {false, GGML_OP_WIN_UNPART, 0, nullptr, nullptr}, + {false, GGML_OP_GET_REL_POS, 0, nullptr, nullptr}, + {false, GGML_OP_ADD_REL_POS, 0, nullptr, nullptr}, + {false, GGML_OP_RWKV_WKV6, 0, nullptr, nullptr}, + {false, GGML_OP_GATED_LINEAR_ATTN, 0, nullptr, nullptr}, + {false, GGML_OP_RWKV_WKV7, 0, nullptr, nullptr}, + {false, GGML_OP_UNARY, 0, nullptr, nullptr}, + {false, GGML_OP_MAP_CUSTOM1, 0, nullptr, nullptr}, + {false, GGML_OP_MAP_CUSTOM2, 0, nullptr, nullptr}, + {false, GGML_OP_MAP_CUSTOM3, 0, nullptr, nullptr}, + {false, GGML_OP_CUSTOM, 0, nullptr, nullptr}, + {false, GGML_OP_CROSS_ENTROPY_LOSS, 0, nullptr, nullptr}, + {false, GGML_OP_CROSS_ENTROPY_LOSS_BACK, 0, nullptr, nullptr}, + {false, GGML_OP_OPT_STEP_ADAMW, 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_ABS), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_SGN), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_NEG), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_STEP), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_TANH), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_ELU), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_RELU), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_SIGMOID), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU_ERF), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_GELU_QUICK), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_SILU), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_HARDSWISH), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_HARDSIGMOID), 0, nullptr, nullptr}, + {false, static_cast(GGML_UNARY_OP_EXP), 0, nullptr, nullptr} +}; + +static_assert(ggmlhexagon_k_op_caps[GGML_OP_NONE].supported, "GGML_OP_NONE is not true"); +static_assert(ggmlhexagon_k_op_caps[GGML_OP_ADD].supported, "GGML_OP_ADD is not true"); +static_assert(ggmlhexagon_k_op_caps[GGML_OP_MUL_MAT].supported, "GGML_OP_MUL_MAT is not true"); +static_assert(ggmlhexagon_k_op_caps[GGML_OP_SOFT_MAX].supported, "GGML_OP_SOFT_MAX is not true"); +static_assert(std::size(ggmlhexagon_k_op_caps) == (static_cast(GGML_OP_COUNT) + static_cast(GGML_UNARY_OP_COUNT)), + "pls check ggmlhexagon_k_op_caps and ensure is corresponding to latest ggml.h"); + +static int32_t g_qnntensor_idx = 0; //ensure every QNN tensor name is unique +static int32_t g_qnnopcfg_idx = 0; //ensure every QNN opconfig name is unique + +// ================================================================================================= +// section-2: ggml-hexagon internal troubleshooting and profiler function/class +// ================================================================================================= +static const char * ggmlhexagon_get_hwaccel_approach_name(int hwaccle_approach) { + switch (hwaccle_approach) { + case HWACCEL_QNN: + return "HWACCEL_QNN"; + case HWACCEL_QNN_SINGLEGRAPH: + return "HWACCEL_QNN_SINGLEGRAPH"; + case HWACCEL_CDSP: + return "HWACCEL_CDSP"; + default: + return "unknown hwaccel approach"; + } +} + +static void ggmlhexagon_get_timestring(char * p_currenttime) { + if (nullptr == p_currenttime) + return; + + auto time_to_string = [](const std::chrono::system_clock::time_point & tp)->std::string { + auto as_time_t = std::chrono::system_clock::to_time_t(tp); + struct tm tm; + + localtime_r(&as_time_t, &tm); + + std::chrono::milliseconds ms = std::chrono::duration_cast(tp.time_since_epoch()); + char buf[GGMLHEXAGON_TMPBUF_LEN]; + memset(buf, 0, GGMLHEXAGON_TMPBUF_LEN); + snprintf(buf, sizeof(buf), "%04d-%02d-%02d,%02d:%02d:%02d", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + GGML_UNUSED(ms); + return buf; + }; + + std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); + snprintf(p_currenttime, GGMLHEXAGON_TMPBUF_LEN, "%s", time_to_string(tp).c_str()); +} + +static void ggmlhexagon_log_internal(ggml_log_level level, const char * file, const char * func, int line, const char * format, ...) { + static std::mutex ggmlhexagon_log_internal_mutex; + static char s_ggmlhexagon_log_internal_buf[GGMLHEXAGON_LOGBUF_LEN]; + + GGML_UNUSED(file); +#if !(defined __ANDROID__) || !(defined ANDROID) + GGML_UNUSED(level); +#endif + { + std::lock_guard lock(ggmlhexagon_log_internal_mutex); + va_list args; + va_start(args, format); + int len_prefix = snprintf(s_ggmlhexagon_log_internal_buf, GGMLHEXAGON_LOGBUF_LEN, "[%s, %d]: ", func, line); + int len = vsnprintf(s_ggmlhexagon_log_internal_buf + len_prefix, GGMLHEXAGON_LOGBUF_LEN - len_prefix, format, args); + if (len < (GGMLHEXAGON_LOGBUF_LEN - len_prefix)) { +#if (defined __ANDROID__) || (defined ANDROID) + __android_log_print(ANDROID_LOG_INFO, PROJECT_NAME, "%s\n", s_ggmlhexagon_log_internal_buf); + if (GGML_LOG_LEVEL_INFO == level) { + printf("%s\n", s_ggmlhexagon_log_internal_buf); + } +#else + //for Snapdragon based WoA(Windows on ARM) device or Linux + printf("%s\n", s_ggmlhexagon_log_internal_buf); +#endif + } + va_end(args); + } +} + +static void ggmlhexagon_print_tensors_info(const char * func_name, const ggml_backend_hexagon_context * ctx, + const ggml_tensor * src0, const ggml_tensor * src1, const ggml_tensor * dst) { + //skip sanity check of params because of performance concern + if (0 == g_hexagon_appcfg.dump_op_info) { + if (0 == g_hexagon_appcfg.print_tensors_info) + return; + } + + if (nullptr != func_name && nullptr != ctx) { + GGMLHEXAGON_LOG_DEBUG("call %s in dev %s\n", func_name, ctx->name); + } + if (nullptr != src0) { + GGMLHEXAGON_LOG_DEBUG( + "%-6s: type = %i (%s) ne = %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 ", nb = (%5zi, %5zi, %5zi, %5zi)", + src0->name, + src0->type, ggml_type_name(src0->type), src0->ne[0], src0->ne[1], src0->ne[2], + src0->ne[3], + src0->nb[0], src0->nb[1], src0->nb[2], src0->nb[3]); + } + if (nullptr != src1) { + GGMLHEXAGON_LOG_DEBUG( + "%-6s: type = %i (%s) ne = %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 ", nb = (%5zi, %5zi, %5zi, %5zi)", + src1->name, + src1->type, ggml_type_name(src1->type), src1->ne[0], src1->ne[1], src1->ne[2], + src1->ne[3], + src1->nb[0], src1->nb[1], src1->nb[2], src1->nb[3]); + } + GGMLHEXAGON_LOG_DEBUG("%-6s: type = %i (%s) ne = %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 ", nb = (%5zi, %5zi, %5zi, %5zi)", + dst->name, + dst->type, ggml_type_name(dst->type), dst->ne[0], dst->ne[1], dst->ne[2], dst->ne[3], + dst->nb[0], dst->nb[1], dst->nb[2], dst->nb[3]); + GGMLHEXAGON_LOG_DEBUG("\n"); +} + +static void ggmlhexagon_dump_op_info(const struct ggml_tensor * tensor) { + //skip sanity check of params because of performance concern + if (0 == g_hexagon_appcfg.dump_op_info) + return; + + const struct ggml_tensor * src0 = tensor->src[0]; + struct ggml_tensor * src1 = tensor->src[1]; + struct ggml_tensor * dst = const_cast(tensor); + GGMLHEXAGON_LOG_DEBUG("op name:%s, tensor type:%s", ggml_op_name(tensor->op), ggml_type_name(tensor->type)); + ggmlhexagon_print_tensors_info(nullptr, nullptr, src0, src1, dst); +} + +static void ggmlhexagon_dump_tensor_elements(const ggml_tensor * tensor) { + float value = 0; + std::ostringstream tmposs; + if (tensor->type == GGML_TYPE_F32) { + for (int h = 0; h < tensor->ne[3]; h++) { + for (int i = 0; i < tensor->ne[2]; i++) { + for (int j = 0; j < tensor->ne[1]; j++) { + for (int k = 0; k < tensor->ne[0]; k++) { + value = ((float *) tensor->data)[h * tensor->ne[2] + i * tensor->ne[1] + + j * tensor->ne[0] + k]; + tmposs << std::setw(8) << std::fixed << std::setprecision(2) << value + << " "; + } + if (strlen(tmposs.str().c_str()) <= (GGMLHEXAGON_LOGBUF_LEN - 96)) { + GGMLHEXAGON_LOG_DEBUG("%s\n", tmposs.str().c_str()); + } + tmposs.clear(); + tmposs.str(""); + } + } + } + } + + GGMLHEXAGON_LOG_DEBUG("\n"); +} + +static void ggmlhexagon_dump_tensor(const ggml_tensor * tensor, const char * name) { + GGMLHEXAGON_LOG_DEBUG("dump ggml tensor %s(%s)\n", name, tensor->name); + GGMLHEXAGON_LOG_DEBUG("%15s: type = %i (%5s) ne = %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64", nb = (%5zi, %5zi, %5zi, %5zi)\n", + name, + tensor->type, ggml_type_name(tensor->type), + tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3], + tensor->nb[0], tensor->nb[1], tensor->nb[2], tensor->nb[2]); + ggmlhexagon_dump_tensor_elements(tensor); + + GGMLHEXAGON_LOG_DEBUG("\n"); +} + +//a simple high-cohesion and low-coupling class to collect necessary profiler data and visualize NPU performance accordingly +class hexagon_profiler { +public: + static hexagon_profiler & get_instance() { + //make thread-safety without using complex dynamic resource management + static hexagon_profiler instance; + return instance; + } + +public: + void profiler_init(int profiler_threshold_duration, int profiler_threshold_counts) { + reset(); + //here is not accurate profiler start time because inference wasn't launched at the moment + _profiler_starttime = ggml_time_us(); + + _profiler_threshold_duration = profiler_threshold_duration; + _profiler_threshold_counts = profiler_threshold_counts; + + std::string filename = std::string(g_hexagon_appcfg.runtime_libpath) + "/"; + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + if (g_hexagon_appcfg.thread_counts > 1) { + //multi-threading feature enabled on cDSP side + if (0 == g_hexagon_appcfg.enable_rpc_ion_mempool) { + filename = filename + "hexagon_perf_cdsp_mt.dat"; + } else { + filename = filename + "hexagon_perf_cdsp_ion_mt.dat"; + } + } else { + if (0 == g_hexagon_appcfg.enable_rpc_ion_mempool) { + filename = filename + "hexagon_perf_cdsp.dat"; + } else { + filename = filename + "hexagon_perf_cdsp_ion.dat"; + } + } + } else { + filename = filename + "hexagon_perf_qnn.dat"; + } + GGMLHEXAGON_LOG_DEBUG("profiler name:%s", filename.c_str()); + const char * profiler_filename = filename.c_str(); + _fp_profile_file = fopen(profiler_filename, "w"); + if (nullptr == _fp_profile_file) { + GGMLHEXAGON_LOG_WARN("can't open profiler file %s, reason:%s", profiler_filename, strerror(errno)); + reset(); + return; + } else { + size_t written_size = 0; + char profiler_info[GGMLHEXAGON_TMPBUF_LEN]; + const char * prefix = "### starting hexagon profiler at "; + + written_size = fwrite(prefix, 1, strlen(prefix), _fp_profile_file); + if (written_size != strlen(prefix)) { + GGMLHEXAGON_LOG_WARN("write data to file %s failed, reason: %s", profiler_filename, strerror(errno)); + profiler_deinit(); + return; + } + + memset(profiler_info, 0, GGMLHEXAGON_TMPBUF_LEN); + ggmlhexagon_get_timestring(profiler_info); + written_size = fwrite(profiler_info, 1, strlen(profiler_info), _fp_profile_file); + if (written_size != strlen(profiler_info)) { + GGMLHEXAGON_LOG_WARN("write data to file %s failed, reason: %s", profiler_filename, strerror(errno)); + profiler_deinit(); + return; + } + fprintf(_fp_profile_file, "\n\n"); + fprintf(_fp_profile_file, + "#frame input max total avg elapse frame max total avg\n"); + fprintf(_fp_profile_file, + "# inference inference inference inference\n"); + fprintf(_fp_profile_file, + "#index len i-len i-len i-speed time time time time time\n"); + fprintf(_fp_profile_file, "\n\n"); + } + _enable_profiler = true; + } + + void profiler_deinit() { + if (nullptr != _fp_profile_file) { + fclose(_fp_profile_file); + _fp_profile_file = nullptr; + } + reset(); + } + +/** + * \param inference_time microseconds, inference time for a single GGML op + * \param inference_input_size bytes, total input data size for a single GGML op + * \param inference_output_size bytes, total output data size for a single GGML op + */ + void profiler_update_profilerdata(const char * ggml_opname, int inference_time, int inference_input_size, int inference_output_size) { + if (!_enable_profiler) + return; + + //1.get the accurate profiler starting time in this function when frame index is 0 + //2.update frame index in this function accordingly + profiler_update_frameindex(); + + int64_t elapse_time = ggml_time_us() - profiler_get_starttime(); + profiler_update_elapsetime(elapse_time); + if (elapse_time > (_profiler_threshold_duration * SIZE_IN_MB)) { + //do nothing when elapsed profiler time > profiler_duration in ggml-hexagon.cfg + return; + } + if (profiler_get_frame_index() >= _profiler_threshold_counts) { + //do nothing when frame_index >= profiler_counts in ggml-hexagon.cfg + return; + } + + if (inference_input_size > profiler_get_max_inputsize()) { + profiler_set_max_inputsize(inference_input_size); + } + + if (inference_output_size > profiler_get_max_outputsize()) { + profiler_set_max_outputsize(inference_output_size); + } + + if (inference_time > profiler_get_max_inferencetime()) { + profiler_set_max_inferencetime(inference_time); + } + + profiler_update_total_inputsize(inference_input_size); + profiler_update_total_outputsize(inference_output_size); + profiler_update_total_inferencetime(inference_time); + profiler_update_elapsetime(elapse_time); + + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + if (10 > _frame_index) { + //FIXME:why some initial profiler data in llama-cli looks unusual + //return; + } + } + + if (0 == elapse_time) { + //filter invalid profiler data + return; + } + + if (NULL != _fp_profile_file) { + fprintf(_fp_profile_file, "%-8d %-6d %-6d %-10ld %-11ld %-10ld %-12d %-9d %-11ld %-3ld\n", + profiler_get_frame_index(), + inference_input_size, + profiler_get_max_inputsize(), + profiler_get_total_inputputsize(), + profiler_get_total_inputputsize() / profiler_get_frame_index(), + + elapse_time, + inference_time, + profiler_get_max_inferencetime(), + profiler_get_total_inferencetime(), + profiler_get_total_inferencetime() / profiler_get_frame_index() + ); + } + + //print/compare NPU's I/O performance between 8Gen3 and 8Elite(aka 8Gen4) , removed in the future + char bps_string[GGMLHEXAGON_TMPBUF_LEN]; + memset(bps_string, 0, GGMLHEXAGON_TMPBUF_LEN); + profiler_get_bpsstring(_total_inputsize + _total_outputsize, elapse_time, bps_string); + GGMLHEXAGON_LOG_VERBOSE("I/O performance:%s", bps_string); + } + + int profiler_get_frame_index() { + return _frame_index; + } + + int profiler_get_threshold_count() { + return _profiler_threshold_counts; + } + +private: + void profiler_set_max_inputsize(int input_size) { + _max_inputsize = input_size; + } + + void profiler_set_max_outputsize(int output_size) { + _max_outputsize = output_size; + } + + void profiler_set_max_inferencetime(int inference_time) { + _max_inferencetime = inference_time; + } + + void profiler_update_frameindex() { + if (0 == _frame_index) { + _profiler_starttime = ggml_time_us(); + } + _frame_index += 1; + } + + void profiler_update_elapsetime(int64_t elapse_time_microseconds) { + _profiler_elapsetime = elapse_time_microseconds; + } + + void profiler_update_total_inferencetime(int inference_time) { + _total_inferencetime += inference_time; + } + + void profiler_update_total_inputsize(int input_size) { + _total_inputsize += input_size; + } + + void profiler_update_total_outputsize(int output_size) { + _total_outputsize += output_size; + } + + int profiler_get_max_inputsize() { + return _max_inputsize; + } + + int profiler_get_max_outputsize() { + return _max_outputsize; + } + + int profiler_get_max_inferencetime() { + return _max_inferencetime; + } + + int64_t profiler_get_total_inferencetime() { + return _total_inferencetime; + } + + int64_t profiler_get_total_inputputsize() { + return _total_inputsize; + } + + //might-be used to calculate total I/O performance in the future + int64_t profiler_get_total_outputsize() { + return _total_outputsize; + } + + int64_t profiler_get_starttime() { + return _profiler_starttime; + } + + int64_t profiler_get_elapsedtime() { + return _profiler_elapsetime; + } + + void profiler_get_bpsstring(int64_t data_size, int64_t elapse_time_microseconds, char * bps_string) { + if (nullptr == bps_string) { + return; + } + + float bps = 0.0f; + bps = (data_size * SIZE_IN_MB * 1.0f) / (elapse_time_microseconds * 1.0f); + if (bps >= SIZE_IN_MB) { + snprintf(bps_string, GGMLHEXAGON_TMPBUF_LEN, "%.2f MiB/s", ((float) bps) / SIZE_IN_MB); + } else if (bps >= 1000) { + snprintf(bps_string, GGMLHEXAGON_TMPBUF_LEN, "%.1f KiB/s", ((float) bps) / 1000); + } else { + snprintf(bps_string, GGMLHEXAGON_TMPBUF_LEN, "%.2f B/s", bps); + } + } + + void reset() { + _frame_index = 0; + + _max_inputsize = 0; + _max_outputsize = 0; + _max_inferencetime = 0; + + _total_inputsize = 0; + _total_outputsize = 0; + _total_inferencetime = 0; + + _profiler_starttime = 0; + _profiler_elapsetime = 0; + _fp_profile_file = nullptr; + _enable_profiler = false; + _profiler_threshold_duration = 100; + _profiler_threshold_duration = 5; + } + +private: + hexagon_profiler() { + reset(); + } + + hexagon_profiler(const hexagon_profiler &) = delete; + + hexagon_profiler(const hexagon_profiler &&) = delete; + + hexagon_profiler & operator= (const hexagon_profiler &) = delete; + +private: + int _frame_index; + + int _max_inputsize; //bytes + int _max_outputsize; //bytes + int _max_inferencetime; //bytes + + int64_t _total_inputsize; //bytes + int64_t _total_outputsize; //bytes + int64_t _total_inferencetime; //microsecond + + int64_t _profiler_starttime; //microsecond + int64_t _profiler_elapsetime; //microsecond + FILE * _fp_profile_file; + + bool _enable_profiler; + int _profiler_threshold_duration; //seconds + int _profiler_threshold_counts; +}; +static hexagon_profiler & g_hexagon_profiler = hexagon_profiler::get_instance(); + +//a simple perf class to probe NPU performance +class hexagon_perf { +public: + hexagon_perf(const std::string & perf_name) : _perf_name(std::move(perf_name)) {} + hexagon_perf(const std::string & perf_name, const char * op_name, int input_size, int output_size) + : _perf_name(std::move(perf_name)), _op_name(op_name), + _input_size(input_size), + _output_size(output_size) { + + } + + void start() { + if (0 == g_hexagon_appcfg.enable_perf) + return; + _begin_time = ggml_time_us(); + } + + void info() { + if (0 == g_hexagon_appcfg.enable_perf) { + return; + } + + _end_time = ggml_time_us(); + _duration = (_end_time - _begin_time); + //add following judgement will useful for other developers and AI experts although: + // it breaks the original logic + // it's not mandatory + // had to expose two public function in hexagon_profiler class + if (g_hexagon_profiler.profiler_get_frame_index() <= g_hexagon_profiler.profiler_get_threshold_count()) { + GGMLHEXAGON_LOG_VERBOSE("inference duration of %s through %s: %lld microseconds", + _perf_name.c_str(), ggmlhexagon_get_hwaccel_approach_name(g_hexagon_appcfg.hwaccel_approach), _duration); + } + + //update profiler data + g_hexagon_profiler.profiler_update_profilerdata(_op_name, _duration, _input_size, _output_size); + } + +private: + hexagon_perf() = delete; + hexagon_perf(const hexagon_perf & ) = delete; + hexagon_perf(const hexagon_perf && ) = delete; + hexagon_perf & operator= (const hexagon_perf & ) = delete; + +private: + int64_t _begin_time = 0LL; + int64_t _end_time = 0LL; + int64_t _duration = 0LL; + std::string _perf_name; + const char * _op_name; + int _input_size = 0; + int _output_size = 0; +}; + +//a simple class to load configurations from ggml-hexagon.cfg +class hexagon_appcfg { +public: + hexagon_appcfg() {} + + void dump(std::function worker) { + if (!_load_success) { + GGMLHEXAGON_LOG_INFO("qnn cfg file %s not loaded", _cfg_filename.c_str()); + return; + } + auto iter = _hexagon_appcfg.begin(); + while (iter != _hexagon_appcfg.end()) { + auto kv_iter = iter->second.begin(); + while (kv_iter != iter->second.end()) { + worker(iter->first, kv_iter->first, kv_iter->second); + ++kv_iter; + } + ++iter; + } + } + + bool load(const std::string & file_name) { + if (file_name == "") { + return false; + } + _cfg_filename = file_name; + std::ifstream in; + std::string line; + in.open(file_name.c_str()); + if (not in.is_open()) { + GGMLHEXAGON_LOG_WARN("can't open file %s", file_name.c_str()); + return false; + } + while (getline(in, line)) { + std::string section, key, value; + if (not parse_line(line, section, key, value)) { + continue; + } + set_section_keyvalue(section, key, value); + } + _load_success = true; + return true; + } + + void get_stringvalue(const std::string & section, const std::string & key, std::string & value, std::string default_value) { + value = default_value; + if (_hexagon_appcfg.find(section) == _hexagon_appcfg.end()) { + return; + } + if (_hexagon_appcfg[section].find(key) == _hexagon_appcfg[section].end()) { + return; + } + value = _hexagon_appcfg[section][key]; + } + + void get_intvalue(const std::string & section, const std::string & key, int & value, int default_value) { + value = default_value; + if (_hexagon_appcfg.find(section) == _hexagon_appcfg.end()) { + return; + } + if (_hexagon_appcfg[section].find(key) == _hexagon_appcfg[section].end()) { + return; + } + value = atol(_hexagon_appcfg[section][key].c_str()); + } + +private: + void ltrim(std::string & str) { + if (str.empty()) return; + size_t len = 0; + const char * temp = str.c_str(); + while (*temp && isblank(*temp)) { + ++len; + ++temp; + } + if (len > 0) str.erase(0, len); + } + + void rtrim(std::string & str) { + if (str.empty()) return; + size_t len = str.length(); + size_t pos = len; + while (pos > 0) { + if (not isblank(str[pos - 1])) { + break; + } + --pos; + } + if (pos != len) str.erase(pos); + } + + void trim(std::string & str) { + ltrim(str); + rtrim(str); + } + + void set_section_keyvalue(std::string & section, std::string & key, std::string & value) { + if (_hexagon_appcfg.find(section) == _hexagon_appcfg.end()) { + std::unordered_map kv_map; + _hexagon_appcfg[section] = kv_map; + } + if (key != "" && value != "") _hexagon_appcfg[section][key] = value; + } + + bool parse_line(std::string & line, std::string & section, std::string & key, std::string & value) { + static std::string cur_section = ""; + std::string nodes[2] = {"#", ";"}; + for (int i = 0; i < 2; ++i) { + std::string::size_type pos = line.find(nodes[i]); + if (pos != std::string::npos) line.erase(pos); + } + trim(line); + if (line == "") return false; + if (line[0] == '[' && line[line.size() - 1] == ']') { + section = line.substr(1, line.size() - 2); + trim(section); + cur_section = section; + return false; + } + if (cur_section == "") return false; + bool is_key = true; + for (size_t i = 0; i < line.size(); ++i) { + if (line[i] == '=') { + is_key = false; + continue; + } + if (is_key) { + key += line[i]; + } else { + value += line[i]; + } + } + section = cur_section; + trim(key); + trim(value); + + //"1.00" -> 1.00 + if (value.front() == '"' && value.back() == '"') { + value.erase(0, 1); // erase the first character " + value.erase(value.size() - 1); // erase the last character " + } + + return true; + } + +private: + hexagon_appcfg(const hexagon_appcfg & ) = delete; + hexagon_appcfg(const hexagon_appcfg && ) = delete; + hexagon_appcfg & operator= (const hexagon_appcfg & ) = delete; + +private: + std::unordered_map> _hexagon_appcfg; + bool _load_success = false; + std::string _cfg_filename; +}; + +// ================================================================================================= +// section-3: helper function for WoA(Window on ARM) +// ================================================================================================= +#if !defined(__ANDROID__) && !defined(__linux__) +#define RTLD_GLOBAL 0x100 +#define RTLD_LOCAL 0x000 +#define RTLD_LAZY 0x000 +#define RTLD_NOW 0x001 +static void * dlopen(const char * filename, int flag); +static int dlclose(void * handle); +static void * dlsym(void* handle, const char* name); +static const char * dlerror(void); + +static const char * last_func = nullptr; +static long last_err; +static void * dlopen(const char * dll, int flags) { + HINSTANCE h = LoadLibraryA(dll); + GGML_UNUSED(flags); + if (h == NULL) { + last_err = GetLastError(); + last_func = "dlopen"; + } + return h; +} + +static int dlclose(void * h) { + if (!FreeLibrary((HINSTANCE)h)) { + last_err = GetLastError(); + last_func = "dlclose"; + return -1; + } + return 0; +} + +static void * dlsym(void * h, const char * name) { + FARPROC p = GetProcAddress((HINSTANCE)h, name); + if (!p) { + last_err = GetLastError(); + last_func = "dlsym"; + } + return (void*)(intptr_t)p; +} + +static const char * dlerror(void) { + static char str[512]; + if (!last_err) return nullptr; + + snprintf(str, 512, "%s error #%ld", last_func, last_err); + last_err = 0; + last_func = NULL; + + return str; +} +#endif + +// ================================================================================================= +// section-4: general helper function +// ================================================================================================= +static const char * ggmlhexagon_get_socmodel_desc(uint32_t soc_model) { + switch (soc_model) { + case SM7450: + return "SM7450"; + case SM8350: + return "SM8350"; + case SM8450: + return "SM8450"; + case SM8475: + return "SM8475"; + case SM8550: + return "SM8550"; + case SM8650: + return "SM8650"; + case SM8750: + return "SM8750"; + default: + return "unknown"; + } +} + +//0x68 -> 68, 0x69 -> 69, 0x73 -> 73, 0x75 -> 75, 0x79 -> 79 +static size_t ggmlhexagon_htparch_hex_to_decimal(size_t htp_arch) { + //naive algorithm + int a = htp_arch / 16; + int b = htp_arch % 16; + return a * 10 + b; +} + +static const char * ggmlhexagon_get_htparch_desc(size_t htp_arch) { + switch (htp_arch) { + case V68: + return "QCOM_HTP_V68"; + case V69: + return "QCOM_HTP_V69"; + case V73: + return "QCOM_HTP_V73"; + case V75: + return "QCOM_HTP_V75"; + case V79: + return "QCOM_HTP_V79"; + default: + return "unknown"; + } +} + +static struct qcom_socinfo * ggmlhexagon_get_socinfo_from_socmodel(uint32_t soc_model) { + size_t items = sizeof(g_qnn_soc_info_table) / sizeof(g_qnn_soc_info_table[0]); + for (size_t idx = 0; idx < items; idx++) { + if (soc_model == g_qnn_soc_info_table[idx].soc_model) { + return &g_qnn_soc_info_table[idx]; + } + } + return nullptr; +} + +static struct qcom_socinfo * ggmlhexagon_get_socinfo_from_socmodel(size_t htp_arch) { + size_t items = sizeof(g_qnn_soc_info_table) / sizeof(g_qnn_soc_info_table[0]); + for (size_t idx = 0; idx < items; idx++) { + if (htp_arch == g_qnn_soc_info_table[idx].htp_arch) { + return &g_qnn_soc_info_table[idx]; + } + } + return nullptr; +} + +static inline uint32_t ggmlqnn_get_tensor_data_size(const ggml_tensor * tensor) { + /* + size_t data_size = ggml_row_size(tensor->type, tensor->ne[0]); + size_t n_dims = ggml_get_tensor_rank(tensor); + for (int i = 1; i < n_dims; i++) { + data_size *= tensor->ne[i]; + } + + return data_size; + */ + return ggml_nbytes(tensor); +} + +static inline bool ggmlqnn_is_valid_params(ggml_backend_hexagon_context * ctx, const ggml_tensor * src0, + const ggml_tensor * src1, ggml_tensor * dst) { + if ((nullptr == ctx) || (nullptr == src0) || (nullptr == dst)) { + GGMLHEXAGON_LOG_WARN("invalid params\n"); + return false; + } + + qnn_instance * instance = ctx->instance; + if (nullptr == instance) { + GGMLHEXAGON_LOG_WARN("invalid params\n"); + return false; + } + + return true; +} + +static size_t ggmlhexagon_get_system_total_memory_in_bytes() { +#if defined(__ANDROID__) || defined(__linux__) + struct sysinfo info = {}; + if (0 == sysinfo(&info)) { + return (info.totalram + info.totalswap) * info.mem_unit; + } + size_t pages = (size_t)sysconf(_SC_PHYS_PAGES); + size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE); + + return pages * page_size; +#else + //TODO: Snapdragon based WoA(Windows on ARM) + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + if (GlobalMemoryStatusEx(&statex)) { + GGMLHEXAGON_LOG_INFO("total physical mem:%llu Mb", statex.ullTotalPhys >> 20); + GGMLHEXAGON_LOG_INFO("avail physical mem:%llu Mb", statex.ullAvailPhys >> 20); + return statex.ullTotalPhys; + } + return 0; +#endif +} + +static size_t ggmlhexagon_get_system_free_memory_in_bytes() { +#if defined(__ANDROID__) || defined(__linux__) + struct sysinfo info = {}; + if (0 == sysinfo(&info)) { + return (info.freeram + info.freeswap) * info.mem_unit; + } + size_t avail_pages = (size_t)sysconf(_SC_AVPHYS_PAGES); + size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE); + + return avail_pages * page_size; +#else + //TODO: Snapdragon based WoA(Windows on ARM) + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + if (GlobalMemoryStatusEx(&statex)) { + GGMLHEXAGON_LOG_INFO("total physical mem:%llu Mb", statex.ullTotalPhys >> 20); + GGMLHEXAGON_LOG_INFO("avail physical mem:%llu Mb", statex.ullAvailPhys >> 20); + return statex.ullAvailPhys; + } + return 0; +#endif +} + +static bool ggmlhexagon_same_types(const ggml_backend_hexagon_context * ctx, const ggml_tensor * op_tensor) { + GGML_UNUSED(ctx); + ggml_tensor * src0 = op_tensor->src[0]; + ggml_tensor * src1 = op_tensor->src[1]; + if (nullptr != src1) { + if (src0->type != op_tensor->type || src1->type != op_tensor->type) { + return false; + } + } else { + if (src0->type != op_tensor->type) { + return false; + } + } + + if (src0->type != GGML_TYPE_F32) + return false; + + return true; +} + +static const char * ggmlhexagon_get_ggml_type_name(ggml_type type) { + const auto * traits = ggml_get_type_traits(type); + return traits->type_name; +} + +static void ggmlhexagon_append_tensor_dimensions(const ggml_tensor * tensor, std::string & output) { + char buffer[GGMLHEXAGON_TMPBUF_LEN] = {}; + const char * type_name = ggmlhexagon_get_ggml_type_name(tensor->type); + int len = 0; + switch (ggml_n_dims(tensor)) { + case 1: + len = snprintf(buffer, sizeof(buffer), "%ldx1%s", (long)tensor->ne[0], type_name); + break; + case 2: + len = snprintf(buffer, sizeof(buffer), "%ldx%ld%s", (long)tensor->ne[0], (long)tensor->ne[1], type_name); + break; + case 3: + len = snprintf(buffer, sizeof(buffer), "%ldx%ldx%ld%s", (long)tensor->ne[0], (long)tensor->ne[1], + (long)tensor->ne[2], type_name); + break; + case 4: + default: + len = snprintf(buffer, sizeof(buffer), "%ldx%ldx%ldx%ld%s", (long)tensor->ne[0], (long)tensor->ne[1], + (long)tensor->ne[2], (long)tensor->ne[3], type_name); + break; + } + GGML_ASSERT(len > 0 && len < (int)sizeof(buffer)); + output.append(buffer, len); +} + +static size_t ggmlhexagon_get_op_index(const ggml_tensor * tensor) { + if (tensor->op == GGML_OP_UNARY) { + return static_cast(GGML_OP_COUNT) + static_cast(ggml_get_unary_op(tensor)); + } + + return tensor->op; +} + +static size_t ggmlhexagon_get_op_input_param_count(const ggml_tensor * op) { + auto op_index = ggmlhexagon_get_op_index(op); + GGML_ASSERT(op_index < std::size(ggmlqnn_k_op_caps)); + return ggmlhexagon_k_op_caps[op_index].input_param_count; +} + +static void ggmlhexagon_get_opkey_from_op(const ggml_tensor * op, std::string & output) { + GGML_ASSERT(op->op != GGML_OP_NONE); + output += ggml_op_desc(op); + output += ggmlhexagon_get_ggml_type_name(op->type); + size_t param_count = ggmlhexagon_get_op_input_param_count(op); + for (size_t i = 0; i < param_count; ++i) { + auto * input = op->src[i]; + if (!input) { + break; + } + output += '_'; + ggmlhexagon_append_tensor_dimensions(input, output); + } +} + +static void * ggmlhexagon_type_trait(ggml_backend_hexagon_context * ctx, ggml_tensor * op) { + const ggml_tensor * src0 = op->src[0]; + const ggml_tensor * src1 = op->src[1]; + ggml_tensor * dst = op; + const enum ggml_type src0_type = src0->type; + + GGML_TENSOR_BINARY_OP_LOCALS + GGML_ASSERT(ne0 == ne01); + GGML_ASSERT(ne1 == ne11); + GGML_ASSERT(ne2 == ne12); + GGML_ASSERT(ne3 == ne13); + GGML_ASSERT(nb00 == ggml_type_size(src0_type)); + GGML_ASSERT(nb10 == ggml_type_size(src1->type)); + + const int64_t ne_plane = ne01 * ne00; + const size_t desired_size = ((GGML_TYPE_F32 == src0_type) ? 0 : ne03 * ne02 * ne_plane * sizeof(float)); + ctx->desired_size = desired_size; + if (ctx->work_size < desired_size) { + ctx->work_data.reset(new char[desired_size]); + ctx->work_size = desired_size; + } + ctx->n_threads = std::thread::hardware_concurrency(); + void * wdata = ctx->work_data.get(); + // convert src0 to float + if (src0_type != GGML_TYPE_F32) { + const auto * type_traits = ggml_get_type_traits(src0_type); + ggml_to_float_t const to_float = type_traits->to_float; + + for (int64_t i03 = 0; i03 < ne03; i03++) { + for (int64_t i02 = 0; i02 < ne02; i02++) { + const void * x = (char *)src0->data + i02 * nb02 + i03 * nb03; + float * const wplane = (float *)wdata + i02 * ne_plane + i03 * ne02 * ne_plane; + + const int min_cols_per_thread = 4096; + const int min_rows_per_thread = std::max((int)(min_cols_per_thread / ne00), 1); + const int n_threads = std::max(std::min(ctx->n_threads, (int)(ne01 / min_rows_per_thread)), 1); + for (int i = 1; i < n_threads; i++) { + const int64_t start = i * ne01 / n_threads; + const int64_t end = (i + 1) * ne01 / n_threads; + if (start < end) { + ctx->tasks.push_back(std::async(std::launch::async, [=]() { + for (int64_t i01 = start; i01 < end; i01++) { + to_float((const char *)x + i01 * nb01, wplane + i01 * ne00, ne00); + } + })); + } + } + { + // reuse the current thread for the first task + const int64_t start = 0; + const int64_t end = ne01 / n_threads; + for (int64_t i01 = start; i01 < end; i01++) { + to_float((const char *) x + i01 * nb01, wplane + i01 * ne00, ne00); + } + } + } + } + + // wait for all tasks to finish + for (auto &task: ctx->tasks) { + task.get(); + } + ctx->tasks.clear(); + } + return wdata; +} + +static void ggmlhexagon_set_runtime_path(size_t device, const std::string & path) { +#if defined(__ANDROID__) + if ((HEXAGON_BACKEND_QNNNPU == device) || (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach)) { + std::string lib_runtime_path = path + ":/vendor/dsp/cdsp:/vendor/lib64:/vendor/dsp/dsp:/vendor/dsp/images"; + if (0 == setenv("LD_LIBRARY_PATH", lib_runtime_path.c_str(), 1)) { + GGMLHEXAGON_LOG_DEBUG("setenv LD_LIBRARY_PATH %s successfully", lib_runtime_path.c_str()); + } else { + GGMLHEXAGON_LOG_ERROR("setenv LD_LIBRARY_PATH %s failure", lib_runtime_path.c_str()); + } + + std::string adsp_runtime_path = path + ";/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/rfsa/adsp;/vendor/dsp/dsp;/vendor/dsp/images;/dsp"; + if (0 == setenv("ADSP_LIBRARY_PATH", adsp_runtime_path.c_str(), 1)) { + GGMLHEXAGON_LOG_DEBUG("setenv ADSP_LIBRARY_PATH %s successfully", adsp_runtime_path.c_str()); + } else { + GGMLHEXAGON_LOG_ERROR("setenv ADSP_LIBRARY_PATH %s failure", adsp_runtime_path.c_str()); + } + } else { + if (0 == setenv("LD_LIBRARY_PATH", + (path + + ":/vendor/dsp/cdsp:/vendor/lib64:/vendor/dsp/dsp:/vendor/dsp/images").c_str(), + 1)) { + GGMLHEXAGON_LOG_DEBUG("%s backend setenv successfully\n", + ggml_backend_hexagon_get_devname(device)); + } else { + GGMLHEXAGON_LOG_ERROR("%s backend setenv failure\n", + ggml_backend_hexagon_get_devname(device)); + } + } +#endif +} + +static void ggmlhexagon_load_cfg() { + //this function can be called in various scenarios + static bool initialized = false; + if (initialized) { + GGMLHEXAGON_LOG_DEBUG("hexagon appcfg file already loaded\n"); + return; + } + char time_string[GGMLHEXAGON_TMPBUF_LEN]; + memset(time_string, 0, GGMLHEXAGON_TMPBUF_LEN); + ggmlhexagon_get_timestring(time_string); + GGMLHEXAGON_LOG_DEBUG("program running start time:%s", time_string); + std::string cfg_filename = std::string(g_hexagon_appcfg.runtime_libpath) + std::string(g_hexagon_appcfg.cfgfilename); + GGMLHEXAGON_LOG_INFO("load hexagon appcfg from %s", cfg_filename.c_str()); + hexagon_appcfg hexagoncfg_instance; + hexagoncfg_instance.load(cfg_filename); + hexagoncfg_instance.dump([](const std::string & section, const std::string & key, const std::string value) { + std::ostringstream tmposs; + tmposs << "section[" << std::setw(10) << std::left << section << "],[" << std::setw(25) << std::left << key << "] = [" << value << "]"; + GGMLHEXAGON_LOG_INFO("%s", tmposs.str().c_str()); + }); + std::string precision_mode; + std::string version; //version of ggml-hexagon.cpp + std::string ggmldsp_version; //version of ggml-dsp.c + hexagoncfg_instance.get_stringvalue("general", "version", version, "1.00"); + hexagoncfg_instance.get_stringvalue("general", "ggmldsp_version", ggmldsp_version, "0.62"); + hexagoncfg_instance.get_intvalue("general", "enable_perf", g_hexagon_appcfg.enable_perf, 1); + hexagoncfg_instance.get_intvalue("general", "print_tensors_info", g_hexagon_appcfg.print_tensors_info, 0); + hexagoncfg_instance.get_intvalue("general", "dump_op_info", g_hexagon_appcfg.dump_op_info, 0); + hexagoncfg_instance.get_intvalue("general", "hwaccel_approach", g_hexagon_appcfg.hwaccel_approach, HWACCEL_CDSP); + hexagoncfg_instance.get_intvalue("general", "hexagon_backend", g_hexagon_appcfg.hexagon_backend, HEXAGON_BACKEND_CDSP); + hexagoncfg_instance.get_intvalue("general", "enable_q_mulmat", g_hexagon_appcfg.enable_q_mulmat, 0); + hexagoncfg_instance.get_intvalue("general", "enable_profiler", g_hexagon_appcfg.enable_profiler, 0); + hexagoncfg_instance.get_intvalue("general", "profiler_duration", g_hexagon_appcfg.profiler_duration, 5); + hexagoncfg_instance.get_intvalue("general", "profiler_counts", g_hexagon_appcfg.profiler_counts, 100); + hexagoncfg_instance.get_intvalue("general", "enable_pinned_memory", g_hexagon_appcfg.enable_pinned_memory, 0); + + hexagoncfg_instance.get_intvalue("qnn", "hvx_threads", g_hexagon_appcfg.hvx_threads, 4); + hexagoncfg_instance.get_intvalue("qnn", "vtcm_size_in_mb", g_hexagon_appcfg.vtcm_size_in_mb, 8); + hexagoncfg_instance.get_intvalue("qnn", "enable_dlbc", g_hexagon_appcfg.enable_dlbc, 1); + hexagoncfg_instance.get_stringvalue("qnn", "precision_mode", precision_mode, "fp32"); + hexagoncfg_instance.get_intvalue("qnn", "print_qnn_internal_log", g_hexagon_appcfg.print_qnn_internal_log, 0); + + hexagoncfg_instance.get_intvalue("cdsp", "enable_rpc_ion_mempool", g_hexagon_appcfg.enable_rpc_ion_mempool, 0); + hexagoncfg_instance.get_intvalue("cdsp", "enable_all_q_mulmat", g_hexagon_appcfg.enable_all_q_mulmat, 0); + hexagoncfg_instance.get_intvalue("cdsp", "thread_counts", g_hexagon_appcfg.thread_counts, 4); + + GGMLHEXAGON_LOG_INFO("internal ggml_hexagon_version=%s", g_hexagon_appcfg.ggml_hexagon_version); + GGMLHEXAGON_LOG_INFO("internal ggml_dsp_version=%s", g_hexagon_appcfg.ggml_dsp_version); + GGMLHEXAGON_LOG_INFO("external ggml_hexagon_version=%s", version.c_str()); + GGMLHEXAGON_LOG_INFO("external ggml_dsp_version=%s", ggmldsp_version.c_str()); + memcpy(g_hexagon_appcfg.ggml_dsp_version, ggmldsp_version.c_str(), strlen(ggmldsp_version.c_str())); + GGMLHEXAGON_LOG_INFO("hwaccel_approach=%d(%s)", g_hexagon_appcfg.hwaccel_approach, + ggmlhexagon_get_hwaccel_approach_name(g_hexagon_appcfg.hwaccel_approach)); + GGMLHEXAGON_LOG_INFO("hexagon_backend=%d(%s)", g_hexagon_appcfg.hexagon_backend, + ggml_backend_hexagon_get_devname(g_hexagon_appcfg.hexagon_backend)); + GGMLHEXAGON_LOG_INFO("runtime libpath=%s", g_hexagon_appcfg.runtime_libpath); + GGMLHEXAGON_LOG_INFO("enable_perf=%d", g_hexagon_appcfg.enable_perf); + GGMLHEXAGON_LOG_INFO("enable_profiler=%d", g_hexagon_appcfg.enable_profiler); + + if (precision_mode.find("fp16") != std::string::npos) { + g_hexagon_appcfg.precision_mode = 1; + } else { + g_hexagon_appcfg.precision_mode = 0; + } + + ggmlhexagon_set_runtime_path(HEXAGON_BACKEND_CDSP, g_hexagon_appcfg.runtime_libpath); + + if (1 == g_hexagon_appcfg.enable_profiler) { + //make sure this function is called only once + g_hexagon_profiler.profiler_init(g_hexagon_appcfg.profiler_duration, g_hexagon_appcfg.profiler_counts); + } + + initialized = true; +} + +static bool ggmlhexagon_check_valid_appcfg() { + bool is_valid_appcfg = true; + + GGMLHEXAGON_LOG_DEBUG("user's specified hwaccel approach=%d(%s)", g_hexagon_appcfg.hwaccel_approach, + ggmlhexagon_get_hwaccel_approach_name(g_hexagon_appcfg.hwaccel_approach)); + GGMLHEXAGON_LOG_DEBUG("user's specified hexagon_backend=%d", g_hexagon_appcfg.hexagon_backend); + if (g_hexagon_appcfg.hexagon_backend >= GGML_HEXAGON_MAX_DEVICES) { + GGMLHEXAGON_LOG_INFO("using default ggml backend"); + is_valid_appcfg = false; + } + + if (HWACCEL_QNN_SINGLEGRAPH == g_hexagon_appcfg.hwaccel_approach) { + GGMLHEXAGON_LOG_INFO("HWACCEL_QNN_SINGLEGRAPH not supported"); + is_valid_appcfg = false; + } + + if (HWACCEL_QNN == g_hexagon_appcfg.hwaccel_approach) { + if (HEXAGON_BACKEND_CDSP == g_hexagon_appcfg.hexagon_backend) { + GGMLHEXAGON_LOG_INFO("hexagon_backend HEXAGON_BACKEND_CDSP must match with hwaccel_approach HWACCEL_CDSP"); + is_valid_appcfg = false; + } + } + + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + if ((HEXAGON_BACKEND_CDSP != g_hexagon_appcfg.hexagon_backend) && (HEXAGON_BACKEND_GGML != g_hexagon_appcfg.hexagon_backend)) { + GGMLHEXAGON_LOG_INFO("hwaccel_approach HWACCEL_CDSP must match with hexagon_backend HEXAGON_BACKEND_CDSP"); + is_valid_appcfg = false; + } + + if (1 == g_hexagon_appcfg.enable_all_q_mulmat) { + if (0 == g_hexagon_appcfg.enable_q_mulmat) { + GGMLHEXAGON_LOG_INFO("ensure set enable_q_mulmat to 1 firstly when set enable_all_q_mulmat to 1"); + is_valid_appcfg = false; + } + } + } + + if (!is_valid_appcfg) { + GGMLHEXAGON_LOG_INFO("it seems there is wrong configuration in ggml-hexagon.cfg, will using the default ggml backend accordingly"); + } + return is_valid_appcfg; +} + +static void ggmlhexagon_probe_dspinfo(ggml_backend_hexagon_context * ctx); +static void ggmlhexagon_print_running_timestamp(ggml_backend_hexagon_context * ctx) { + char timestamp[GGMLHEXAGON_TMPBUF_LEN]; + memset(timestamp, 0, GGMLHEXAGON_TMPBUF_LEN); + + GGMLHEXAGON_LOG_INFO("ggml_hexagon_version: %s", g_hexagon_appcfg.ggml_hexagon_version); + GGMLHEXAGON_LOG_INFO("ggml_dsp_version: %s", g_hexagon_appcfg.ggml_dsp_version); + GGMLHEXAGON_LOG_INFO("hwaccel approach: %d(%s)", g_hexagon_appcfg.hwaccel_approach, + ggmlhexagon_get_hwaccel_approach_name(g_hexagon_appcfg.hwaccel_approach)); + GGMLHEXAGON_LOG_INFO("hexagon_backend: %d(%s)", g_hexagon_appcfg.hexagon_backend, + ggml_backend_hexagon_get_devname(g_hexagon_appcfg.hexagon_backend)); + GGMLHEXAGON_LOG_INFO("enable pinned_memory: %s", g_hexagon_appcfg.enable_pinned_memory ? "YES" : "NO"); + ggmlhexagon_get_timestring(timestamp); + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + GGMLHEXAGON_LOG_INFO("offload quantize GGML_OP_MUL_MAT: %s", g_hexagon_appcfg.enable_q_mulmat ? "YES" : "NO"); + GGMLHEXAGON_LOG_INFO("using rpc ion memory pool: %s", g_hexagon_appcfg.enable_rpc_ion_mempool ? "YES" : "NO"); + GGMLHEXAGON_LOG_INFO("thread_counts with HWACCEL_CDSP: %d", g_hexagon_appcfg.thread_counts); + ggmlhexagon_probe_dspinfo(ctx); + } else { + GGMLHEXAGON_LOG_INFO("thread_counts with HWACCEL_QNN: %d", g_hexagon_appcfg.hvx_threads); + GGMLHEXAGON_LOG_INFO("offload quantize GGML_OP_MUL_MAT: %s", g_hexagon_appcfg.enable_q_mulmat ? "YES" : "NO"); + } + GGMLHEXAGON_LOG_INFO("running timestamp:%s", timestamp); + + if (1 == g_hexagon_appcfg.enable_profiler) { + //make sure this function is called only once + g_hexagon_profiler.profiler_deinit(); + } +} + +// ================================================================================================= +// section-5: QNN helper function/class +// ================================================================================================= +//make sure every QNN tensor/opcfg name is unique, threadsafe is not required at the moment +static void ggmlqnn_reset_idx() { + g_qnntensor_idx = 0; + g_qnnopcfg_idx = 0; +} + +static void ggmlqnn_inc_idx(int idx_type) { + switch (idx_type) { + case QNN_TENSOR_INDEX: + g_qnntensor_idx++; + break; + case QNN_OPCFG_INDEX: + g_qnnopcfg_idx++; + break; + default: + break; + } +} + +static int32_t ggmlqnn_get_idx(int idx_type) { + switch (idx_type) { + case QNN_TENSOR_INDEX: + return g_qnntensor_idx; + case QNN_OPCFG_INDEX: + return g_qnnopcfg_idx; + default: + break; + } + + //it's not make sense, just for fix compiler warning + return g_qnntensor_idx; +} + +static intptr_t ggmlqnn_align_to(size_t alignment, intptr_t offset) { + return offset % alignment == 0 ? offset + : offset + + (static_cast(alignment) - + offset % static_cast(alignment)); +} + +static size_t ggmlqnn_memscpy(void * dst, size_t dst_size, const void * src, size_t copy_size) { + if (!dst || !src || !dst_size || !copy_size) + return 0; + + size_t min_size = dst_size < copy_size ? dst_size : copy_size; + + memcpy(dst, src, min_size); + + return min_size; +} + +static char * ggmlqnn_strndup(const char * source, size_t maxlen) { +#if defined(__ANDROID__) || defined(__linux__) + return strndup(source, maxlen); +#else + //TODO:behaviour is not exactly same to Android&Linux + GGML_UNUSED(maxlen); + return strdup(source); +#endif +} + +static inline uint32_t ggmlqnn_get_tensorid(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.id; + } + return 0u; +} + +static inline const char * ggmlqnn_get_tensorname(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.name; + } + return nullptr; +} + +static inline Qnn_TensorType_t ggmlqnn_get_tensortype(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.type; + } + return QNN_TENSOR_TYPE_UNDEFINED; +} + +static inline Qnn_TensorDataFormat_t ggmlqnn_get_tensor_dataformat(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.dataFormat; + } + return QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER; +} + +static inline Qnn_DataType_t ggmlqnn_get_tensor_datatype(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.dataType; + } + return QNN_DATATYPE_UNDEFINED; +} + +static inline Qnn_QuantizeParams_t ggmlqnn_get_tensor_quantparams(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.quantizeParams; + } + return QNN_QUANTIZE_PARAMS_INIT; +} + +static inline uint32_t ggmlqnn_get_tensor_rank(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.rank; + } + return 0u; +} + +static inline uint32_t * ggmlqnn_get_tensor_dimensions(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.dimensions; + } + return nullptr; +} + +static inline Qnn_TensorMemType_t ggmlqnn_get_tensor_memtype(const Qnn_Tensor_t & tensor) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + return tensor.v1.memType; + } + return QNN_TENSORMEMTYPE_UNDEFINED; +} + +static inline void ggmlqnn_set_tensor_id(Qnn_Tensor_t & tensor, uint32_t id) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.id = id; + } +} + +static inline void ggmlqnn_set_tensor_name(Qnn_Tensor_t & tensor, const char * name) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.name = name; + } +} + +static inline void ggmlqnn_set_tensor_type(Qnn_Tensor_t & tensor, Qnn_TensorType_t type) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.type = type; + } +} + +static inline void ggmlqnn_set_tensor_dataformat(Qnn_Tensor_t & tensor, Qnn_TensorDataFormat_t format) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.dataFormat = format; + } +} + +static inline void ggmlqnn_set_tensor_datatype(Qnn_Tensor_t & tensor, Qnn_DataType_t dataType) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.dataType = dataType; + } +} + +static inline void ggmlqnn_set_tensor_quantparams(Qnn_Tensor_t & tensor, Qnn_QuantizeParams_t params) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.quantizeParams = params; + } +} + +static inline void ggmlqnn_set_tensor_rank(Qnn_Tensor_t & tensor, uint32_t rank) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.rank = rank; + } +} + +static inline void ggmlqnn_set_tensor_dimensions(Qnn_Tensor_t & tensor, uint32_t * dims) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.dimensions = dims; + } +} + +static inline void ggmlqnn_set_tensor_memtype(Qnn_Tensor_t & tensor, Qnn_TensorMemType_t memType) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.memType = memType; + } +} + +static inline void ggmlqnn_set_tensor_clientbuf(Qnn_Tensor_t & tensor, Qnn_ClientBuffer_t clientBuf) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.clientBuf = clientBuf; + } +} + +static inline void ggmlqnn_set_tensor_memhandle(Qnn_Tensor_t & tensor, Qnn_MemHandle_t handle) { + if (tensor.version == QNN_TENSOR_VERSION_1) { + tensor.v1.memHandle = handle; + } +} + +static int ggmlqnn_deep_copy_qnntensor(Qnn_Tensor_t & src, Qnn_Tensor_t & dst) { + int err = 0; + + dst.version = src.version; + ggmlqnn_set_tensor_name(dst, ggmlqnn_strndup(ggmlqnn_get_tensorname(src), std::string(ggmlqnn_get_tensorname(src)).size())); + if (nullptr == ggmlqnn_get_tensorname(dst)) { + return 1; + } + ggmlqnn_set_tensor_id(dst, ggmlqnn_get_tensorid(src)); + ggmlqnn_set_tensor_type(dst, ggmlqnn_get_tensortype(src)); + ggmlqnn_set_tensor_dataformat(dst, ggmlqnn_get_tensor_dataformat(src)); + ggmlqnn_set_tensor_datatype(dst, ggmlqnn_get_tensor_datatype(src)); + ggmlqnn_set_tensor_memtype(dst, ggmlqnn_get_tensor_memtype(src)); + + if (ggmlqnn_get_tensor_memtype(src) == QNN_TENSORMEMTYPE_RAW) { + Qnn_ClientBuffer_t client_buf = {nullptr, 0}; + ggmlqnn_set_tensor_clientbuf(dst, client_buf); + } else if (ggmlqnn_get_tensor_memtype(src) == QNN_TENSORMEMTYPE_MEMHANDLE) { + ggmlqnn_set_tensor_memhandle(dst, nullptr); + } else { + return 1; + } + + Qnn_QuantizeParams_t src_qparam = ggmlqnn_get_tensor_quantparams(src); + Qnn_QuantizationEncoding_t encoding = src_qparam.quantizationEncoding; + if (encoding == QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { + Qnn_QuantizeParams_t src_qparam_cpy = src_qparam; + Qnn_AxisScaleOffset_t & axis_scale_offset = src_qparam_cpy.axisScaleOffsetEncoding; + Qnn_ScaleOffset_t ** scale_offset = &axis_scale_offset.scaleOffset; + size_t scale_offset_size = axis_scale_offset.numScaleOffsets * sizeof(Qnn_ScaleOffset_t); + *scale_offset = (Qnn_ScaleOffset_t *)malloc(scale_offset_size); + ggmlqnn_memscpy(*scale_offset, + scale_offset_size, + src_qparam.axisScaleOffsetEncoding.scaleOffset, + scale_offset_size); + ggmlqnn_set_tensor_quantparams(dst, src_qparam_cpy); + } else if (encoding == QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET) { + Qnn_QuantizeParams_t src_qparam_cpy = src_qparam; + Qnn_BwAxisScaleOffset_t & bwaxis_scale_offset = src_qparam_cpy.bwAxisScaleOffsetEncoding; + size_t scale_size = bwaxis_scale_offset.numElements * sizeof(float); + float ** scales = &bwaxis_scale_offset.scales; + int32_t ** offsets = &bwaxis_scale_offset.offsets; + *scales = (float *)malloc(scale_size); + ggmlqnn_memscpy(*scales, scale_size, src_qparam.bwAxisScaleOffsetEncoding.scales, scale_size); + + if (bwaxis_scale_offset.offsets != nullptr) { + size_t offset_size = bwaxis_scale_offset.numElements * sizeof(int32_t); + *offsets = (int32_t *)malloc(offset_size); + ggmlqnn_memscpy(*offsets, offset_size, src_qparam.bwAxisScaleOffsetEncoding.offsets, offset_size); + } + ggmlqnn_set_tensor_quantparams(dst, src_qparam_cpy); + } else { + ggmlqnn_set_tensor_quantparams(dst, src_qparam); + } + + uint32_t rank = ggmlqnn_get_tensor_rank(src); + ggmlqnn_set_tensor_rank(dst, rank); + size_t dim_size = GGML_MAX_DIMS * sizeof(uint32_t); + uint32_t * dimensions = (uint32_t *)malloc(dim_size); + if (nullptr == dimensions) { + GGMLHEXAGON_LOG_WARN("deep_copy_qnn_tensors() allocation error while copying tensor %s\n", ggmlqnn_get_tensorname(src)); + return 1; + } + ggmlqnn_memscpy(dimensions, dim_size, ggmlqnn_get_tensor_dimensions(src), dim_size); + ggmlqnn_set_tensor_dimensions(dst, dimensions); + + return err; +} + +static int ggmlqnn_free_qnntensor(Qnn_Tensor_t * tensor) { + int err = 0; + free((void *) ggmlqnn_get_tensorname(*tensor)); + Qnn_QuantizeParams_t src_qparam = ggmlqnn_get_tensor_quantparams(*tensor); + Qnn_QuantizationEncoding_t encoding = src_qparam.quantizationEncoding; + if (encoding == QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { + free(src_qparam.axisScaleOffsetEncoding.scaleOffset); + } else if (encoding == QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET) { + free(src_qparam.bwAxisScaleOffsetEncoding.scales); + if (src_qparam.bwAxisScaleOffsetEncoding.offsets != nullptr) { + free(src_qparam.bwAxisScaleOffsetEncoding.offsets); + } + } + GGMLHEXAGON_LOG_DEBUG("free tensor %p", tensor); + free(ggmlqnn_get_tensor_dimensions(*tensor)); + free(tensor); + + return err; +} + +static const char * ggmlqnn_get_qnnerror_string(Qnn_ErrorHandle_t qnn_error_code) { + // file:///opt/qcom/aistack/qairt/2.31.0.250130/docs/QNN/general/api_error_codes.html + switch (qnn_error_code) { + case QNN_SUCCESS: + return "QNN_SUCCESS"; + case QNN_COMMON_ERROR_GENERAL: + return "QNN_COMMON_ERROR_GENERAL"; + + // QnnGraph_Error_t + case QNN_GRAPH_ERROR_UNSUPPORTED_FEATURE: + return "QNN_GRAPH_ERROR_UNSUPPORTED_FEATURE"; + case QNN_GRAPH_ERROR_MEM_ALLOC: + return "QNN_GRAPH_ERROR_MEM_ALLOC"; + case QNN_GRAPH_ERROR_INVALID_ARGUMENT: + return "QNN_GRAPH_ERROR_INVALID_ARGUMENT"; + case QNN_GRAPH_ERROR_INVALID_HANDLE: + return "QNN_GRAPH_ERROR_INVALID_HANDLE"; + case QNN_GRAPH_ERROR_GRAPH_DOES_NOT_EXIST: + return "QNN_GRAPH_ERROR_GRAPH_DOES_NOT_EXIST"; + case QNN_GRAPH_ERROR_INVALID_NAME: + return "QNN_GRAPH_ERROR_INVALID_NAME"; + case QNN_GRAPH_ERROR_INVALID_TENSOR: + return "QNN_GRAPH_ERROR_INVALID_TENSOR"; + case QNN_GRAPH_ERROR_INVALID_OP_CONFIG: + return "QNN_GRAPH_ERROR_INVALID_OP_CONFIG"; + case QNN_GRAPH_ERROR_SET_PROFILE: + return "QNN_GRAPH_ERROR_SET_PROFILE"; + case QNN_GRAPH_ERROR_UNCONNECTED_NODE: + return "QNN_GRAPH_ERROR_UNCONNECTED_NODE"; + case QNN_GRAPH_ERROR_CREATE_FAILED: + return "QNN_GRAPH_ERROR_CREATE_FAILED"; + case QNN_GRAPH_ERROR_OPTIMIZATION_FAILED: + return "QNN_GRAPH_ERROR_OPTIMIZATION_FAILED"; + case QNN_GRAPH_ERROR_FINALIZE_FAILED: + return "QNN_GRAPH_ERROR_FINALIZE_FAILED"; + case QNN_GRAPH_ERROR_GRAPH_NOT_FINALIZED: + return "QNN_GRAPH_ERROR_GRAPH_NOT_FINALIZED"; + case QNN_GRAPH_ERROR_GRAPH_FINALIZED: + return "QNN_GRAPH_ERROR_GRAPH_FINALIZED"; + case QNN_GRAPH_ERROR_EXECUTION_ASYNC_FIFO_FULL: + return "QNN_GRAPH_ERROR_EXECUTION_ASYNC_FIFO_FULL"; + case QNN_GRAPH_ERROR_SIGNAL_IN_USE: + return "QNN_GRAPH_ERROR_SIGNAL_IN_USE"; + case QNN_GRAPH_ERROR_ABORTED: + return "QNN_GRAPH_ERROR_ABORTED"; + case QNN_GRAPH_ERROR_PROFILE_IN_USE: + return "QNN_GRAPH_ERROR_PROFILE_IN_USE"; + case QNN_GRAPH_ERROR_TIMED_OUT: + return "QNN_GRAPH_ERROR_TIMED_OUT"; + case QNN_GRAPH_ERROR_SUBGRAPH: + return "QNN_GRAPH_ERROR_SUBGRAPH"; + case QNN_GRAPH_ERROR_DISABLED: + return "QNN_GRAPH_ERROR_DISABLED"; + case QNN_GRAPH_ERROR_DYNAMIC_TENSOR_SHAPE: + return "QNN_GRAPH_ERROR_DYNAMIC_TENSOR_SHAPE"; + case QNN_GRAPH_ERROR_TENSOR_SPARSITY: + return "QNN_GRAPH_ERROR_TENSOR_SPARSITY"; + case QNN_GRAPH_ERROR_EARLY_TERMINATION: + return "QNN_GRAPH_ERROR_EARLY_TERMINATION"; + case QNN_GRAPH_ERROR_INVALID_CONTEXT: + return "QNN_GRAPH_ERROR_INVALID_CONTEXT"; + + //QQnnTensor_Error_t + //Invalid context/graph handle in creating tensor + case QNN_TENSOR_ERROR_INVALID_HANDLE: + return "QNN_TENSOR_ERROR_INVALID_HANDLE"; + //Tensor with specified credentials not registered with a context/graph + case QNN_TENSOR_ERROR_DOES_NOT_EXIST: + return "QNN_TENSOR_ERROR_DOES_NOT_EXIST"; + // (deprecated) Tensor has already been registered with backend + case QNN_TENSOR_ERROR_ALREADY_EXISTS: + return "QNN_TENSOR_ERROR_ALREADY_EXISTS"; + // Invalid tensor param. + case QNN_TENSOR_ERROR_INVALID_TENSOR_PARAM: + return "QNN_TENSOR_ERROR_INVALID_TENSOR_PARAM"; + // This tensor param is currently unsupported + case QNN_TENSOR_ERROR_UNSUPPORTED_TENSOR_PARAM: + return "QNN_TENSOR_ERROR_UNSUPPORTED_TENSOR_PARAM"; + // Tensor provided for update is invalid + case QNN_TENSOR_ERROR_INCOMPATIBLE_TENSOR_UPDATE: + return "QNN_TENSOR_ERROR_INCOMPATIBLE_TENSOR_UPDATE"; + + // QnnOpPackage_Error_t + case QNN_OP_PACKAGE_ERROR_LIBRARY_ALREADY_INITIALIZED: + return "QNN_OP_PACKAGE_ERROR_LIBRARY_ALREADY_INITIALIZED"; + case QNN_OP_PACKAGE_ERROR_LIBRARY_NOT_INITIALIZED: + return "QNN_OP_PACKAGE_ERROR_LIBRARY_NOT_INITIALIZED"; + case QNN_OP_PACKAGE_ERROR_INVALID_HANDLE: + return "QNN_OP_PACKAGE_ERROR_INVALID_HANDLE"; + case QNN_OP_PACKAGE_ERROR_INVALID_INFRASTRUCTURE: + return "QNN_OP_PACKAGE_ERROR_INVALID_INFRASTRUCTURE"; + case QNN_OP_PACKAGE_ERROR_INVALID_INFO: + return "QNN_OP_PACKAGE_ERROR_INVALID_INFO"; + case QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE: + return "QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE"; + case QNN_OP_PACKAGE_ERROR_INVALID_ARGUMENT: + return "QNN_OP_PACKAGE_ERROR_INVALID_ARGUMENT"; + + default: + return "unknown QNN error"; + } +} + +// ref:explanation of k-quants, https://github.com/ggerganov/llama.cpp/pull/1684 +static Qnn_DataType_t ggmlqnn_datatype_from_ggml_datatype(enum ggml_type ggmltype) { + switch (ggmltype) { + case GGML_TYPE_F16: + return QNN_DATATYPE_FLOAT_16; + case GGML_TYPE_F32: + return QNN_DATATYPE_FLOAT_32; + case GGML_TYPE_I8: + return QNN_DATATYPE_INT_8; + case GGML_TYPE_Q8_0: + return QNN_DATATYPE_SFIXED_POINT_8; + case GGML_TYPE_Q4_0: + return QNN_DATATYPE_SFIXED_POINT_4; + default: + break; + } + return QNN_DATATYPE_UNDEFINED; +} + +static void ggmlqnn_get_qnn_dimensions_from_ggml_dimensions(uint32_t * qnn_dimensions, const uint32_t * ggml_dimensions, uint32_t rank) { + if (rank > GGML_MAX_DIMS) { + GGMLHEXAGON_LOG_WARN("invalid params"); + return; + } + if (nullptr == qnn_dimensions || nullptr == ggml_dimensions) { + GGMLHEXAGON_LOG_WARN("invalid params"); + return; + } + for (size_t idx = 0; idx < GGML_MAX_DIMS; idx++) + qnn_dimensions[idx] = ggml_dimensions[idx]; + + if (rank >= 2) { + qnn_dimensions[rank - 1] = ggml_dimensions[rank - 2]; + qnn_dimensions[rank - 2] = ggml_dimensions[rank - 1]; + } +} + +template +Fn ggmlqnn_load_qnn_functionpointers(void * handle, const char * function_name) { + return reinterpret_cast(dlsym(handle, function_name)); +} + +class qnn_interface { +#define DEFINE_SHIM_FUNCTION_INTERFACE(F, pointer_name) \ + template \ + inline auto qnn_##F(Args... args) const { \ + return (_qnn_interface->QNN_INTERFACE_VER_NAME.pointer_name)( \ + std::forward(args)...); \ + } + + +#define DEFINE_SHIM_FUNCTION_SYS_INTERFACE(F, pointer_name) \ + template \ + inline auto qnn_##F(Args... args) const { \ + return (_qnn_sys_interface->QNN_SYSTEM_INTERFACE_VER_NAME.pointer_name)( \ + std::forward(args)...); \ + } + + friend class qnn_instance; + +public: + qnn_interface() = default; + + // QnnBackend + DEFINE_SHIM_FUNCTION_INTERFACE(backend_create, backendCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(backend_free, backendFree) + + DEFINE_SHIM_FUNCTION_INTERFACE(backend_register_op_package, backendRegisterOpPackage) + + DEFINE_SHIM_FUNCTION_INTERFACE(backend_validate_op_config, backendValidateOpConfig) + + DEFINE_SHIM_FUNCTION_INTERFACE(backend_get_api_version, backendGetApiVersion) + + // QnnDevice + DEFINE_SHIM_FUNCTION_INTERFACE(device_create, deviceCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(device_free, deviceFree) + + DEFINE_SHIM_FUNCTION_INTERFACE(device_get_infrastructure, deviceGetInfrastructure) + + DEFINE_SHIM_FUNCTION_INTERFACE(device_get_platform_info, deviceGetPlatformInfo) + + DEFINE_SHIM_FUNCTION_INTERFACE(device_get_info, deviceGetInfo) + + // QnnContext + DEFINE_SHIM_FUNCTION_INTERFACE(context_create, contextCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(context_get_binary_size, contextGetBinarySize) + + DEFINE_SHIM_FUNCTION_INTERFACE(context_get_binary, contextGetBinary) + + DEFINE_SHIM_FUNCTION_INTERFACE(context_create_from_binary, contextCreateFromBinary) + + DEFINE_SHIM_FUNCTION_INTERFACE(context_free, contextFree) + + // QnnGraph + DEFINE_SHIM_FUNCTION_INTERFACE(graph_create, graphCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(graph_add_node, graphAddNode) + + DEFINE_SHIM_FUNCTION_INTERFACE(graph_finalize, graphFinalize) + + DEFINE_SHIM_FUNCTION_INTERFACE(graph_execute, graphExecute) + + DEFINE_SHIM_FUNCTION_INTERFACE(graph_retrieve, graphRetrieve) + + // QnnLog + DEFINE_SHIM_FUNCTION_INTERFACE(log_create, logCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(log_free, logFree) + + DEFINE_SHIM_FUNCTION_INTERFACE(log_set_log_level, logSetLogLevel) + + // QnnProfile + DEFINE_SHIM_FUNCTION_INTERFACE(profile_create, profileCreate) + + DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_events, profileGetEvents) + + DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_sub_events, profileGetSubEvents) + + DEFINE_SHIM_FUNCTION_INTERFACE(profile_get_event_data, profileGetEventData) + + DEFINE_SHIM_FUNCTION_INTERFACE(profile_free, profileFree) + + // QnnMem + DEFINE_SHIM_FUNCTION_INTERFACE(mem_register, memRegister) + + DEFINE_SHIM_FUNCTION_INTERFACE(mem_de_register, memDeRegister) + + // QnnProperty + DEFINE_SHIM_FUNCTION_INTERFACE(property_has_capability, propertyHasCapability) + + // QnnTensor + DEFINE_SHIM_FUNCTION_INTERFACE(tensor_create_context_tensor, tensorCreateContextTensor) + + DEFINE_SHIM_FUNCTION_INTERFACE(tensor_create_graph_tensor, tensorCreateGraphTensor) + + // QnnSystem + DEFINE_SHIM_FUNCTION_SYS_INTERFACE(system_context_create, systemContextCreate) + + DEFINE_SHIM_FUNCTION_SYS_INTERFACE(system_context_get_binary_info, systemContextGetBinaryInfo) + + DEFINE_SHIM_FUNCTION_SYS_INTERFACE(system_context_free, systemContextFree) + + void set_qnn_interface(const QnnInterface_t * qnn_interface) { + _qnn_interface = qnn_interface; + } + + void set_qnn_system_interface(const QnnSystemInterface_t * qnn_sys_interface) { + _qnn_sys_interface = qnn_sys_interface; + } + + uint32_t get_backend_id() const { + return _qnn_interface->backendId; + } + + bool is_loaded() const { + return ((_qnn_sys_interface != nullptr) && (_qnn_interface != nullptr)); + } + +private: + const QnnInterface_t * _qnn_interface = nullptr; + + const QnnSystemInterface_t * _qnn_sys_interface = nullptr; +}; + +class qnn_instance { +public: + using BackendIdType = decltype(QnnInterface_t{}.backendId); + + explicit qnn_instance(const std::string & lib_path, const std::string & backend_name, + const std::string & model_name) : + _lib_path(std::move(lib_path)), + _backend_name(std::move(backend_name)), + _model_name(std::move(model_name)) {} + + ~qnn_instance() { + } + + int qnn_init(const QnnSaver_Config_t ** saver_config); + + int qnn_finalize(); + + const qnn_interface & get_qnn_interface() { + if (!_qnn_interface.is_loaded()) { + GGMLHEXAGON_LOG_WARN("pls check why _qnn_interface is not loaded\n"); + } + return _qnn_interface; + } + + const QNN_INTERFACE_VER_TYPE & get_qnn_raw_interface() { + if (!_qnn_interface.is_loaded()) { + GGMLHEXAGON_LOG_WARN("pls check why _qnn_interface is not loaded\n"); + } + return _qnn_raw_interface; + } + + const QNN_SYSTEM_INTERFACE_VER_TYPE & get_qnn_raw_system_interface() { + if (!_qnn_interface.is_loaded()) { + GGMLHEXAGON_LOG_WARN("pls check why _qnn_interface is not loaded\n"); + } + return _qnn_raw_system_interface; + } + + Qnn_LogHandle_t get_qnn_log_handle() { return _qnn_log_handle; } + + Qnn_ProfileHandle_t get_qnn_profile_handle() { return _qnn_profile_handle; } + + Qnn_DeviceHandle_t get_qnn_device_handle() { return _qnn_device_handle; } + + Qnn_BackendHandle_t get_qnn_backend_handle() { return _qnn_backend_handle; } + + Qnn_ContextHandle_t get_qnn_context_handle() { return _qnn_context_handle; } + + QnnSystemContext_Handle_t get_qnn_system_handle() { return _qnn_system_handle; } + + Qnn_GraphHandle_t get_qnn_graph_handle() { return _qnn_graph_handle; } + + int init_qnn_graph(const char * graph_name, + bool debug, + uint8_t do_node_validation = 1, + const QnnGraph_Config_t ** graph_configs = nullptr + ); + int init_qnn_graph(const std::string & graph_name, HEXAGONBackend device, size_t vtcm_size_in_mb = 8, size_t hvx_threads = 8); + + int finalize_qnn_graph(); + + bool is_valid_graph() const { return _qnn_graph_handle != nullptr; } + + int htp_init_perfinfra(); + + int htp_set_rpc_polling(); + + int htp_set_high_performance_mode(); + + std::string & get_qnn_graph_name() { return _graph_name; } + + bool is_rpcmem_initialized() { + return _rpcmem_initialized; + } + + void set_rpcmem_initialized(bool initialized) { + _rpcmem_initialized = initialized; + } + + size_t get_rpcmem_capacity() { return _rpcmem_capacity; } + size_t get_rpcmem_usage() { return _rpcmem_usage; } + + int32_t rpcmem_to_fd(void * buf); + + int register_rpcmem(void * p_data, Qnn_Tensor_t * p_tensor); + Qnn_MemHandle_t register_rpcmem(void * p_data, const uint32_t rank, uint32_t * dimensions, Qnn_DataType_t data_type); + + void unregister_rpcmem(); + void unregister_rpcmem(Qnn_MemHandle_t mem_handle); + + void * alloc_rpcmem(size_t bytes, size_t alignment); + void * get_rpcmem_from_memhandle(Qnn_MemHandle_t mem_handle); + + void free_rpcmem(void * buf); + void free_rpcmem(); + + bool is_rpcmem_allocated(void * buf); + + bool is_rpcmem_registered(Qnn_MemHandle_t handle) { + return _qnn_mem_set.count(handle) != 0U; + } + + bool enable_qnn_rpc() { + return _enable_qnn_rpc; + } + + HEXAGONBackend get_device_id() { + return _device_id; + } + +private: + int load_system(); + + int unload_system(); + + int load_backend(std::string & lib_path, const QnnSaver_Config_t ** saver_config); + + int unload_backend(); + + void set_qnn_raw_interface(QNN_INTERFACE_VER_TYPE & raw_interface) { + _qnn_raw_interface = raw_interface; + } + + void set_qnn_raw_system_interface(QNN_SYSTEM_INTERFACE_VER_TYPE & raw_interface) { + _qnn_raw_system_interface = raw_interface; + } + + void * alloc_rpcmem_internal(size_t bytes, size_t alignment); + + void htp_probe_rpc_meminfo(); + + void htp_print_info(); + + void print_backend_info(); + + void htp_set_memory_grow_size(size_t size = 1ul * 1024 * 1024); + + void htp_enter_performance_mode(); + + void htp_set_n_hvx_threads(size_t n_threads); + +private: + static constexpr const int _required_num_providers = 1; + +private: + std::string _lib_path; + std::string _backend_name; + std::string _model_name; // name of prebuilt QNN model, might be used in the future + BackendIdType _backend_id; + + bool _debug_tensor = false; // flag to indicate if requested graph is to be run in debug mode + bool _do_node_validations = true; // flag to indicate whether all add_node calls need to be validated + QnnLog_Level_t _qnn_log_level = QNN_LOG_LEVEL_DEBUG; + + qnn_profile_level _profile_level = PROFILE_OFF; + + void * _system_lib_handle = nullptr; + void * _loaded_lib_handle = nullptr; + const QnnInterface_t * _loaded_backend = nullptr; + + Qnn_GraphHandle_t _qnn_graph_handle = nullptr; + + Qnn_LogHandle_t _qnn_log_handle = nullptr; + + Qnn_ProfileHandle_t _qnn_profile_handle = nullptr; + + Qnn_DeviceHandle_t _qnn_device_handle = nullptr; + + Qnn_BackendHandle_t _qnn_backend_handle = nullptr; + + Qnn_ContextHandle_t _qnn_context_handle = nullptr; + + QnnSystemContext_Handle_t _qnn_system_handle = nullptr; + + QnnHtpDevice_PerfInfrastructure_t * _qnn_htp_perfinfra = nullptr; + uint32_t _qnn_htp_powerconfig_id = 1; + uint32_t _qnn_htp_device_id = 0; + uint32_t _qnn_htp_core_id = 0; + + uint32_t _qnn_rpc_pollingtime = 9999; // 0-10000 us for high performing + + qnn_interface _qnn_interface; + QNN_INTERFACE_VER_TYPE _qnn_raw_interface; + QNN_SYSTEM_INTERFACE_VER_TYPE _qnn_raw_system_interface; + + std::unordered_map _qnn_mem_set; + std::unordered_map _qnn_rpc_buffer_to_handles; + + std::atomic_bool _rpcmem_initialized{false}; + pfn_rpc_mem_alloc _pfn_rpc_mem_alloc; + pfn_rpc_mem_free _pfn_rpc_mem_free; + pfn_rpc_mem_to_fd _pfn_rpc_mem_to_fd; + pfn_rpc_mem_init _pfn_rpc_mem_init; + pfn_rpc_mem_deinit _pfn_rpc_mem_deinit; + std::unordered_map _rpcmem_store_map; + std::unordered_map _rpcmem_usage_map; + size_t _rpcmem_usage = 0; // mempool usage in bytes + size_t _rpcmem_capacity = 0; // mempool size in bytes + + std::string _graph_name; + HEXAGONBackend _device_id; + void * _rpc_lib_handle = nullptr; + bool _enable_qnn_rpc = false; //TODO:unknown issue with QNN RPC feature + + qnn_instance(const qnn_instance &) = delete; + void operator=(const qnn_instance &) = delete; + + qnn_instance(qnn_instance &&) = delete; + void operator=(qnn_instance &&) = delete; +}; + +void * qnn_instance::alloc_rpcmem_internal(size_t bytes, size_t alignment) { + if (!_rpcmem_initialized) { + GGMLHEXAGON_LOG_WARN("rpc memory not initialized\n"); + return nullptr; + } + + auto allocate_bytes = static_cast(bytes + alignment); + void * buf = _pfn_rpc_mem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, allocate_bytes); + if (nullptr == buf) { + GGMLHEXAGON_LOG_WARN("failed to allocate rpc memory\n"); + return nullptr; + } + + auto aligned_buf = reinterpret_cast(ggmlqnn_align_to(alignment, + reinterpret_cast(buf))); + bool status = _rpcmem_store_map.insert(std::pair(aligned_buf, buf)).second; + if (!status) { + GGMLHEXAGON_LOG_WARN("failed to allocate rpc memory\n"); + _pfn_rpc_mem_free(buf); + } + return aligned_buf; +} + +void * qnn_instance::alloc_rpcmem(size_t bytes, size_t alignment) { + if (_rpcmem_usage > (_rpcmem_capacity - (8 * SIZE_IN_MB))) { // reserve 8Mbytes in rpc mempool + GGMLHEXAGON_LOG_WARN("rpc mempool capacity: %d MiB, usage: %d MiB", _rpcmem_capacity / SIZE_IN_MB, _rpcmem_usage / SIZE_IN_MB); + return nullptr; + } + + auto aligned_buf = alloc_rpcmem_internal(bytes, alignment); + if (nullptr == aligned_buf) + return nullptr; + _rpcmem_usage_map.insert(std::pair(aligned_buf, bytes)); + + _rpcmem_usage += bytes; + return aligned_buf; +} + +void qnn_instance::free_rpcmem(void * buf) { + size_t rpcbuffer_size = 0; + if (!_rpcmem_initialized) { + GGMLHEXAGON_LOG_WARN("rpc memory not initialized\n"); + } else if (0 == _rpcmem_store_map.count(buf)) { + GGMLHEXAGON_LOG_WARN("no allocated tensor\n"); + } else { + GGMLHEXAGON_LOG_DEBUG("free rpc mem %p", _rpcmem_store_map[buf]); + for (const auto & [rpcbuffer, rpcbuffer_size] : _rpcmem_usage_map) { + if (buf == rpcbuffer) { + _rpcmem_usage -= rpcbuffer_size; + } + } + + if (rpcbuffer_size != 0) { + _rpcmem_usage_map.erase(buf); + } + _pfn_rpc_mem_free(_rpcmem_store_map[buf]); + _rpcmem_store_map.erase(buf); + } +} + +void qnn_instance::free_rpcmem() { + if (_rpcmem_store_map.empty()) { + GGMLHEXAGON_LOG_WARN("no rpcmem allocated\n"); + return; + } + + for (const auto & [rpcbuffer, raw_rpcbuffer] : _rpcmem_store_map) { + GGMLHEXAGON_LOG_DEBUG("free rpc buffer %p", rpcbuffer); + _pfn_rpc_mem_free(rpcbuffer); + } + + _rpcmem_store_map.clear(); + _rpcmem_usage_map.clear(); + _rpcmem_usage = 0; +} + +int32_t qnn_instance::rpcmem_to_fd(void * buf) { + int32_t mem_fd = -1; + if (!is_rpcmem_initialized()) { + GGMLHEXAGON_LOG_WARN("rpc memory not initialized\n"); + } else { + mem_fd = _pfn_rpc_mem_to_fd(buf); + } + + return mem_fd; +} + +int qnn_instance::register_rpcmem(void * p_data, Qnn_Tensor_t * p_tensor) { + if (nullptr == p_data || (nullptr == p_tensor)) { + GGMLHEXAGON_LOG_WARN("invalid param\n"); + return 1; + } + + if (!is_rpcmem_initialized()) { + GGMLHEXAGON_LOG_WARN("rpc memory not initialized\n"); + return 2; + } + + if (is_rpcmem_registered((QNN_VER_PTR(*p_tensor)->memHandle))) { + GGMLHEXAGON_LOG_WARN("tensor %s has been registered shared memory\n", (QNN_VER_PTR(*p_tensor)->name)); + return 3; + } + + int32_t mem_fd = rpcmem_to_fd(p_data); + if (-1 == mem_fd) { + GGMLHEXAGON_LOG_WARN("failed to get file descriptor\n"); + return 4; + } + GGMLHEXAGON_LOG_DEBUG("mem_fd %d\n", mem_fd); + Qnn_MemDescriptor_t descriptor = { + {QNN_VER_PTR(*p_tensor)->rank, QNN_VER_PTR(*p_tensor)->dimensions, nullptr}, + QNN_VER_PTR(*p_tensor)->dataType, + QNN_MEM_TYPE_ION, + {{mem_fd}}}; + Qnn_MemHandle_t handle = nullptr; + int error = QNN_SUCCESS; + error = _qnn_interface.qnn_mem_register( + _qnn_context_handle, + &descriptor, + /*numDescriptors=*/1, + &handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to register shared memory, error %d, %s\n", QNN_GET_ERROR_CODE(error), strerror(error)); + return 5; + } else { + GGMLHEXAGON_LOG_INFO("tensor %s successfully register shared memory\n", (QNN_VER_PTR(*p_tensor)->name)); + } + QNN_VER_PTR(*p_tensor)->memHandle = handle; + _qnn_mem_set.insert((std::pair(p_data, handle))); + + return 0; +} + +Qnn_MemHandle_t qnn_instance::register_rpcmem(void * p_data, const uint32_t rank, uint32_t * dimensions, Qnn_DataType_t data_type) { + if (!p_data) { + GGMLHEXAGON_LOG_WARN("invalid param"); + return nullptr; + } + + if (!is_rpcmem_initialized()) { + GGMLHEXAGON_LOG_WARN("rpc memory not initialized"); + return nullptr; + } + + if (is_rpcmem_registered(p_data)) { + GGMLHEXAGON_LOG_WARN("rpc memory already registered"); + return _qnn_rpc_buffer_to_handles[p_data]; + } + + int32_t mem_fd = rpcmem_to_fd(p_data); + if (mem_fd == -1) { + GGMLHEXAGON_LOG_WARN("failed to get file descriptor"); + return nullptr; + } + + GGMLHEXAGON_LOG_DEBUG("mem_fd %d", mem_fd); + Qnn_MemDescriptor_t descriptor = { + {rank, dimensions, nullptr}, + data_type, QNN_MEM_TYPE_ION, + {{mem_fd}} + }; + Qnn_MemHandle_t handle = nullptr; + Qnn_ErrorHandle_t error = _qnn_interface.qnn_mem_register(_qnn_context_handle, &descriptor, /*numDescriptors=*/1, &handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to register shared memory, error %d, %s", QNN_GET_ERROR_CODE(error), strerror(error)); + return nullptr; + } + + _qnn_rpc_buffer_to_handles.insert({p_data, handle}); + GGMLHEXAGON_LOG_DEBUG("successfully register shared memory handler: %p", handle); + return handle; +} + +void * qnn_instance::get_rpcmem_from_memhandle(Qnn_MemHandle_t mem_handle) { + for (const auto & [ptr, handle] : _qnn_mem_set) { + if (mem_handle == handle) { + return ptr; + } + } + + GGMLHEXAGON_LOG_WARN("can't find rpcmem from qnn mem handle %p", mem_handle); + return nullptr; +} + +void qnn_instance::unregister_rpcmem() { + if (_qnn_mem_set.empty()) { + GGMLHEXAGON_LOG_WARN("no rpcmem registered\n"); + } + + for (const auto & [ptr, mem_handle] : _qnn_mem_set) { + auto error = _qnn_interface.qnn_mem_de_register(&mem_handle, 1); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to unregister shared memory, error %d\n", QNN_GET_ERROR_CODE(error)); + } else { + GGMLHEXAGON_LOG_DEBUG("unregister shared memory ok"); + } + } + _qnn_mem_set.clear(); +} + +void qnn_instance::unregister_rpcmem(Qnn_MemHandle_t mem_handle) { + Qnn_ErrorHandle_t error = _qnn_interface.qnn_mem_de_register(&mem_handle, 1); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to unregister shared memory, error %d", QNN_GET_ERROR_CODE(error)); + } + + auto it = std::find_if(_qnn_mem_set.begin(), _qnn_mem_set.end(), + [mem_handle](const auto &kv) { return kv.second == mem_handle; }); + if (it == _qnn_mem_set.end()) { + GGMLHEXAGON_LOG_WARN("failed to find shared memory handler: %p", mem_handle); + return; + } + + _qnn_mem_set.erase(it); +} + +bool qnn_instance::is_rpcmem_allocated(void * buf) { + return _rpcmem_store_map.count(buf) != 0U; +} + +int qnn_instance::load_backend(std::string & lib_path, const QnnSaver_Config_t ** saver_config) { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + GGMLHEXAGON_LOG_DEBUG("lib_path:%s\n", lib_path.c_str()); + + void * lib_handle = dlopen(lib_path.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (nullptr == lib_handle) { + GGMLHEXAGON_LOG_WARN("can not open QNN library %s, with error: %s", lib_path.c_str(), dlerror()); + return 1; + } + + auto get_providers = ggmlqnn_load_qnn_functionpointers<_pfn_QnnInterface_getProviders *>( + lib_handle, + "QnnInterface_getProviders"); + if (nullptr == get_providers) { + GGMLHEXAGON_LOG_WARN("can not load symbol QnnInterface_getProviders : %s", dlerror()); + return 2; + } + + std::uint32_t num_providers = 0; + const QnnInterface_t ** provider_list = nullptr; + error = get_providers(&provider_list, &num_providers); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to get providers, error %d", QNN_GET_ERROR_CODE(error)); + return 3; + } + GGMLHEXAGON_LOG_DEBUG("num_providers=%d\n", num_providers); + if (num_providers != _required_num_providers) { + GGMLHEXAGON_LOG_WARN("providers is %d instead of required %d", num_providers, _required_num_providers); + return 4; + } + + if (nullptr == provider_list) { + GGMLHEXAGON_LOG_WARN("failed to get qnn interface providers\n"); + return 5; + } + bool found_valid_interface = false; + QNN_INTERFACE_VER_TYPE qnn_interface; + for (size_t idx = 0; idx < num_providers; idx++) { + if (QNN_API_VERSION_MAJOR == provider_list[idx]->apiVersion.coreApiVersion.major && + QNN_API_VERSION_MINOR <= provider_list[idx]->apiVersion.coreApiVersion.minor) { + found_valid_interface = true; + qnn_interface = provider_list[idx]->QNN_INTERFACE_VER_NAME; + break; + } + } + + if (!found_valid_interface) { + GGMLHEXAGON_LOG_WARN("unable to find a valid qnn interface\n"); + return 6; + } else { + GGMLHEXAGON_LOG_INFO("find a valid qnn interface\n"); + } + set_qnn_raw_interface(qnn_interface); + + BackendIdType backend_id = provider_list[0]->backendId; + _loaded_backend = provider_list[0]; + _loaded_lib_handle = lib_handle; + _backend_id = backend_id; + + auto saver_initialize = + ggmlqnn_load_qnn_functionpointers<_pfn_QnnSaver_initialize *>(_loaded_lib_handle, "QnnSaver_initialize"); + if (nullptr != saver_initialize) { + error = saver_initialize(saver_config); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to saver_initialize,error %d", QNN_GET_ERROR_CODE(error)); + return 7; + } + } else { + GGMLHEXAGON_LOG_WARN("saver_initialize is null\n"); + } + + return 0; +} + +int qnn_instance::unload_backend() { + int dlclose_error = 0; + dlclose_error = dlclose(_loaded_lib_handle); + if (dlclose_error != 0) { + GGMLHEXAGON_LOG_WARN("failed to close QNN backend %d, error %s\n", _backend_id, dlerror()); + } + + return 0; +} + +int qnn_instance::load_system() { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + +#if !defined(__ANDROID__) && !defined(__linux__) + std::string system_lib_path = _lib_path + "QnnSystem.dll"; +#else + std::string system_lib_path = _lib_path + "libQnnSystem.so"; +#endif + GGMLHEXAGON_LOG_DEBUG("system_lib_path:%s\n", system_lib_path.c_str()); + + _system_lib_handle = dlopen(system_lib_path.c_str(), RTLD_NOW | RTLD_LOCAL); + if (nullptr == _system_lib_handle) { + GGMLHEXAGON_LOG_WARN("can not open QNN library %s, error: %s\n", system_lib_path.c_str(), dlerror()); + //re-try with default path of QNN binary runtime lib + _lib_path = std::string(g_hexagon_appcfg.runtime_libpath); +#if !defined(__ANDROID__) && !defined(__linux__) + system_lib_path = _lib_path + "QnnSystem.dll"; +#else + system_lib_path = _lib_path + "libQnnSystem.so"; +#endif + _system_lib_handle = dlopen(system_lib_path.c_str(), RTLD_NOW | RTLD_LOCAL); + if (nullptr == _system_lib_handle) { + GGMLHEXAGON_LOG_WARN("can not open QNN library %s, error: %s\n", system_lib_path.c_str(), dlerror()); + return 1; + } + } + + auto * get_providers = reinterpret_cast<_pfn_QnnSystemInterface_getProviders *>(dlsym( + _system_lib_handle, "QnnSystemInterface_getProviders")); + if (nullptr == get_providers) { + GGMLHEXAGON_LOG_WARN("can not load QNN symbol QnnSystemInterface_getProviders: %s\n", dlerror()); + return 2; + } + + uint32_t num_providers = 0; + const QnnSystemInterface_t ** provider_list = nullptr; + error = get_providers(&provider_list, &num_providers); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to get providers, error %d\n", QNN_GET_ERROR_CODE(error)); + return 3; + } + + if (num_providers != _required_num_providers) { + GGMLHEXAGON_LOG_WARN("providers is %d instead of required %d\n", num_providers, _required_num_providers); + return 4; + } + + if (nullptr == provider_list) { + GGMLHEXAGON_LOG_WARN("can not get providers\n"); + return 5; + } + + QNN_SYSTEM_INTERFACE_VER_TYPE qnn_system_interface; + bool found_valid_system_interface = false; + for (size_t idx = 0; idx < num_providers; idx++) { + if (QNN_SYSTEM_API_VERSION_MAJOR == + provider_list[idx]->systemApiVersion.major && + QNN_SYSTEM_API_VERSION_MINOR <= + provider_list[idx]->systemApiVersion.minor) { + found_valid_system_interface = true; + qnn_system_interface = provider_list[idx]->QNN_SYSTEM_INTERFACE_VER_NAME; + break; + } + } + if (!found_valid_system_interface) { + GGMLHEXAGON_LOG_WARN("unable to find a valid qnn system interface\n"); + return 6; + } else { + GGMLHEXAGON_LOG_INFO("find a valid qnn system interface\n"); + } + set_qnn_raw_system_interface(qnn_system_interface); + + _qnn_interface.set_qnn_system_interface(provider_list[0]); + + _qnn_interface.qnn_system_context_create(&_qnn_system_handle); + if (nullptr == _qnn_system_handle) { + GGMLHEXAGON_LOG_WARN("can not create QNN system contenxt\n"); + } else { + GGMLHEXAGON_LOG_INFO("initialize qnn system successfully\n"); + } + + return 0; +} + +int qnn_instance::unload_system() { + int result = 0; + + if (nullptr == _system_lib_handle) { + GGMLHEXAGON_LOG_DEBUG("system lib handle is null\n"); + return 1; + } + + if (nullptr != _qnn_system_handle) { + result = _qnn_interface.qnn_system_context_free(_qnn_system_handle); + if (result != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN system context\n"); + } + _qnn_system_handle = nullptr; + } + + int dlclose_error = dlclose(_system_lib_handle); + if (dlclose_error != 0) { + GGMLHEXAGON_LOG_WARN("failed to close QnnSystem library, error %s\n", dlerror()); + return 2; + } + + _system_lib_handle = nullptr; + + return result; +} + +static void ggmlqnn_sdk_logcallback(const char * fmt, + QnnLog_Level_t level, + uint64_t timestamp, + va_list argp) { + + if (0 == g_hexagon_appcfg.print_qnn_internal_log) + return; + + static std::mutex log_mutex; + static unsigned char s_ggmlqnn_sdk_logbuf[GGMLHEXAGON_LOGBUF_LEN]; + + const char * log_level_desc = ""; + switch (level) { + case QNN_LOG_LEVEL_ERROR: + log_level_desc = " ERROR "; + break; + case QNN_LOG_LEVEL_WARN: + log_level_desc = "WARNING"; + break; + case QNN_LOG_LEVEL_INFO: + log_level_desc = " INFO "; + break; + case QNN_LOG_LEVEL_DEBUG: + log_level_desc = " DEBUG "; + break; + case QNN_LOG_LEVEL_VERBOSE: + log_level_desc = "VERBOSE"; + break; + case QNN_LOG_LEVEL_MAX: + log_level_desc = "UNKNOWN"; + break; + } + + double ms = (double) timestamp / 1000000.0; + { + std::lock_guard lock(log_mutex); + memset(s_ggmlqnn_sdk_logbuf, 0, GGMLHEXAGON_LOGBUF_LEN); + vsnprintf(reinterpret_cast(s_ggmlqnn_sdk_logbuf), GGMLHEXAGON_LOGBUF_LEN, fmt, argp); + GGMLHEXAGON_LOG_DEBUG("%8.1fms [%-7s] %s\n", ms, log_level_desc, s_ggmlqnn_sdk_logbuf); + } +#if !GGMLHEXAGON_DEBUG + GGML_UNUSED(log_level_desc); + GGML_UNUSED(ms); +#endif +} + +int qnn_instance::qnn_init(const QnnSaver_Config_t ** saver_config) { + GGMLHEXAGON_LOG_DEBUG("enter qni_init\n"); + + _device_id = HEXAGON_BACKEND_GGML; + if (_backend_name.find("QnnCpu") != std::string::npos) { + _device_id = HEXAGON_BACKEND_QNNCPU; + } + if (_backend_name.find("QnnGpu") != std::string::npos) { + _device_id = HEXAGON_BACKEND_QNNGPU; + } + if (_backend_name.find("QnnHtp") != std::string::npos) { + _device_id = HEXAGON_BACKEND_QNNNPU; + } + if (HEXAGON_BACKEND_GGML == _device_id) { + GGMLHEXAGON_LOG_INFO("user specified qnn backend is ggml, skip QNN initialize"); + return 0; + } + + if (0 != load_system()) { + GGMLHEXAGON_LOG_WARN("can not load QNN system lib, pls check why?\n"); + return 1; + } else { + GGMLHEXAGON_LOG_DEBUG("load QNN system lib successfully\n"); + } + + std::string backend_lib_path = _lib_path + _backend_name; + + int is_load_ok = load_backend(backend_lib_path, saver_config); + if (0 != is_load_ok) { + GGMLHEXAGON_LOG_WARN("failed to load QNN backend\n"); + return 2; + } + + _qnn_interface.set_qnn_interface(_loaded_backend); +#if 1 + _qnn_interface.qnn_log_create(ggmlqnn_sdk_logcallback, _qnn_log_level, &_qnn_log_handle); +#else + _qnn_raw_interface.logCreate(ggmlqnn_sdk_logcallback, _qnn_log_level, &_qnn_log_handle); +#endif + if (nullptr == _qnn_log_handle) { + GGMLHEXAGON_LOG_WARN("why failed to initialize qnn log\n"); //NPU backend not work on Qualcomm SoC based low-end phone + return 3; + } else { + GGMLHEXAGON_LOG_DEBUG("initialize qnn log successfully\n"); + } + + std::vector temp_backend_config; + _qnn_interface.qnn_backend_create(_qnn_log_handle, + temp_backend_config.empty() ? nullptr : temp_backend_config.data(), + &_qnn_backend_handle); + if (nullptr == _qnn_backend_handle) { + GGMLHEXAGON_LOG_WARN("why failed to initialize qnn backend\n"); + return 4; + } else { + GGMLHEXAGON_LOG_DEBUG("initialize qnn backend successfully\n"); + } + + if (nullptr != _qnn_raw_interface.propertyHasCapability) { + auto qnnstatus = _qnn_raw_interface.propertyHasCapability(QNN_PROPERTY_GROUP_DEVICE); + if (QNN_PROPERTY_NOT_SUPPORTED == qnnstatus) { + GGMLHEXAGON_LOG_WARN("device property is not supported\n"); + } + if (QNN_PROPERTY_ERROR_UNKNOWN_KEY == qnnstatus) { + GGMLHEXAGON_LOG_WARN("device property is not known to backend\n"); + } + } + + Qnn_ErrorHandle_t qnnstatus = QNN_SUCCESS; + if (_device_id == HEXAGON_BACKEND_QNNNPU) { + const QnnDevice_PlatformInfo_t * p_info = nullptr; + qcom_socinfo soc_info = {}; + qnnstatus = _qnn_raw_interface.deviceGetPlatformInfo(nullptr, &p_info); + if (QNN_SUCCESS == qnnstatus) { + GGMLHEXAGON_LOG_INFO("device counts %d\n", p_info->v1.numHwDevices); + QnnDevice_HardwareDeviceInfo_t * infos = p_info->v1.hwDevices; + QnnHtpDevice_OnChipDeviceInfoExtension_t chipinfo = {}; + for (uint32_t i = 0; i < p_info->v1.numHwDevices; i++) { + GGMLHEXAGON_LOG_INFO("deviceID:%d, deviceType:%d, numCores %d\n", (int) infos[i].v1.deviceId, + (int) infos[i].v1.deviceType, (int) infos[i].v1.numCores); + QnnDevice_DeviceInfoExtension_t devinfo = infos[i].v1.deviceInfoExtension; + chipinfo = devinfo->onChipDevice; + size_t htp_arch = (size_t) chipinfo.arch; + GGMLHEXAGON_LOG_INFO("htp_type:%d(%s)\n", devinfo->devType, + (devinfo->devType == QNN_HTP_DEVICE_TYPE_ON_CHIP) ? "ON_CHIP" : ""); + soc_info = { chipinfo.socModel, htp_arch, chipinfo.vtcmSize, {} }; + } + _qnn_raw_interface.deviceFreePlatformInfo(nullptr, p_info); + } else { + GGMLHEXAGON_LOG_WARN("failed to get platform info, are we in emulator?\n"); + soc_info = { NONE, UNKNOWN_SM, 0, {} }; + } + + QnnHtpDevice_CustomConfig_t soc_customconfig; + soc_customconfig.option = QNN_HTP_DEVICE_CONFIG_OPTION_SOC; + soc_customconfig.socModel = soc_info.soc_model; + QnnDevice_Config_t soc_devconfig; + soc_devconfig.option = QNN_DEVICE_CONFIG_OPTION_CUSTOM; + soc_devconfig.customConfig = &soc_customconfig; + + /* + QnnHtpDevice_CustomConfig_t arch_customconfig; + arch_customconfig.option = QNN_HTP_DEVICE_CONFIG_OPTION_ARCH; + arch_customconfig.arch.arch = (QnnHtpDevice_Arch_t)soc_info.htp_arch; + arch_customconfig.arch.deviceId = 0; + QnnDevice_Config_t arch_devconfig; + arch_devconfig.option = QNN_DEVICE_CONFIG_OPTION_CUSTOM; + arch_devconfig.customConfig = &arch_customconfig; + */ + const QnnDevice_Config_t * p_deviceconfig[] = { &soc_devconfig, nullptr }; + qnnstatus = _qnn_raw_interface.deviceCreate(_qnn_log_handle, p_deviceconfig, &_qnn_device_handle); + } else { + qnnstatus = _qnn_interface.qnn_device_create(_qnn_log_handle, nullptr, &_qnn_device_handle); + } + if (QNN_SUCCESS != qnnstatus && QNN_DEVICE_ERROR_UNSUPPORTED_FEATURE != qnnstatus) { + GGMLHEXAGON_LOG_WARN("failed to create QNN device\n"); + } else { + GGMLHEXAGON_LOG_INFO("create device successfully\n"); + } + + if (PROFILE_OFF != _profile_level) { + GGMLHEXAGON_LOG_INFO("profiling turned on; level = %d", _profile_level); + if (PROFILE_BASIC == _profile_level) { + GGMLHEXAGON_LOG_INFO("basic profiling requested. creating Qnn Profile object\n"); + if (QNN_PROFILE_NO_ERROR != _qnn_raw_interface.profileCreate( + _qnn_backend_handle, QNN_PROFILE_LEVEL_BASIC, &_qnn_profile_handle)) { + GGMLHEXAGON_LOG_WARN("unable to create profile handle in the backend\n"); + return 5; + } else { + GGMLHEXAGON_LOG_DEBUG("initialize qnn profile successfully\n"); + } + } else if (PROFILE_DETAIL == _profile_level) { + GGMLHEXAGON_LOG_INFO("detailed profiling requested. Creating Qnn Profile object\n"); + if (QNN_PROFILE_NO_ERROR != _qnn_raw_interface.profileCreate( + _qnn_backend_handle, QNN_PROFILE_LEVEL_DETAILED, &_qnn_profile_handle)) { + GGMLHEXAGON_LOG_WARN("unable to create profile handle in the backend\n"); + return 6; + } else { + GGMLHEXAGON_LOG_DEBUG("initialize qnn profile successfully\n"); + } + } + } + +#if defined(__ANDROID__) || defined(__linux__) + std::filesystem::path full_path(std::string(g_hexagon_appcfg.runtime_libpath) + "libcdsprpc.so"); + full_path /= std::filesystem::path("libcdsprpc.so").filename(); + _rpc_lib_handle = dlopen(full_path.string().c_str(), RTLD_NOW | RTLD_LOCAL); + if (nullptr == _rpc_lib_handle) { + GGMLHEXAGON_LOG_WARN("failed to load %s\n", full_path.c_str()); + _rpc_lib_handle = dlopen("libcdsprpc.so", RTLD_NOW | RTLD_LOCAL); + } +#else + _rpc_lib_handle = dlopen("libcdsprpc.dll", RTLD_NOW | RTLD_LOCAL); +#endif + if (nullptr == _rpc_lib_handle) { + GGMLHEXAGON_LOG_WARN("failed to load qualcomm's rpc lib, error:%s\n", dlerror()); + return 7; + } else { + GGMLHEXAGON_LOG_DEBUG("load rpcmem lib successfully\n"); + set_rpcmem_initialized(true); + } + _pfn_rpc_mem_init = reinterpret_cast(dlsym(_rpc_lib_handle, "rpcmem_init")); + _pfn_rpc_mem_deinit = reinterpret_cast(dlsym(_rpc_lib_handle, "rpcmem_deinit")); + _pfn_rpc_mem_alloc = reinterpret_cast(dlsym(_rpc_lib_handle,"rpcmem_alloc")); + _pfn_rpc_mem_free = reinterpret_cast(dlsym(_rpc_lib_handle, "rpcmem_free")); + _pfn_rpc_mem_to_fd = reinterpret_cast(dlsym(_rpc_lib_handle,"rpcmem_to_fd")); + if (nullptr == _pfn_rpc_mem_alloc || nullptr == _pfn_rpc_mem_free || nullptr == _pfn_rpc_mem_to_fd) { + GGMLHEXAGON_LOG_WARN("unable to access symbols in QNN RPC lib, dlerror(): %s", dlerror()); + dlclose(_rpc_lib_handle); + return 8; + } + + if (nullptr != _pfn_rpc_mem_init) // make Qualcomm's SoC based low-end phone happy + _pfn_rpc_mem_init(); + + std::vector temp_context_config; + _qnn_interface.qnn_context_create(_qnn_backend_handle, _qnn_device_handle, + temp_context_config.empty() ? nullptr : temp_context_config.data(), + &_qnn_context_handle); + if (nullptr == _qnn_context_handle) { + GGMLHEXAGON_LOG_WARN("why failed to initialize qnn context, error:%s\n", strerror(errno)); + return 9; + } else { + GGMLHEXAGON_LOG_DEBUG("initialize qnn context successfully\n"); + } + + if (_backend_name.find("Htp") != std::string::npos) { + htp_print_info(); + htp_probe_rpc_meminfo(); + + if (0 != htp_init_perfinfra()) { + GGMLHEXAGON_LOG_WARN("initialize HTP performance failure"); + } + + htp_enter_performance_mode(); + htp_set_memory_grow_size(); + + if (enable_qnn_rpc()) { + GGMLHEXAGON_LOG_INFO("NPU RPC feature enabled with QNN-NPU backend"); + } else { + GGMLHEXAGON_LOG_INFO("NPU RPC feature disabled with QNN-NPU backend"); + } + } + + print_backend_info(); + + GGMLHEXAGON_LOG_DEBUG("leave qni_init\n"); + + return 0; +} + +int qnn_instance::qnn_finalize() { + int ret_status = 0; + Qnn_ErrorHandle_t error = QNN_SUCCESS; + + GGMLHEXAGON_LOG_INFO("enter %s\n", __func__); + ggmlqnn_reset_idx(); + + free_rpcmem(); + unregister_rpcmem(); + + if (nullptr != _pfn_rpc_mem_deinit) + _pfn_rpc_mem_deinit(); + + if (0 != dlclose(_rpc_lib_handle)) { + GGMLHEXAGON_LOG_WARN("failed to unload qualcomm's rpc lib, error:%s\n", dlerror()); + } else { + GGMLHEXAGON_LOG_DEBUG("succeed to close rpcmem lib\n"); + } + + if (nullptr != _qnn_context_handle) { + error = _qnn_interface.qnn_context_free(_qnn_context_handle, _qnn_profile_handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN context_handle: ID %u, error %d\n", + _qnn_interface.get_backend_id(), QNN_GET_ERROR_CODE(error)); + + } + _qnn_context_handle = nullptr; + } + + if (nullptr != _qnn_profile_handle) { + error = _qnn_interface.qnn_profile_free(_qnn_profile_handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN profile_handle: ID %u, error %d\n", + _qnn_interface.get_backend_id(), QNN_GET_ERROR_CODE(error)); + + } + _qnn_profile_handle = nullptr; + } + + if (nullptr != _qnn_device_handle) { + error = _qnn_interface.qnn_device_free(_qnn_device_handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN device_handle: ID %u, error %d\n", + _qnn_interface.get_backend_id(), QNN_GET_ERROR_CODE(error)); + + } + _qnn_device_handle = nullptr; + } + + if (nullptr != _qnn_backend_handle) { + error = _qnn_interface.qnn_backend_free(_qnn_backend_handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN backend_handle: ID %u, error %d\n", + _qnn_interface.get_backend_id(), QNN_GET_ERROR_CODE(error)); + } + _qnn_backend_handle = nullptr; + + } + + if (nullptr != _qnn_log_handle) { + error = _qnn_interface.qnn_log_free(_qnn_log_handle); + if (error != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to free QNN log_handle: ID %u, error %d\n", + _qnn_interface.get_backend_id(), QNN_GET_ERROR_CODE(error)); + } + _qnn_log_handle = nullptr; + } + + unload_backend(); + unload_system(); + + GGMLHEXAGON_LOG_INFO("leave %s\n", __func__); + return ret_status; +} + +int qnn_instance::init_qnn_graph(const std::string & graph_name, HEXAGONBackend device, size_t vtcm_size_in_mb, size_t hvx_threads) { + _graph_name = graph_name; + _device_id = device; + + //GGMLHEXAGON_LOG_DEBUG("[%s][%s]created", ggml_backend_hexagon_get_devname(device), graph_name.c_str()); + + Qnn_ErrorHandle_t error = QNN_SUCCESS; + if (HEXAGON_BACKEND_QNNNPU == device) { + QnnHtpGraph_CustomConfig_t hvx_config; + hvx_config.option = QNN_HTP_GRAPH_CONFIG_OPTION_NUM_HVX_THREADS; + hvx_config.numHvxThreads = hvx_threads; + QnnGraph_Config_t graph_hvx_config; + graph_hvx_config.option = QNN_GRAPH_CONFIG_OPTION_CUSTOM; + graph_hvx_config.customConfig = &hvx_config; + + QnnHtpGraph_CustomConfig_t dlbc_config = QNN_HTP_GRAPH_CUSTOM_CONFIG_INIT; + dlbc_config.option = QNN_HTP_GRAPH_CONFIG_OPTION_OPTIMIZATION; + dlbc_config.optimizationOption.type = QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC; + if (0 == g_hexagon_appcfg.enable_dlbc) + dlbc_config.optimizationOption.floatValue = 0.0; // set to 0.0 to turn off DLBC + else + dlbc_config.optimizationOption.floatValue = 1.0; // set to 1.0 to turn on DLBC + QnnGraph_Config_t graph_dlbc_config; + graph_dlbc_config.option = QNN_GRAPH_CONFIG_OPTION_CUSTOM; + graph_dlbc_config.customConfig = &dlbc_config; + + QnnHtpGraph_CustomConfig_t opt_config = QNN_HTP_GRAPH_CUSTOM_CONFIG_INIT; + opt_config.option = QNN_HTP_GRAPH_CONFIG_OPTION_OPTIMIZATION; + opt_config.optimizationOption.type = QNN_HTP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_OPTIMIZATION_FLAG; + opt_config.optimizationOption.floatValue = 1; // 1 / 3 + QnnGraph_Config_t graph_opt_config; + graph_opt_config.option = QNN_GRAPH_CONFIG_OPTION_CUSTOM; + graph_opt_config.customConfig = &opt_config; + + QnnHtpGraph_CustomConfig_t vtcm_config = QNN_HTP_GRAPH_CUSTOM_CONFIG_INIT; + vtcm_config.option = QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE; + vtcm_config.vtcmSizeInMB = vtcm_size_in_mb; + QnnGraph_Config_t graph_vtcm_config; + graph_vtcm_config.option = QNN_GRAPH_CONFIG_OPTION_CUSTOM; + graph_vtcm_config.customConfig = &vtcm_config; + + std::vector graph_configs; + graph_configs.push_back(&graph_hvx_config); + graph_configs.push_back(&graph_dlbc_config); + graph_configs.push_back(&graph_vtcm_config); + graph_configs.push_back(&graph_opt_config); + if (1 == g_hexagon_appcfg.precision_mode) { + QnnHtpGraph_CustomConfig_t fp16_config = QNN_HTP_GRAPH_CUSTOM_CONFIG_INIT; + fp16_config.option = QNN_HTP_GRAPH_CONFIG_OPTION_PRECISION; + fp16_config.precision = QNN_PRECISION_FLOAT16; + QnnGraph_Config_t graph_fp16_config; + graph_fp16_config.option = QNN_GRAPH_CONFIG_OPTION_CUSTOM; + graph_fp16_config.customConfig = &fp16_config; + graph_configs.push_back(&graph_fp16_config); + } + graph_configs.push_back(nullptr); + error = _qnn_interface.qnn_graph_create(_qnn_context_handle, graph_name.c_str(), graph_configs.data(), &_qnn_graph_handle); + //GGMLHEXAGON_LOG_DEBUG("[%s][%s]created graph %p", ggml_backend_hexagon_get_devname(device), graph_name.c_str(), _qnn_graph_handle); + } else { + error = _qnn_interface.qnn_graph_create(_qnn_context_handle, graph_name.c_str(), nullptr, &_qnn_graph_handle); + } + if (QNN_SUCCESS != error) { + GGMLHEXAGON_LOG_ERROR("[%s][%s]failed to create qnn graph, error: %s", + ggml_backend_hexagon_get_devname(device), graph_name.c_str(), + ggmlqnn_get_qnnerror_string(error)); + return error; + } + + GGMLHEXAGON_LOG_DEBUG("[%s]create graph %s succeed", ggml_backend_hexagon_get_devname(device), graph_name.c_str()); + if (HEXAGON_BACKEND_QNNNPU == device) { + htp_set_n_hvx_threads(hvx_threads); + } + return QNN_SUCCESS; +} + +int qnn_instance::init_qnn_graph(const char * graph_name, bool debug, uint8_t do_node_validation, + const QnnGraph_Config_t ** graph_configs) { + Qnn_ErrorHandle_t result = 0; + + if (nullptr == graph_name) { + GGMLHEXAGON_LOG_WARN("graph name is null\n"); + return 1; + } + + if (!_graph_name.empty()) { + GGMLHEXAGON_LOG_WARN("qnn model for graph %s already initialized\n", graph_name); + return 2; + } + + if (!do_node_validation) { + GGMLHEXAGON_LOG_WARN("node validation disabled, backend will not perform op validation prior to adding node\n"); + } + + _graph_name = graph_name; + _debug_tensor = debug; + _do_node_validations = do_node_validation; + + result = _qnn_raw_interface.graphCreate(_qnn_context_handle, + graph_name, + graph_configs, + &_qnn_graph_handle); + if (QNN_GRAPH_NO_ERROR != result || nullptr == _qnn_graph_handle) { + GGMLHEXAGON_LOG_WARN("failed to create graph in qnn context\n"); + return 3; + } else { + GGMLHEXAGON_LOG_DEBUG("succeed to create graph %s, %p\n", graph_name, _qnn_graph_handle); + } + + return 0; +} + +int qnn_instance::finalize_qnn_graph() { + if (nullptr != _qnn_graph_handle) { + if (_qnn_raw_interface.graphFinalize(_qnn_graph_handle, + _qnn_profile_handle, nullptr) + != QNN_GRAPH_NO_ERROR) { + GGMLHEXAGON_LOG_WARN("finalizing graph failure\n"); + return 1; + } + } else { + GGMLHEXAGON_LOG_DEBUG("qnn graph handle is null\n"); + } + + return 0; +} + +int qnn_instance::htp_init_perfinfra() { + QnnDevice_Infrastructure_t device_infra = nullptr; + Qnn_ErrorHandle_t error = _qnn_raw_interface.deviceGetInfrastructure(&device_infra); + if (QNN_SUCCESS != error) { + GGMLHEXAGON_LOG_WARN("failed to get qnn device infra\n"); + return 1; + } + + QnnHtpDevice_Infrastructure_t * htp_infra = static_cast(device_infra); + QnnHtpDevice_PerfInfrastructure_t * htp_perfinfra = &htp_infra->perfInfra; + uint32_t power_configid = 1; + uint32_t device_id = 0; + uint32_t core_id = 0; + htp_perfinfra->createPowerConfigId(device_id, core_id, &power_configid); + _qnn_htp_perfinfra = htp_perfinfra; + _qnn_htp_powerconfig_id = power_configid; + //TODO:hardcode to 0 and 0 although it's correct + _qnn_htp_device_id = device_id; + _qnn_htp_core_id = core_id; + + return 0; +} + +void qnn_instance::htp_probe_rpc_meminfo() { + size_t candidate_size = 0; + uint8_t * rpc_buffer = nullptr; + size_t probe_slots[] = {1024, 1536, 2048 - 48, 2048}; + size_t probe_counts = sizeof(probe_slots) / sizeof(size_t); + for (size_t idx = 0; idx < probe_counts; idx++) { + rpc_buffer = static_cast(alloc_rpcmem_internal(probe_slots[idx] * SIZE_IN_MB, 4)); + if (nullptr == rpc_buffer) { + GGMLHEXAGON_LOG_DEBUG("alloc rpcmem %d (MiB) failure during probe rpc memory info, reason: %s\n", probe_slots[idx], strerror(errno)); + break; + } else { + candidate_size = probe_slots[idx]; + free_rpcmem(rpc_buffer); + rpc_buffer = nullptr; + } + } + if (candidate_size > _rpcmem_capacity) + _rpcmem_capacity = candidate_size * SIZE_IN_MB; + + free_rpcmem(); + _rpcmem_usage = 0; + GGMLHEXAGON_LOG_INFO("capacity of rpc ion memory %d MiB\n", _rpcmem_capacity / SIZE_IN_MB); +} + +void qnn_instance::htp_print_info() { + const QnnDevice_PlatformInfo_t * p_info = nullptr; + _qnn_raw_interface.deviceGetPlatformInfo(nullptr, &p_info); + GGMLHEXAGON_LOG_DEBUG("HTP device counts %d", p_info->v1.numHwDevices); + QnnDevice_HardwareDeviceInfo_t * infos = p_info->v1.hwDevices; + for (size_t i = 0; i < p_info->v1.numHwDevices; i++) { + GGMLHEXAGON_LOG_DEBUG("HTP deviceID:%d, deviceType:%d, numCores %d", infos[i].v1.deviceId, + infos[i].v1.deviceType, infos[i].v1.numCores); + QnnDevice_DeviceInfoExtension_t devinfo = infos[i].v1.deviceInfoExtension; + QnnHtpDevice_OnChipDeviceInfoExtension_t chipinfo = devinfo->onChipDevice; + QnnHtpDevice_Arch_t htp_arch = chipinfo.arch; + GGMLHEXAGON_LOG_DEBUG("HTP_TYPE:%d(%s)", devinfo->devType, + (devinfo->devType == QNN_HTP_DEVICE_TYPE_ON_CHIP) ? "QNN_HTP_DEVICE_TYPE_ON_CHIP" : "QNN_HTP_DEVICE_TYPE_UNKNOWN"); + GGMLHEXAGON_LOG_DEBUG("qualcomm soc_model:%d(%s), htp_arch:%d(%s), vtcm_size:%d MiB," \ + "dlbc_support:%d, signedpd_support:%d", \ + chipinfo.socModel, ggmlhexagon_get_socmodel_desc(chipinfo.socModel), \ + htp_arch, ggmlhexagon_get_htparch_desc(htp_arch), chipinfo.vtcmSize, \ + chipinfo.dlbcSupport, chipinfo.signedPdSupport); + struct qcom_socinfo * socinfo = ggmlhexagon_get_socinfo_from_socmodel(chipinfo.socModel); + g_hexagon_mgr[HEXAGON_BACKEND_QNNNPU].socinfo = { chipinfo.socModel, htp_arch, chipinfo.vtcmSize, {}}; + if (nullptr != socinfo) { + memcpy(g_hexagon_mgr[HEXAGON_BACKEND_QNNNPU].socinfo.soc_desc, socinfo->soc_desc, sizeof(socinfo->soc_desc)); + GGMLHEXAGON_LOG_DEBUG("soc info:%s", socinfo->soc_desc); + } else { + memcpy(g_hexagon_mgr[HEXAGON_BACKEND_QNNNPU].socinfo.soc_desc, "unknown", 7); + GGMLHEXAGON_LOG_DEBUG("soc info:unknown"); + } + } + _qnn_raw_interface.deviceFreePlatformInfo(nullptr, p_info); +} + +void qnn_instance::print_backend_info() { + auto print_property = [&](const char * name, QnnProperty_Key_t property) { + auto ret = _qnn_raw_interface.propertyHasCapability(property); + + const char * status = "Unknown"; + if (ret == QNN_PROPERTY_SUPPORTED) { + status = "Yes"; + } else if (ret == QNN_PROPERTY_NOT_SUPPORTED) { + status = "No"; + } + + GGMLHEXAGON_LOG_INFO("%s: %s", name, status); + }; + + GGMLHEXAGON_LOG_INFO("QNN backend properties:"); + print_property("Create context from binary list", QNN_PROPERTY_CONTEXT_SUPPORT_CREATE_FROM_BINARY_LIST_ASYNC); + print_property("Dynamic batch", QNN_PROPERTY_GRAPH_SUPPORT_BATCH_MULTIPLE); + print_property("Early termination", QNN_PROPERTY_GRAPH_SUPPORT_EARLY_TERMINATION); + print_property("Dynamic dimensions", QNN_PROPERTY_TENSOR_SUPPORT_DYNAMIC_DIMENSIONS); + print_property("Blockwise quantization", QNN_PROPERTY_TENSOR_SUPPORT_QUANTIZATION_ENCODING_BLOCK); + print_property("Blockwise quantization with expansion", QNN_PROPERTY_TENSOR_SUPPORT_QUANTIZATION_ENCODING_BLOCKWISE_EXPANSION); + print_property("Vector quantization", QNN_PROPERTY_TENSOR_SUPPORT_QUANTIZATION_ENCODING_VECTOR); + print_property("Tensor sparsity", QNN_PROPERTY_TENSOR_SUPPORT_SPARSITY); + print_property("Updateable application tensor", QNN_PROPERTY_TENSOR_SUPPORT_UPDATEABLE_APP_TENSORS); + print_property("Updateable native tensor", QNN_PROPERTY_TENSOR_SUPPORT_UPDATEABLE_NATIVE_TENSORS); + print_property("Updateable static tensor", QNN_PROPERTY_TENSOR_SUPPORT_UPDATEABLE_STATIC_TENSORS); + print_property("Qnn group device", QNN_PROPERTY_GROUP_DEVICE); +} + +void qnn_instance::htp_set_memory_grow_size(size_t size) { + QnnHtpPerfInfrastructure_MemoryConfig_t grow_size_config = { + .option = QNN_HTP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_GROW_SIZE, + .memGrowSizeConfig = (uint32_t)size, + }; + + const QnnHtpPerfInfrastructure_MemoryConfig_t *memory_config[] = { + &grow_size_config, + nullptr, + }; + Qnn_ErrorHandle_t result = _qnn_htp_perfinfra->setMemoryConfig(_qnn_htp_device_id, _qnn_htp_core_id, memory_config); + if (QNN_SUCCESS != result) { + GGMLHEXAGON_LOG_WARN("failed to set HTP memory config"); + } else { + GGMLHEXAGON_LOG_INFO("succeed to set HTP memory config"); + } +} + +void qnn_instance::htp_set_n_hvx_threads(size_t n_threads) { + QnnHtpGraph_CustomConfig_t htp_hvx_thread_config = { + .option = QNN_HTP_GRAPH_CONFIG_OPTION_NUM_HVX_THREADS, + .numHvxThreads = n_threads, + }; + + QnnGraph_Config_t hvx_thread_config = { + .option = QNN_GRAPH_CONFIG_OPTION_CUSTOM, + .customConfig = &htp_hvx_thread_config, + }; + + const QnnGraph_Config_t * graph_configs[] = {&hvx_thread_config, nullptr}; + Qnn_ErrorHandle_t result = _qnn_raw_interface.graphSetConfig(_qnn_graph_handle, graph_configs); + if (QNN_SUCCESS != result) { + GGMLHEXAGON_LOG_WARN("failed to set QNN graph config: set hvx threads %d", n_threads); + } else { + //GGMLHEXAGON_LOG_DEBUG("succeed to set QNN graph config: set hvx threads %d", n_threads); + } +} + +void qnn_instance::htp_enter_performance_mode() { + QnnHtpPerfInfrastructure_PowerConfig_t dcvs_v3_config = { + .option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_V3, + .dcvsV3Config = + { + .contextId = _qnn_htp_powerconfig_id, + + .setDcvsEnable = 1, + .dcvsEnable = 0, + + .powerMode = QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_PERFORMANCE_MODE, + + .setSleepLatency = 1, + .sleepLatency = 40, + + .setSleepDisable = 1, + .sleepDisable = 1, + + .setBusParams = 1, + .busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + .busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + .busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + + .setCoreParams = 1, + .coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + .coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + .coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER, + }, + }; + + QnnHtpPerfInfrastructure_PowerConfig_t hmx_config = { + .option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_HMX_V2, + .hmxV2Config = + { + .hmxPickDefault = 0, + .hmxVoltageCornerMin = DCVS_EXP_VCORNER_MAX, + .hmxVoltageCornerTarget = DCVS_EXP_VCORNER_MAX, + .hmxVoltageCornerMax = DCVS_EXP_VCORNER_MAX, + .hmxPerfMode = QNN_HTP_PERF_INFRASTRUCTURE_CLK_PERF_HIGH, + }, + }; + + QnnHtpPerfInfrastructure_PowerConfig_t rpc_ctrl_config = { + .option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_CONTROL_LATENCY, + .rpcControlLatencyConfig = 100, + }; + + QnnHtpPerfInfrastructure_PowerConfig_t rpc_poll_config = { + .option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_POLLING_TIME, + .rpcPollingTimeConfig = 9999, + }; + + const QnnHtpPerfInfrastructure_PowerConfig_t * power_configs[] = { + &dcvs_v3_config, + &hmx_config, + &rpc_ctrl_config, + &rpc_poll_config, + nullptr, + }; + Qnn_ErrorHandle_t ret = _qnn_htp_perfinfra->setPowerConfig(_qnn_htp_powerconfig_id, power_configs); + if (ret != QNN_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed to set HTP power config"); + } else { + GGMLHEXAGON_LOG_INFO("succeed to set HTP power config"); + } +} + +static uint8_t * ggmlqnn_create_rpc_buffer(qnn_instance * instance, const ggml_tensor * ggml_tensor, Qnn_Tensor_t * qnn_tensor, bool b_copydata) { + if (nullptr == instance || nullptr == ggml_tensor || nullptr == qnn_tensor) { + GGMLHEXAGON_LOG_WARN("invalid params\n"); + return nullptr; + } + + uint8_t * qnn_rpcbuffer = static_cast(instance->alloc_rpcmem(ggml_nbytes(ggml_tensor), 4)); + if (nullptr == qnn_rpcbuffer) { + GGMLHEXAGON_LOG_WARN("alloc rpcmem failure, %s\n", strerror(errno)); + return nullptr; + } else { + GGMLHEXAGON_LOG_DEBUG("alloc rpcmem %p successfully\n", qnn_rpcbuffer); + } + if (b_copydata) + memcpy(qnn_rpcbuffer, ggml_tensor->data, ggml_nbytes(ggml_tensor)); + instance->register_rpcmem(qnn_rpcbuffer, qnn_tensor); + return qnn_rpcbuffer; +} + +static Qnn_OpConfig_t ggmlqnn_create_op_config(const char * name, const char * package, const char * type, + Qnn_Param_t * params, uint32_t num_params, + Qnn_Tensor_t * inputs, uint32_t num_inputs, + Qnn_Tensor_t * outputs, uint32_t num_outputs) { + + char opcfg_name[GGML_MAX_NAME] = {}; + + //ensure the opcfg name is unique + if (nullptr == name) { + snprintf(opcfg_name, GGML_MAX_NAME, "opcfg_%-8d", ggmlqnn_get_idx(QNN_OPCFG_INDEX)); + } else { + snprintf(opcfg_name, GGML_MAX_NAME, "opcfg_%s_%-8d", name, ggmlqnn_get_idx(QNN_OPCFG_INDEX)); + } + //GGMLHEXAGON_LOG_DEBUG("create qnn opconfig %s", opcfg_name); + ggmlqnn_inc_idx(QNN_OPCFG_INDEX); + + Qnn_OpConfigV1_t v1 = {opcfg_name, package, type, + num_params, params, + num_inputs, inputs, + num_outputs, outputs + }; + Qnn_OpConfig_t opcfg = {QNN_OPCONFIG_VERSION_1, {v1}}; + + return opcfg; +} + +static Qnn_Tensor_t * ggmlqnn_create_general_tensor(qnn_instance * instance, Qnn_GraphHandle_t graph_handle, + const ggml_tensor * tensor, const char * name, + Qnn_TensorType_t qnn_tensor_type, + Qnn_DataType_t qnn_data_type, + uint32_t rank, uint32_t * dims, + void * data, uint32_t data_size, + bool b_transpose = false) { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + char tensor_name[GGML_MAX_NAME] = {}; + + //ensure the tensor name is unique + if (nullptr == name) { + snprintf(tensor_name, GGML_MAX_NAME, "tensor_%-8d", ggmlqnn_get_idx(QNN_TENSOR_INDEX)); + } else { + snprintf(tensor_name, GGML_MAX_NAME, "tensor_%s%-8d", name, ggmlqnn_get_idx(QNN_TENSOR_INDEX)); + } + GGMLHEXAGON_LOG_DEBUG("init_tensor %s", tensor_name); + ggmlqnn_inc_idx(QNN_TENSOR_INDEX); + + uint32_t reverse_dims[GGML_MAX_DIMS] = {}; + uint32_t transpose_dims[GGML_MAX_DIMS] = {}; + uint32_t * tensor_dims = nullptr; + //case 1:use dims info from ggml tensor + if (nullptr != tensor) { + //there are different dimension order between ggml tensor and qnn tensor + for (size_t idx = 0; idx < rank; idx++) { + reverse_dims[idx] = (uint32_t)tensor->ne[rank - 1 - idx]; + } + tensor_dims = reverse_dims; + } + //case 2: use user's specified tensor_dims + if (nullptr != dims) { + tensor_dims = dims; + } + //case 3: transpose for dst tensor + if (b_transpose) { + GGML_ASSERT(tensor != nullptr); //ensure ggml_tensor is not nullptr for this special case + + ggmlqnn_get_qnn_dimensions_from_ggml_dimensions(transpose_dims, reverse_dims, ggml_n_dims(tensor)); + tensor_dims = transpose_dims; + } + + Qnn_Tensor_t qnn_tensor = { + .version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = tensor_name, + .type = qnn_tensor_type, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = qnn_data_type, + .quantizeParams = {.encodingDefinition = QNN_DEFINITION_UNDEFINED, + .quantizationEncoding = QNN_QUANTIZATION_ENCODING_UNDEFINED, + .scaleOffsetEncoding = {.scale = 0.0000000000000000f, .offset = 0} + }, + .rank = rank, + .dimensions = tensor_dims, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, .dataSize = 0} + } + }; + Qnn_Tensor_t * p_qnn_tensor = (Qnn_Tensor_t *)calloc(1, sizeof(Qnn_Tensor_t)); + if (nullptr == p_qnn_tensor) { + GGMLHEXAGON_LOG_WARN("calloc failed"); + return nullptr; + } + error = ggmlqnn_deep_copy_qnntensor(qnn_tensor, *p_qnn_tensor); + if (error != QNN_SUCCESS) { + free(p_qnn_tensor); + GGMLHEXAGON_LOG_WARN("init tensor failed"); + return nullptr; + } + + bool enable_npu_rpc = (instance->enable_qnn_rpc() && instance->get_device_id() == HEXAGON_BACKEND_QNNNPU); + if (enable_npu_rpc) { + QNN_VER_PTR(*p_qnn_tensor)->memType = QNN_TENSORMEMTYPE_MEMHANDLE; + QNN_VER_PTR(*p_qnn_tensor)->clientBuf = {.data=nullptr, .dataSize=0}; + } else { + QNN_VER_PTR(*p_qnn_tensor)->clientBuf = {data, data_size}; + } + QNN_INTERFACE_VER_TYPE qnn_raw_interface = instance->get_qnn_raw_interface(); + CHECK_QNN_API(error, qnn_raw_interface.tensorCreateGraphTensor(graph_handle, p_qnn_tensor)); + + return p_qnn_tensor; +} + +static Qnn_Tensor_t * ggmlqnn_create_compute_tensor(qnn_instance * instance, Qnn_GraphHandle_t graph_handle, + const ggml_tensor * tensor, Qnn_TensorType_t tensor_type) { + uint32_t dimensions[] = {(uint32_t) tensor->ne[0], (uint32_t) tensor->ne[1], + (uint32_t) tensor->ne[2], (uint32_t) tensor->ne[3]}; + Qnn_DataType_t qnn_data_type = QNN_DATATYPE_FLOAT_32; + Qnn_TensorType_t qnn_tensor_type = QNN_TENSOR_TYPE_APP_WRITE; + + if (0 == tensor->flags) { + qnn_tensor_type = tensor_type; + } else { + if (tensor->flags & GGML_TENSOR_FLAG_INPUT) { + qnn_tensor_type = QNN_TENSOR_TYPE_APP_WRITE; + } else if (tensor->flags & GGML_TENSOR_FLAG_OUTPUT) { + qnn_tensor_type = QNN_TENSOR_TYPE_APP_READ; + } + } + + qnn_data_type = ggmlqnn_datatype_from_ggml_datatype(tensor->type); + Qnn_Tensor_t * p_qnn_tensor = ggmlqnn_create_general_tensor(instance, graph_handle, tensor, nullptr, + qnn_tensor_type, qnn_data_type, + ggml_n_dims(tensor), dimensions, + nullptr, 0); + return p_qnn_tensor; +} + +// ================================================================================================= +// section-6: hwaccel approach through QNN: offload GGML op to QNN backend +// ================================================================================================= +/* + * provide a general skeleton to offload ggml op to QNN backend: perform element-wise + * operation on 1/2 input tensors and 1 output tensors +*/ +static void ggmlqnn_compute_elementwise(ggml_backend_hexagon_context * ctx, ggml_tensor * op) { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + qnn_instance * instance = nullptr; + Qnn_GraphHandle_t graph_handle = nullptr; + Qnn_Tensor_t * p_tensor0 = nullptr; + Qnn_Tensor_t * p_tensor1 = nullptr; + Qnn_Tensor_t * p_tensor2 = nullptr; + const ggml_tensor * src0 = op->src[0]; + const ggml_tensor * src1 = op->src[1]; + ggml_tensor * dst = op; + + GGMLQNN_CHECK_PARAMS(ctx, src0, src1, dst); + instance = ctx->instance; + QNN_INTERFACE_VER_TYPE qnn_raw_interface = ctx->raw_interface; + size_t qnn_op_index = ggmlhexagon_get_op_index(op); + const char * qnn_op_name = ggmlqnn_k_op_caps[qnn_op_index].qnn_op_name; + size_t input_param_count = ggmlqnn_k_op_caps[qnn_op_index].input_param_count; + const char * ggml_original_opname = ggml_op_name(op->op); + std::string ggml_op_name_string = std::string("ggml_") + ggml_original_opname; + const char * ggml_op_name = ggml_op_name_string.c_str(); + + std::string graph_name; + ggmlhexagon_get_opkey_from_op(op, graph_name); + + int input_size = ggml_nbytes(src0); + if (nullptr != src1) + input_size += ggml_nbytes(src1); + hexagon_perf op_perf(graph_name, ggml_original_opname, input_size, ggml_nbytes(dst)); + op_perf.start(); + + bool enable_npu_rpc = instance->enable_qnn_rpc() && ctx->device == HEXAGON_BACKEND_QNNNPU; + if (ctx->qnn_singlenode_graph_map.find(graph_name) != ctx->qnn_singlenode_graph_map.end()) { + //retrieve computational resource from cached QNN graph + qnn_singlenode_res_t & graph_item = ctx->qnn_singlenode_graph_map[graph_name]; + graph_handle = std::get<0>(graph_item); + qnn_ptensors_t & ptensors = std::get<1>(graph_item); + p_tensor0 = ptensors[0]; + if (2 == input_param_count) { + p_tensor1 = ptensors[1]; + p_tensor2 = ptensors[2]; + } else { + //now p_tensor1 is nullptr + p_tensor2 = ptensors[1]; + } + } else { + GGML_ASSERT(instance->get_device_id() == ctx->device); + GGMLHEXAGON_LOG_INFO("graph name %s", graph_name.c_str()); + //create QNN graph + error = instance->init_qnn_graph(graph_name, static_cast(ctx->device), + g_hexagon_appcfg.vtcm_size_in_mb, + g_hexagon_appcfg.hvx_threads); + if (QNN_SUCCESS != error) { + GGMLHEXAGON_LOG_WARN("can't create qnn graph handle with graph name %s, error = %d\n", graph_name.c_str(), error); + return; + } + graph_handle = instance->get_qnn_graph_handle(); + + //GGMLHEXAGON_LOG_DEBUG("graph_handle %p", graph_handle); + //create computational tensor + p_tensor0 = ggmlqnn_create_compute_tensor(instance, graph_handle, src0, QNN_TENSOR_TYPE_APP_WRITE); + if (2 == input_param_count) { + p_tensor1 = ggmlqnn_create_compute_tensor(instance, graph_handle, src1, QNN_TENSOR_TYPE_APP_WRITE); + } + p_tensor2 = ggmlqnn_create_compute_tensor(instance, graph_handle, dst, QNN_TENSOR_TYPE_APP_READ); + + //compose QNN graph + qnn_tensors_t input_tensors; + input_tensors.reserve(input_param_count); + input_tensors.push_back(*p_tensor0); + if (2 == input_param_count) { + input_tensors.push_back(*p_tensor1); + } + Qnn_Tensor_t output_tensors[] = { + *p_tensor2 + }; + Qnn_OpConfig_t op_config = ggmlqnn_create_op_config(ggml_op_name, + QNN_OP_PACKAGE_NAME_QTI_AISW, + qnn_op_name, nullptr, 0, + input_tensors.data(), + input_param_count, output_tensors, + 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, op_config)); + //finalize QNN graph + CHECK_QNN_API(error, qnn_raw_interface.graphFinalize(graph_handle, nullptr, nullptr)); + + //cache QNN graph + qnn_ptensors_t qnn_elementwise_tensors; + qnn_elementwise_tensors.reserve(input_param_count + 1); + + qnn_elementwise_tensors.push_back(p_tensor0); + if (2 == input_param_count) { + qnn_elementwise_tensors.push_back(p_tensor1); + } + qnn_elementwise_tensors.push_back(p_tensor2); + auto graph_item = std::make_tuple(graph_handle, qnn_elementwise_tensors); + ctx->qnn_singlenode_graph_map[graph_name] = graph_item; + } + + if (enable_npu_rpc) { + uint8_t * qnn_buffer_0 = static_cast(instance->get_rpcmem_from_memhandle( + QNN_VER_PTR(*p_tensor0)->memHandle)); + GGMLHEXAGON_LOG_DEBUG("qnn_rpcbuffer_0 = %p\n", qnn_buffer_0); + if (nullptr != qnn_buffer_0) { + memcpy(qnn_buffer_0, src0->data, ggml_nbytes(src0)); + } + + if (2 == input_param_count) { + uint8_t * qnn_buffer_1 = static_cast(instance->get_rpcmem_from_memhandle( + QNN_VER_PTR(*p_tensor1)->memHandle)); + GGMLHEXAGON_LOG_DEBUG("qnn_rpcbuffer_1 = %p\n", qnn_buffer_1); + if (nullptr != qnn_buffer_1) { + memcpy(qnn_buffer_1, src1->data, ggml_nbytes(src1)); + } + } + } else { + QNN_VER_PTR(*p_tensor0)->clientBuf = {src0->data, ggmlqnn_get_tensor_data_size(src0)}; + if (2 == input_param_count) { + QNN_VER_PTR(*p_tensor1)->clientBuf = {src1->data, ggmlqnn_get_tensor_data_size(src1)}; + } + QNN_VER_PTR(*p_tensor2)->clientBuf = {dst->data, ggmlqnn_get_tensor_data_size(dst)}; + } + + qnn_tensors_t input_tensors; + input_tensors.reserve(input_param_count); + input_tensors.push_back(*p_tensor0); + if (2 == input_param_count) { + input_tensors.push_back(*p_tensor1); + } + Qnn_Tensor_t output_tensors[] = { + *p_tensor2 + }; + CHECK_QNN_API(error, qnn_raw_interface.graphExecute(graph_handle, + input_tensors.data(), input_param_count, + output_tensors, 1, + nullptr, nullptr)); + if (enable_npu_rpc) { + uint8_t * qnn_buffer_2 = static_cast(instance->get_rpcmem_from_memhandle(QNN_VER_PTR(*p_tensor2)->memHandle)); + if (nullptr != qnn_buffer_2) { + memcpy(dst->data, qnn_buffer_2, ggml_nbytes(dst)); + } + } + + op_perf.info(); +} + +/* + * this function is AI-assisted code from Grok 3 for purpose of offload 4d matrix mulmat to QNN backend + * various UT has verified and succeed but failed in CT of test-backend-ops + * + * the logic of ggmlqnn_compute_mul_mat_4d is similar to ggmlqnn_compute_mul_mat but much more complicated + * than ggmlqnn_compute_mul_mat, so it's a standalone function. + * it will be combined with ggmlqnn_compute_mul_mat in the future + */ +static void ggmlqnn_compute_mul_mat_4d(ggml_backend_hexagon_context * ctx, ggml_tensor * op) { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + qnn_instance * instance = ctx->instance; + QNN_INTERFACE_VER_TYPE qnn_raw_interface = ctx->raw_interface; + + const ggml_tensor * src0 = op->src[0]; + const ggml_tensor * src1 = op->src[1]; + ggml_tensor * dst = op; + + GGMLQNN_CHECK_PARAMS(ctx, src0, src1, dst); + GGML_ASSERT(ggml_n_dims(src0) == 4 && ggml_n_dims(src1) == 4); + + hexagon_perf op_perf("ggmlqnn_compute_mul_mat_4d"); + op_perf.start(); + + std::string graph_name; + ggmlhexagon_get_opkey_from_op(op, graph_name); + GGMLHEXAGON_LOG_DEBUG("graph name %s\n", graph_name.c_str()); + + ggmlhexagon_print_tensors_info(__func__, ctx, src0, src1, dst); + + Qnn_GraphHandle_t graph_handle = nullptr; + Qnn_Tensor_t * p_tensor0 = nullptr; + Qnn_Tensor_t * p_reshape0_out = nullptr; + Qnn_Tensor_t * p_tile0_out = nullptr; + Qnn_Tensor_t * p_tensor1 = nullptr; + Qnn_Tensor_t * p_permute1_out = nullptr; + Qnn_Tensor_t * p_reshape1_out = nullptr; + Qnn_Tensor_t * p_matmul_out = nullptr; + Qnn_Tensor_t * p_reshape2_out = nullptr; + + if (ctx->qnn_singlenode_graph_map.find(graph_name) != ctx->qnn_singlenode_graph_map.end()) { + qnn_singlenode_res_t & graph_item = ctx->qnn_singlenode_graph_map[graph_name]; + graph_handle = std::get<0>(graph_item); + qnn_ptensors_t & tensors = std::get<1>(graph_item); + p_tensor0 = tensors[0]; + p_reshape0_out = tensors[1]; + p_tile0_out = tensors[2]; + p_tensor1 = tensors[3]; + p_permute1_out = tensors[4]; + p_reshape1_out = tensors[5]; + p_matmul_out = tensors[6]; + p_reshape2_out = tensors[7]; + } else { + CHECK_QNN_API(error, qnn_raw_interface.graphCreate(instance->get_qnn_context_handle(), graph_name.c_str(), NULL, &graph_handle)); + + // Define dimensions + uint32_t K = src0->ne[0]; // Inner dimension + uint32_t M = src0->ne[1]; // Rows of src0 + uint32_t N = src1->ne[1]; // Columns of src1 + uint32_t B0 = src0->ne[2] * src0->ne[3]; // src0 batch + uint32_t B1 = src1->ne[2] * src1->ne[3]; // src1 batch (drives output) + + // Validate K only + GGML_ASSERT(src0->ne[0] == src1->ne[0]); // K must match + + // src0: [K, M, H0, B0] -> QNN: [B0, H0, M, K] + uint32_t src0_dims[] = {static_cast(src0->ne[3]), static_cast(src0->ne[2]), + static_cast(src0->ne[1]), static_cast(src0->ne[0]) + }; + p_tensor0 = ggmlqnn_create_general_tensor(instance, graph_handle, src0, "input0", + QNN_TENSOR_TYPE_APP_WRITE, QNN_DATATYPE_FLOAT_32, 4, + src0_dims, nullptr, 0); + + // Reshape src0 to [B0, M, K] + uint32_t reshape0_out_dims[] = {B0, M, K}; + p_reshape0_out = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "reshape0_out", + QNN_TENSOR_TYPE_NATIVE, QNN_DATATYPE_FLOAT_32, 3, + reshape0_out_dims, nullptr, 0); + + Qnn_Tensor_t reshape0_inputs[] = {*p_tensor0}; + Qnn_Tensor_t reshape0_outputs[] = {*p_reshape0_out}; + Qnn_OpConfig_t reshape0_op = ggmlqnn_create_op_config("reshape0", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_RESHAPE, nullptr, 0, + reshape0_inputs, 1, reshape0_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, reshape0_op)); + + // Tile src0 to match B1: [B0, M, K] -> [B1, M, K] + uint32_t tile0_out_dims[] = {B1, M, K}; + p_tile0_out = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "tile0_out", + QNN_TENSOR_TYPE_NATIVE, QNN_DATATYPE_FLOAT_32, 3, + tile0_out_dims, nullptr, 0); + + uint32_t tile_multiples[] = {B1 / B0, 1, 1}; + uint32_t tile_dims[] = {3}; + Qnn_Tensor_t * p_tile_multiples = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "tile_multiples", + QNN_TENSOR_TYPE_STATIC, QNN_DATATYPE_UINT_32, 1, + tile_dims, tile_multiples, sizeof(tile_multiples)); + + Qnn_Param_t tile_params[] = {{.paramType = QNN_PARAMTYPE_TENSOR, .name = "multiples", .tensorParam = *p_tile_multiples}}; + Qnn_Tensor_t tile0_inputs[] = {*p_reshape0_out}; + Qnn_Tensor_t tile0_outputs[] = {*p_tile0_out}; + Qnn_OpConfig_t tile0_op = ggmlqnn_create_op_config("tile0", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_TILE, tile_params, 1, + tile0_inputs, 1, tile0_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, tile0_op)); + + // src1: [N, K, H1, B1] -> QNN: [B1, H1, N, K] + uint32_t src1_dims[] = {static_cast(src1->ne[3]), static_cast(src1->ne[2]), + static_cast(src1->ne[1]), static_cast(src1->ne[0]) + }; + p_tensor1 = ggmlqnn_create_general_tensor(instance, graph_handle, src1, "input1", + QNN_TENSOR_TYPE_APP_WRITE, QNN_DATATYPE_FLOAT_32, 4, + src1_dims, nullptr, 0); + + + // Permute src1 to [B1, H1, K, N] + uint32_t perm_data[] = {0, 1, 3, 2}; + uint32_t perm_dims[] = {4}; + Qnn_Tensor_t * p_perm = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "perm", + QNN_TENSOR_TYPE_STATIC, QNN_DATATYPE_UINT_32, 1, + perm_dims, perm_data, sizeof(perm_data)); + + uint32_t permute1_out_dims[] = {static_cast(src1->ne[3]), static_cast(src1->ne[2]), + static_cast(src1->ne[0]), static_cast(src1->ne[1]) + }; + p_permute1_out = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "permute1_out", + QNN_TENSOR_TYPE_NATIVE, QNN_DATATYPE_FLOAT_32, 4, + permute1_out_dims, nullptr, 0); + + Qnn_Param_t permute1_params[] = {{.paramType = QNN_PARAMTYPE_TENSOR, .name = "perm", .tensorParam = *p_perm}}; + Qnn_Tensor_t permute1_inputs[] = {*p_tensor1}; + Qnn_Tensor_t permute1_outputs[] = {*p_permute1_out}; + Qnn_OpConfig_t permute1_op = ggmlqnn_create_op_config("permute1", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_TRANSPOSE, permute1_params, 1, + permute1_inputs, 1, permute1_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, permute1_op)); + + // Reshape src1 to [B1, K, N] + uint32_t reshape1_out_dims[] = {B1, K, N}; + p_reshape1_out = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "reshape1_out", + QNN_TENSOR_TYPE_NATIVE, QNN_DATATYPE_FLOAT_32, 3, + reshape1_out_dims, nullptr, 0); + + Qnn_Tensor_t reshape1_inputs[] = {*p_permute1_out}; + Qnn_Tensor_t reshape1_outputs[] = {*p_reshape1_out}; + Qnn_OpConfig_t reshape1_op = ggmlqnn_create_op_config("reshape1", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_RESHAPE, nullptr, 0, + reshape1_inputs, 1, reshape1_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, reshape1_op)); + + // MatMul: [B1, M, K] x [B1, K, N] -> [B1, M, N] + uint32_t matmul_out_dims[] = {B1, M, N}; + p_matmul_out = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "matmul_out", + QNN_TENSOR_TYPE_NATIVE, QNN_DATATYPE_FLOAT_32, 3, + matmul_out_dims, nullptr, 0); + + Qnn_Tensor_t matmul_inputs[] = {*p_tile0_out, *p_reshape1_out}; + Qnn_Tensor_t matmul_outputs[] = {*p_matmul_out}; + Qnn_OpConfig_t matmul_op = ggmlqnn_create_op_config("matmul", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_MAT_MUL, nullptr, 0, + matmul_inputs, 2, matmul_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, matmul_op)); + + // Output: [N, M, H1, B1] -> QNN: [B1, H1, M, N] + uint32_t reshape2_out_dims[] = {static_cast(dst->ne[3]), static_cast(dst->ne[2]), + static_cast(dst->ne[1]), static_cast(dst->ne[0]) + }; + p_reshape2_out = ggmlqnn_create_general_tensor(instance, graph_handle, dst, "output", + QNN_TENSOR_TYPE_APP_READ, QNN_DATATYPE_FLOAT_32, 4, + reshape2_out_dims, nullptr, 0); + + Qnn_Tensor_t reshape2_inputs[] = {*p_matmul_out}; + Qnn_Tensor_t reshape2_outputs[] = {*p_reshape2_out}; + Qnn_OpConfig_t reshape2_op = ggmlqnn_create_op_config("reshape2", QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_RESHAPE, nullptr, 0, + reshape2_inputs, 1, reshape2_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, reshape2_op)); + + // Finalize + CHECK_QNN_API(error, qnn_raw_interface.graphFinalize(graph_handle, NULL, NULL)); + + // Cache + qnn_ptensors_t ggml_op_mulmat_tensors = {p_tensor0, p_reshape0_out, p_tile0_out, p_tensor1, + p_permute1_out, p_reshape1_out, p_matmul_out, p_reshape2_out + }; + ctx->qnn_singlenode_graph_map[graph_name] = std::make_tuple(graph_handle, ggml_op_mulmat_tensors); + } + + // Execute + QNN_VER_PTR(*p_tensor0)->clientBuf = {src0->data, static_cast(ggml_nbytes(src0))}; + QNN_VER_PTR(*p_tensor1)->clientBuf = {src1->data, static_cast(ggml_nbytes(src1))}; + QNN_VER_PTR(*p_reshape2_out)->clientBuf = {dst->data, static_cast(ggml_nbytes(dst))}; + + Qnn_Tensor_t input_tensors[] = {*p_tensor0, *p_tensor1}; + Qnn_Tensor_t output_tensors[] = {*p_reshape2_out}; + CHECK_QNN_API(error, qnn_raw_interface.graphExecute(graph_handle, input_tensors, 2, output_tensors, 1, NULL, NULL)); + + op_perf.info(); +} + +/* + * @brief performs matrix multiplication with FP32 & quantized weights and floating-point inputs + * using the QNN backend. this function performs matrix multiplication of the input tensor + * `src1` and the weight tensor `src0`, handling transposing, and quantization as needed, + * and stores the result in the destination tensor `dst`. + * + there are two key-points in properly handling how to offload mulmat to the QNN + 1. transpose + a 3x2 f32 matrix which means 3 rows and 2 columns. in ggml, it could be created from: + struct ggml_tensor* matrix = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 2, 3); + which like this: + +---+---+ + | 0 | 1 | + +---+---+ + | 2 | 3 | + +---+---+ + | 4 | 5 | + +---+---+ + with + ne[0] = 2 + ne[1] = 3 + there are different dimension order between ggml tensor and qnn tensor + + 2. QNN's MatMul can only support input tensors with rank >= 2 + + in the all, there is gap between ggml mulmat and QNN mulmat,we need to perform a transpose + operation when offloading mulmat to QNN backend. this implementation will handle transpose + in func ggmlqnn_compute_create_general_tensor() + + * @param ctx the context of backend + * @param op the destination tensor where the result of the matrix multiplication will be stored. + * + * @note the logic of ggmlqnn_compute_mul_mat is similar to ggmlqnn_compute_op_two_tensors but much more complicated + * than ggmlqnn_compute_op_two_tensors. so it's a standalone function. accordingly, this is another + * typical skeleton for offload other ggml ops to QNN backend. MUL_MAT take most of the compute + * time (about 95%).so to speed up llama inference, should focus on this func. there are three kinds + * of MUL_MAT to compute: + * mul_mat_f32: both src0 and src1 are F32, this will be naturally handled in QNN backend + * mul_mat_f16_f32: src0 is F16 and src1 is F32, f16 in src0 -> f32 in src0', then src0' * src1 + * mul_mat_q_f32: src0 is quantized (Q4_0, Q4_1, Q6_K...) + * and src1 is F32, src0 -> f32 in src0', then src0' * src1 +*/ +static void ggmlqnn_compute_mul_mat(ggml_backend_hexagon_context * ctx, ggml_tensor * op) { + Qnn_ErrorHandle_t error = QNN_SUCCESS; + qnn_instance * instance = nullptr; + Qnn_GraphHandle_t graph_handle = nullptr; + Qnn_Tensor_t * p_tensor0 = nullptr; + Qnn_Tensor_t * p_tensor1 = nullptr; + Qnn_Tensor_t * p_tensor2 = nullptr; + Qnn_Tensor_t * p_param_tensor = nullptr; + Qnn_Tensor_t * p_tensor2_transpose = nullptr; + const ggml_tensor * src0 = op->src[0]; + const ggml_tensor * src1 = op->src[1]; + ggml_tensor * dst = op; + + GGMLQNN_CHECK_PARAMS(ctx, src0, src1, dst); + instance = ctx->instance; + QNN_INTERFACE_VER_TYPE qnn_raw_interface = ctx->raw_interface; + + const enum ggml_type src0_type = src0->type; + const uint32_t src0_rank = ggml_n_dims(src0); + const uint32_t src1_rank = ggml_n_dims(src1); + const char * ggml_original_opname = ggml_op_name(op->op); + ggmlhexagon_print_tensors_info(__func__, ctx, src0, src1, dst); + + std::string graph_name; + ggmlhexagon_get_opkey_from_op(op, graph_name); + + int input_size = ggml_nbytes(src0); + if (nullptr != src1) + input_size += ggml_nbytes(src1); + hexagon_perf op_perf(graph_name, ggml_original_opname, input_size, ggml_nbytes(dst)); + op_perf.start(); + + GGML_ASSERT(src0_rank == src1_rank); + GGML_ASSERT(src0_rank >= 2); //QNN SDK's limitation, make QNN SDK happy + if (4 == src0_rank) { + return ggmlqnn_compute_mul_mat_4d(ctx, op); + } + + void * wdata = ggmlhexagon_type_trait(ctx, op); + const size_t desired_size = ctx->desired_size; + + if (ctx->qnn_singlenode_graph_map.find(graph_name) != ctx->qnn_singlenode_graph_map.end()) { + //retrieve computational resource from cached QNN graph + qnn_singlenode_res_t & graph_item = ctx->qnn_singlenode_graph_map[graph_name]; + graph_handle = std::get<0>(graph_item); + qnn_ptensors_t &tensors = std::get<1>(graph_item); + p_tensor0 = tensors[0]; + p_tensor1 = tensors[1]; + p_tensor2 = tensors[2]; + p_param_tensor = tensors[3]; + p_tensor2_transpose = tensors[4]; + } else { + //create QNN graph + GGMLHEXAGON_LOG_INFO("graph name %s", graph_name.c_str()); + error = instance->init_qnn_graph(graph_name, static_cast(ctx->device), + g_hexagon_appcfg.vtcm_size_in_mb, + g_hexagon_appcfg.hvx_threads); + if (QNN_SUCCESS != error) { + GGMLHEXAGON_LOG_WARN("can't create qnn graph handle with graph name %s, error = %d\n", + graph_name.c_str(), error); + return; + } + graph_handle = instance->get_qnn_graph_handle(); + + //create computational tensor + p_tensor0 = ggmlqnn_create_general_tensor(instance, graph_handle, src0, nullptr, + QNN_TENSOR_TYPE_APP_WRITE, + QNN_DATATYPE_FLOAT_32, src0_rank, + nullptr, nullptr, 0); + p_tensor1 = ggmlqnn_create_general_tensor(instance, graph_handle, src1, nullptr, + QNN_TENSOR_TYPE_APP_WRITE, + QNN_DATATYPE_FLOAT_32, src0_rank, + nullptr, nullptr, 0); + p_tensor2 = ggmlqnn_create_general_tensor(instance, graph_handle, dst, nullptr, + QNN_TENSOR_TYPE_APP_READ, + QNN_DATATYPE_FLOAT_32, src0_rank, + nullptr, nullptr, 0); + + //create param tensor for offload 2d/3d/4d matrix multiplication + const uint32_t param_tensor_data[GGML_MAX_DIMS][GGML_MAX_DIMS] = { + {0}, + {1, 0}, + {0, 2, 1}, + {0, 1, 3, 2}, + }; + uint32_t param_tensor_dims[1] = {src0_rank}; + p_param_tensor = ggmlqnn_create_general_tensor(instance, graph_handle, nullptr, "param", + QNN_TENSOR_TYPE_STATIC, + QNN_DATATYPE_UINT_32, 1, + param_tensor_dims, + (void *) (param_tensor_data[src0_rank - 1]), + src0_rank * sizeof(uint32_t)); + + //create transpose tensor + p_tensor2_transpose = ggmlqnn_create_general_tensor(instance, graph_handle, dst, + "transpose", + QNN_TENSOR_TYPE_NATIVE, + QNN_DATATYPE_FLOAT_32, src0_rank, + nullptr, nullptr, 0, true); + + //compose QNN graph: add mulmat node + Qnn_Param_t out_0_params[] = { + {.paramType = QNN_PARAMTYPE_SCALAR, .name = QNN_OP_MAT_MUL_PARAM_TRANSPOSE_IN1, .scalarParam = { + .dataType = QNN_DATATYPE_BOOL_8, .bool8Value = 1}}}; + Qnn_Tensor_t out_0_inputs[] = {*p_tensor0, *p_tensor1}; + Qnn_Tensor_t out_0_outputs[] = {*p_tensor2_transpose}; + Qnn_OpConfig_t out_0 = ggmlqnn_create_op_config("mulmat_opconfig", + QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_MAT_MUL, out_0_params, 1, + out_0_inputs, 2, out_0_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, out_0)); + + //compose QNN graph: add transpose node + Qnn_Param_t out_trans1_0_params[] = { + {.paramType = QNN_PARAMTYPE_TENSOR, .name = "perm", .tensorParam = *p_param_tensor}}; + Qnn_Tensor_t out_trans1_0_inputs[] = {*p_tensor2_transpose}; + Qnn_Tensor_t out_trans1_0_outputs[] = {*p_tensor2}; + Qnn_OpConfig_t out_trans1_0 = ggmlqnn_create_op_config("mulmat_transpose_opconfig", + QNN_OP_PACKAGE_NAME_QTI_AISW, + QNN_OP_TRANSPOSE, + out_trans1_0_params, 1, + out_trans1_0_inputs, 1, + out_trans1_0_outputs, 1); + CHECK_QNN_API(error, qnn_raw_interface.graphAddNode(graph_handle, out_trans1_0)); + + //finalize QNN graph + CHECK_QNN_API(error, qnn_raw_interface.graphFinalize(graph_handle, nullptr, nullptr)); + + //cache QNN graph + qnn_ptensors_t ggml_op_mulmat_tensors; + ggml_op_mulmat_tensors.reserve(5); + ggml_op_mulmat_tensors.push_back(p_tensor0); + ggml_op_mulmat_tensors.push_back(p_tensor1); + ggml_op_mulmat_tensors.push_back(p_tensor2); + ggml_op_mulmat_tensors.push_back(p_param_tensor); + ggml_op_mulmat_tensors.push_back(p_tensor2_transpose); + auto graph_item = std::make_tuple(graph_handle, ggml_op_mulmat_tensors); + ctx->qnn_singlenode_graph_map[graph_name] = graph_item; + } + + if (src0_type != GGML_TYPE_F32) { + QNN_VER_PTR(*p_tensor0)->clientBuf = {wdata, static_cast(desired_size)}; + } else { + QNN_VER_PTR(*p_tensor0)->clientBuf = {src0->data, ggmlqnn_get_tensor_data_size(src0)}; + } + QNN_VER_PTR(*p_tensor1)->clientBuf = {src1->data, ggmlqnn_get_tensor_data_size(src1)}; + QNN_VER_PTR(*p_tensor2)->clientBuf = {dst->data, ggmlqnn_get_tensor_data_size(dst)}; + + Qnn_Tensor_t tensor_inputs[] = { + *p_tensor0, + *p_tensor1 + }; + Qnn_Tensor_t tensor_outputs[] = { + *p_tensor2 + }; + CHECK_QNN_API(error, qnn_raw_interface.graphExecute(graph_handle, + tensor_inputs, 2, + tensor_outputs, 1, + nullptr, nullptr)); + op_perf.info(); +} + +static void ggmlqnn_compute_repeat(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_div(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_leaky_relu(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_concat(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_arange(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_sqr(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_clamp(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_scale(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_argsort(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_norm(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_group_norm(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_acc(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_sum_rows(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_upsample_nearest2d(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_pad(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_pool2d(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_dup(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_rms_norm(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_im2col(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_timestep_embedding(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_cpy(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + ggmlqnn_compute_dup(ctx, dst); +} + +static void ggmlqnn_compute_softmax(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_get_rows(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +static void ggmlqnn_compute_rope(ggml_backend_hexagon_context * ctx, ggml_tensor * dst) { + GGML_UNUSED(ctx); + GGML_UNUSED(dst); +} + +// ================================================================================================= +// section-7: cDSP helper function +// ================================================================================================= +static const char * ggmlhexagon_get_dsp_name(int domain_id) { + switch (domain_id) { + case HEXAGON_ADSP: + return "Hexagon-aDSP"; + case HEXAGON_MDSP: + return "Hexagon-mDSP"; + case HEXAGON_SDSP: + return "Hexagon-sDSP"; + case HEXAGON_CDSP: + return "Hexagon-cDSP"; + case HEXAGON_CDSP1: + return "Hexagon-cDSP1"; + default: + return "Hexagon-unknown"; + } +} + +static int ggmlhexagon_pd_status_notifier_callback(void * context, int domain, int session, remote_rpc_status_flags_t status){ + int error = AEE_SUCCESS; + switch (status){ + case FASTRPC_USER_PD_UP: + GGMLHEXAGON_LOG_DEBUG("PD is up\n"); + break; + case FASTRPC_USER_PD_EXIT: + GGMLHEXAGON_LOG_DEBUG("PD closed\n"); + break; + case FASTRPC_USER_PD_FORCE_KILL: + GGMLHEXAGON_LOG_DEBUG("PD force kill\n"); + break; + case FASTRPC_USER_PD_EXCEPTION: + GGMLHEXAGON_LOG_DEBUG("PD exception\n"); + break; + case FASTRPC_DSP_SSR: + GGMLHEXAGON_LOG_DEBUG("DSP SSR\n"); + break; + default : + error = AEE_EBADITEM; + break; + } + return error; +} + +static domain * ggmlhexagon_get_domain(int domain_id) { + int size = sizeof(hexagon_supported_domains) / sizeof(domain); + + for (int i = 0; i < size; i++) { + if (hexagon_supported_domains[i].id == domain_id) + return &hexagon_supported_domains[i]; + } + + return nullptr; +} + +static bool ggmlhexagon_is_cdsp(int domain_id) { + return (domain_id == HEXAGON_CDSP) || (domain_id == HEXAGON_CDSP1); +} + +static bool ggmlhexagon_is_valid_domain_id(int domain_id, int compute_only) { + int size = sizeof(hexagon_supported_domains) / sizeof(domain); + + if (0 != compute_only) { + return ggmlhexagon_is_cdsp(domain_id); + } + + for (int i = 0; i < size; i++) { + if (hexagon_supported_domains[i].id == domain_id) + return true; + } + + return false; +} + +static int ggmlhexagon_get_domains_info(const char * domain_type, int * num_domains, fastrpc_domain ** domains_info) { + int hexagon_err = AEE_SUCCESS; + int ss_info = 0; + void * buffer = nullptr; + ss_info = strcmp(domain_type, "NSP")? HPASS: NSP; + system_req_payload req; + memset(&req, 0, sizeof(system_req_payload)); + req.id = FASTRPC_GET_DOMAINS; + req.sys.domains = nullptr; + fastrpc_domain * domain = nullptr; + + if (ss_info != 0) { + req.sys.flags = DOMAINS_LIST_FLAGS_SET_TYPE(req.sys.flags, ss_info); + } else { + req.sys.flags =0; + } + +#ifdef _WIN32 + hexagon_err = AEE_EUNSUPPORTED; + goto bail; +#endif + + hexagon_err = remote_system_request(&req); + if (hexagon_err != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("failure in remote_system_request call: %d", hexagon_err); + goto bail; + } + //allocate memory for domain-info array + req.sys.max_domains = req.sys.num_domains; + buffer = calloc(req.sys.num_domains, sizeof(fastrpc_domain)); + if (nullptr == buffer) { + hexagon_err = AEE_ENOMEMORY; + GGMLHEXAGON_LOG_DEBUG("unable to allocate memory for req.sys.domains"); + goto bail; + } + req.sys.domains = static_cast(buffer); + hexagon_err = remote_system_request(&req); + if (hexagon_err != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("failure in remote_system_request call: %d.\n", hexagon_err); + goto bail; + } + + for (int i = 0; i < req.sys.num_domains; i++) { + //verify that only requested type domains were returned + domain = &req.sys.domains[i]; + if (domain->type != ss_info) { + hexagon_err = -1; + GGMLHEXAGON_LOG_DEBUG("incorrect data received from remote_system_request.\n"); + goto bail; + } + } + *domains_info = req.sys.domains; + *num_domains = req.sys.num_domains; + +bail: + if (hexagon_err && !req.sys.domains) { + free(req.sys.domains); + } + return hexagon_err; +} + +static int ggmlhexagon_get_dsp_support(int * domain) { + int hexagon_error = AEE_SUCCESS; + *domain = HEXAGON_CDSP; + + if (remote_handle_control) { + struct remote_dsp_capability dsp_capability_domain = {HEXAGON_CDSP, DOMAIN_SUPPORT, 0}; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_domain, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_DEBUG("FastRPC Capability API is not supported on this device"); + goto bail; + } + + if (0 == dsp_capability_domain.capability) { + dsp_capability_domain.domain = HEXAGON_ADSP; + dsp_capability_domain.attribute_ID = DOMAIN_SUPPORT; + dsp_capability_domain.capability = 0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_domain, sizeof(struct remote_dsp_capability)); + if(dsp_capability_domain.capability) { + *domain = HEXAGON_ADSP; + } + } + + if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("get_dsp_support failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_DEBUG("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return hexagon_error; +} + +static int ggmlhexagon_get_vtcm_info(int domain, uint32_t attr, uint32_t * capability) { + int hexagon_error = AEE_SUCCESS; + *capability = 0; + + if (attr == VTCM_PAGE || attr == VTCM_COUNT) { + } else { + hexagon_error = AEE_EBADPARM; + GGMLHEXAGON_LOG_DEBUG("unsupported attr, only VTCM_PAGE and VTCM_COUNT supported"); + goto bail; + } + + if (remote_handle_control) { + if (domain == HEXAGON_ADSP || domain == HEXAGON_CDSP) { + /* + * query the DSP for VTCM information + * since the ADSP does not have a dedicated VTCM, we expect the output to be 0 + */ + struct remote_dsp_capability dsp_capability_vtcm_dsp; + dsp_capability_vtcm_dsp.domain = (uint32_t)domain; + dsp_capability_vtcm_dsp.attribute_ID = attr; + dsp_capability_vtcm_dsp.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_vtcm_dsp, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_DEBUG("FastRPC Capability API is not supported on this device"); + GGMLHEXAGON_LOG_DEBUG("running the use case without checking the capability"); + hexagon_error = AEE_SUCCESS; + goto bail; + } else if (hexagon_error == AEE_SUCCESS) { + *capability = dsp_capability_vtcm_dsp.capability; + } else { + GGMLHEXAGON_LOG_DEBUG("get_vtcm_info failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTED; + GGMLHEXAGON_LOG_DEBUG("unsupported domain %d", domain); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_DEBUG("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return hexagon_error; +} + +static bool ggmlhexagon_is_unsignedpd_supported(int domain_id) { + int hexagon_error = AEE_SUCCESS; + if (remote_handle_control) { + struct remote_dsp_capability dsp_capability_domain = {static_cast(domain_id), UNSIGNED_PD_SUPPORT, 0}; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_domain, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_WARN("FastRPC Capability API is not supported on this device. Falling back to signed pd"); + return false; + } + + if (hexagon_error) { + GGMLHEXAGON_LOG_WARN("error 0x%x: FastRPC Capability API failed. falling back to signed pd", hexagon_error); + return false; + } + + if (dsp_capability_domain.capability == 1) { + return true; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_WARN("remote_dsp_capability interface is not supported on this device.falling back to signed pd"); + return false; + } + + return false; +} + +static bool ggmlhexagon_get_unsignedpd_support(void) { + return ggmlhexagon_is_unsignedpd_supported(HEXAGON_CDSP); +} + +static bool ggmlhexagon_is_async_fastrpc_supported(int domain) { + int hexagon_error = AEE_SUCCESS; + if (remote_handle_control) { + if (domain == HEXAGON_CDSP) { + /* + * Query the DSP for ASYNC_FASTRPC_SUPPORT information + * Async fastrpc is supported only on CDSP + */ + struct remote_dsp_capability dsp_capability_async_support; + dsp_capability_async_support.domain = (uint32_t)domain; + dsp_capability_async_support.attribute_ID = ASYNC_FASTRPC_SUPPORT; + dsp_capability_async_support.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_async_support, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_WARN("FastRPC Capability API is not supported on this device"); + hexagon_error = AEE_SUCCESS; + goto bail; + } else if (dsp_capability_async_support.capability == 1) { + return true; + } + + if (hexagon_error != AEE_SUCCESS){ + GGMLHEXAGON_LOG_WARN("failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTED; + GGMLHEXAGON_LOG_WARN("async FastRPC is not supported on domain %d", domain); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_WARN("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return false; +} + +static void ggmlhexagon_set_rpc_latency(remote_handle64 handle, int qos, int latency) { + int hexagon_error = AEE_SUCCESS; + + if (remote_handle_control) { + struct remote_rpc_control_latency data; +/* + qos | latency + ----------------------- + RPC_PM_QOS | 100 + RPC_POLL_QOS | 1000 +*/ + data.enable = qos; + data.latency = latency; + hexagon_error = remote_handle64_control(handle, DSPRPC_CONTROL_LATENCY, (void*)&data, sizeof(data)); + if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_WARN("failed with error 0x%x", hexagon_error); + goto bail; + } else { + GGMLHEXAGON_LOG_INFO("set rpc qos %d, latency %d\n", qos, latency); + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_WARN("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return; +} + +static bool ggmlhexagon_is_status_notification_supported(int domain) { + int hexagon_error = AEE_SUCCESS; + + if (remote_handle_control) { + /* + * Query the DSP for STATUS_NOTIFICATION_SUPPORT information + * DSP User PD status notification Support + */ + struct remote_dsp_capability dsp_capability_status_notification_support; + dsp_capability_status_notification_support.domain = (uint32_t)domain; + dsp_capability_status_notification_support.attribute_ID = STATUS_NOTIFICATION_SUPPORT; + dsp_capability_status_notification_support.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_status_notification_support, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_WARN("FastRPC Capability API is not supported on this device"); + hexagon_error = AEE_SUCCESS; + goto bail; + } else if (1 == dsp_capability_status_notification_support.capability) { + return true; + } + + if (hexagon_error != AEE_SUCCESS){ + GGMLHEXAGON_LOG_WARN("failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_WARN("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return false; +} + +static int ggmlhexagon_get_hmx_support_info(int domain, uint32_t attr, uint32_t * capability) { + int hexagon_error = AEE_SUCCESS; + *capability = 0; + + if (attr != HMX_SUPPORT_SPATIAL && attr != HMX_SUPPORT_DEPTH) { + hexagon_error = AEE_EBADPARM; + GGMLHEXAGON_LOG_WARN("unsupported attr, only HMX_SUPPORT_SPATIAL and HMX_SUPPORT_DEPTH supported"); + goto bail; + } + + if (remote_handle_control) { + if (domain == HEXAGON_CDSP) { + /* + * Query the DSP for HMX SUPPORT information + * HMX is supported on CDSP only + */ + struct remote_dsp_capability dsp_capability_hmx_dsp; + dsp_capability_hmx_dsp.domain = (uint32_t)domain; + dsp_capability_hmx_dsp.attribute_ID = attr; + dsp_capability_hmx_dsp.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_hmx_dsp, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_DEBUG("FastRPC Capability API is not supported on this device"); + hexagon_error = AEE_SUCCESS; + goto bail; + } + else if (hexagon_error == AEE_SUCCESS) { + *capability = dsp_capability_hmx_dsp.capability; + } else { + GGMLHEXAGON_LOG_DEBUG("get_hmx_support_info failed with Error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTED; + GGMLHEXAGON_LOG_DEBUG("HMX support is not there for domain %d", domain); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_DEBUG("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return hexagon_error; +} + +static int ggmlhexagon_get_hvx_arch_ver(int domain, uint32_t * capability) { + int hexagon_error = AEE_SUCCESS; + *capability = 0; + if(remote_handle_control) { + /* + * Query the Hexagon processor architecture version information + */ + struct remote_dsp_capability dsp_capability_arch_ver; + dsp_capability_arch_ver.domain = (uint32_t)domain; + dsp_capability_arch_ver.attribute_ID = ARCH_VER; + dsp_capability_arch_ver.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_arch_ver, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF) == (AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_DEBUG("FastRPC Capability API is not supported on this device"); + hexagon_error = AEE_SUCCESS; + goto bail; + } else if (hexagon_error == AEE_SUCCESS) { + *capability = dsp_capability_arch_ver.capability & 0xFF; + } else { + GGMLHEXAGON_LOG_DEBUG("get_hex_arch_ver failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_DEBUG("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return hexagon_error; +} + +static int ggmlhexagon_get_hvx_support_info(int domain, uint32_t attr, uint32_t * capability) +{ + int hexagon_error = AEE_SUCCESS; + *capability = 0; + if (attr == HVX_SUPPORT_64B) { + hexagon_error = AEE_EBADPARM; + GGMLHEXAGON_LOG_DEBUG("latest targets have 128 byte HVX register, use HVX_SUPPORT_128B instead of HVX_SUPPORT_64B"); + goto bail; + } + + if (attr != HVX_SUPPORT_128B) { + hexagon_error = AEE_EBADPARM; + GGMLHEXAGON_LOG_DEBUG("unsupported attr. only HVX_SUPPORT_128B supported"); + goto bail; + } + + if (remote_handle_control) { + if (domain == HEXAGON_CDSP) { + /* + * Query the DSP for HVX SUPPORT information + * HVX is supported on CDSP only + */ + struct remote_dsp_capability dsp_capability_hvx_dsp; + dsp_capability_hvx_dsp.domain = (uint32_t)domain; + dsp_capability_hvx_dsp.attribute_ID = attr; + dsp_capability_hvx_dsp.capability = (uint32_t)0; + hexagon_error = remote_handle_control(DSPRPC_GET_DSP_INFO, &dsp_capability_hvx_dsp, sizeof(struct remote_dsp_capability)); + if ((hexagon_error & 0xFF)==(AEE_EUNSUPPORTEDAPI & 0xFF)) { + GGMLHEXAGON_LOG_DEBUG("FastRPC Capability API is not supported on this device"); + hexagon_error = AEE_SUCCESS; + goto bail; + } else if (hexagon_error == AEE_SUCCESS) { + *capability = dsp_capability_hvx_dsp.capability; + } else { + GGMLHEXAGON_LOG_DEBUG("failed with error 0x%x", hexagon_error); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTED; + GGMLHEXAGON_LOG_DEBUG("HVX support is not available on domain %d", domain); + goto bail; + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + GGMLHEXAGON_LOG_DEBUG("remote_dsp_capability interface is not supported on this device"); + } + +bail: + return hexagon_error; +} + +static int ggmlhexagon_request_status_notifications(int domain_id, void * context, notify_callback_fn call_back_fn) { + int hexagon_error = AEE_SUCCESS; + struct remote_rpc_notif_register notif; + bool status_notification_support; + + notif.context = context; + notif.domain = domain_id; + notif.notifier_fn = call_back_fn; + + status_notification_support = ggmlhexagon_is_status_notification_supported(domain_id); + if (status_notification_support) { + hexagon_error = remote_session_control(FASTRPC_REGISTER_STATUS_NOTIFICATIONS, (void*)¬if, sizeof(notif)); + if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("error 0x%x: remote_session_control failed to enable status notifications", hexagon_error); + } + } else { + hexagon_error = AEE_EUNSUPPORTEDAPI; + } + + return hexagon_error; +} + +static int ggmlhexagon_init_rpcmempool(ggml_backend_hexagon_context * ctx) { + size_t candidate_size = 0; + uint8_t * rpc_buffer = nullptr; +#ifdef SD_USE_HEXAGON // for stable-diffusion.cpp + size_t probe_slots[] = {1024, 1536, 2000, 2048, 1024 + 2048, 4096}; +#else + size_t probe_slots[] = {1024, 1536, 2000, 2048}; +#endif + size_t probe_counts = sizeof(probe_slots) / sizeof(size_t); + + if (nullptr == ctx) + return 1; + + for (size_t idx = 0; idx < probe_counts; idx++) { +#ifdef SD_USE_HEXAGON // for stable-diffusion.cpp + rpc_buffer = static_cast(rpcmem_alloc2(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, (probe_slots[idx] * SIZE_IN_MB))); +#else + rpc_buffer = static_cast(rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, (probe_slots[idx] * SIZE_IN_MB))); +#endif + if (nullptr == rpc_buffer) { + GGMLHEXAGON_LOG_DEBUG("alloc rpcmem %d (MiB) failure during probe rpc memory info, reason: %s\n", probe_slots[idx], strerror(errno)); + break; + } else { + candidate_size = probe_slots[idx]; + rpcmem_free(rpc_buffer); + rpc_buffer = nullptr; + } + } + ctx->rpc_mempool_capacity = candidate_size * SIZE_IN_MB; + GGMLHEXAGON_LOG_DEBUG("rpc memory capacity %ld(%d MiB) for device %d", + ctx->rpc_mempool_capacity, ctx->rpc_mempool_capacity / SIZE_IN_MB, ctx->device); + GGMLHEXAGON_LOG_INFO("capacity of rpc memory %d MiB", ctx->rpc_mempool_capacity / SIZE_IN_MB); + + if ((g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + GGML_ASSERT(ctx->rpc_mempool_capacity > (8 * SIZE_IN_MB)); + ctx->rpc_mempool_len = ctx->rpc_mempool_capacity - (8 * SIZE_IN_MB); +#ifdef SD_USE_HEXAGON // use rpcmem_alloc2 to alloc 2+ GiB memory, it's a workaround to make stablediffusion.cpp happy + ctx->rpc_mempool = rpcmem_alloc2(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS | RPCMEM_TRY_MAP_STATIC, ctx->rpc_mempool_len); +#else + //FIXME: it seems there is unknown issue with 2+ GiB memory pool + ctx->rpc_mempool = rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS | RPCMEM_TRY_MAP_STATIC, ctx->rpc_mempool_len); +#endif + if (nullptr == ctx->rpc_mempool) { + GGMLHEXAGON_LOG_WARN("alloc rpc memorypool %ld(%d MiB) failed", ctx->rpc_mempool_len, ctx->rpc_mempool_capacity / SIZE_IN_MB); + return 2; + } else { + GGMLHEXAGON_LOG_DEBUG("alloc rpc memorypool %p successfully %ld(%d MiB)", + ctx->rpc_mempool, ctx->rpc_mempool_len, + ctx->rpc_mempool_len / SIZE_IN_MB); + } + ctx->rpc_mempool_handle = rpcmem_to_fd(ctx->rpc_mempool); + GGMLHEXAGON_LOG_DEBUG("rpc mempool handle %d", ctx->rpc_mempool_handle); + remote_register_buf(ctx->rpc_mempool, ctx->rpc_mempool_len, ctx->rpc_mempool_handle); + } + + return 0; +} + +static void ggmlhexagon_deinit_rpcmempool(ggml_backend_hexagon_context * ctx) { + if ((g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + if (ctx->rpc_mempool) { + //deregister rpc memory pool + remote_register_buf(ctx->rpc_mempool, ctx->rpc_mempool_len, -1); + GGMLHEXAGON_LOG_DEBUG("free rpc mempool %p", ctx->rpc_mempool); + rpcmem_free(ctx->rpc_mempool); + ctx->rpc_mempool = nullptr; + ctx->rpc_mempool_len = 0; + ctx->rpc_mempool_capacity = 0; + } + } +} + +static void ggmlhexagon_probe_dspinfo(ggml_backend_hexagon_context * ctx) { + uint32_t dsp_version = 0; + ggmlhexagon_get_hvx_arch_ver(ctx->domain_id, &dsp_version); + + if (dsp_version == 0x68 || dsp_version == 0x69 || dsp_version == 0x73 || dsp_version == 0x75 || dsp_version == 0x79) { + GGMLHEXAGON_LOG_INFO("dsp arch version 0x%x", dsp_version); + //0x68 -> 68, 0x69 -> 69, 0x73 -> 73, 0x75 -> 75, 0x79 -> 79 + size_t htp_arch = ggmlhexagon_htparch_hex_to_decimal(dsp_version); + GGMLHEXAGON_LOG_DEBUG("dsp arch version %d", htp_arch); + struct qcom_socinfo * socinfo = ggmlhexagon_get_socinfo_from_socmodel(htp_arch); + if (nullptr != socinfo) { + //got fully description of SoC when hwaccel approach is HWACCEL_CDSP + GGMLHEXAGON_LOG_INFO("device info: %s, %s", socinfo->soc_desc, ggmlhexagon_get_htparch_desc(htp_arch)); + } + } else { + GGMLHEXAGON_LOG_WARN("error: dsp arch version 0x%x is not supported", dsp_version); + } + + uint32_t vtcm_count = 0; + uint32_t vtcm_page = 0; + ggmlhexagon_get_vtcm_info(ctx->domain_id, VTCM_COUNT, &vtcm_count); + ggmlhexagon_get_vtcm_info(ctx->domain_id, VTCM_PAGE, &vtcm_page); + GGMLHEXAGON_LOG_INFO("vtcm_count %d", vtcm_count); + GGMLHEXAGON_LOG_INFO("vtcm_page %d", vtcm_page); + + uint32_t hmx_depth = 0; + uint32_t hmx_spatial = 0; + ggmlhexagon_get_hmx_support_info(ctx->domain_id, HMX_SUPPORT_DEPTH, &hmx_depth); + ggmlhexagon_get_hmx_support_info(ctx->domain_id, HMX_SUPPORT_SPATIAL, &hmx_spatial); + GGMLHEXAGON_LOG_INFO("hmx_depth %d", hmx_depth); + GGMLHEXAGON_LOG_INFO("hmx_spatial %d", hmx_spatial); + + uint32_t hvx_support_128b = 0; + ggmlhexagon_get_hvx_support_info(ctx->domain_id, HVX_SUPPORT_128B, &hvx_support_128b); + GGMLHEXAGON_LOG_INFO("hvx_support_128b %d", hvx_support_128b); + + GGMLHEXAGON_LOG_INFO("unsigned pd supported %d", ggmlhexagon_get_unsignedpd_support()); + GGMLHEXAGON_LOG_INFO("async fastrpc supported %d", ggmlhexagon_is_async_fastrpc_supported(ctx->domain_id)); +} + +static void ggmlhexagon_deinit_cdsp(ggml_backend_hexagon_context * ctx) { + int hexagon_error = AEE_SUCCESS; + GGMLHEXAGON_LOG_INFO("enter %s", __func__); + if (0 != ctx->ggmlop_handle) { + hexagon_error = ggmlop_dsp_close(ctx->ggmlop_handle); + if (AEE_SUCCESS != hexagon_error) { + GGMLHEXAGON_LOG_WARN("error 0x%x: failed to close ggmlop dsp handle", hexagon_error); + } + ctx->ggmlop_handle = 0; + } + + ggmlhexagon_deinit_rpcmempool(ctx); + + ctx->domain_id = -1; + GGMLHEXAGON_LOG_INFO("leave %s", __func__); +} + +static int ggmlhexagon_init_dsp(ggml_backend_hexagon_context * ctx) { + static std::mutex mutex; + std::lock_guard lock(mutex); + + int hexagon_error = AEE_SUCCESS; + + int domain_id = HEXAGON_CDSP; + const char * domain_type = "NSP"; + + int unsignedpd_flag = 1; + bool is_unsignedpd_enabled = false; + int use_logical_id = 0; + int core_id = -1; + fastrpc_domain * domains_info = NULL; + int num_domains = -1; + + domain * my_domain = NULL; + char * uri = NULL; + + char * ggmlop_domain_uri = NULL; + int ggmlop_domain_uri_len = 0; + + if (nullptr == ctx) + return 1; + GGMLHEXAGON_LOG_DEBUG("init Hexagon cDSP with backend %d(%s)", ctx->device, ggml_backend_hexagon_get_devname(ctx->device)); + if (0 != ctx->ggmlop_handle) { + GGMLHEXAGON_LOG_DEBUG("already init Hexagon cDSP with backend %d(%s)", ctx->device, ggml_backend_hexagon_get_devname(ctx->device)); + return 0; + } + ctx->ggmlop_handle = 0; + + if (-1 == domain_id) { + if (nullptr != domain_type) { + if ((strcmp(domain_type, "NSP") != 0 && strcmp(domain_type, "HPASS") != 0)) { + GGMLHEXAGON_LOG_WARN("invalid domain_type %s. possible values are NSP or HPASS", domain_type); + goto bail; + } else { + hexagon_error = ggmlhexagon_get_domains_info(domain_type, &num_domains, &domains_info); + if (hexagon_error == AEE_EUNSUPPORTED) { + GGMLHEXAGON_LOG_DEBUG("API is not supported on this target so cannot get domains info from the device. falling back to legacy approach of using default domain id"); + hexagon_error = ggmlhexagon_get_dsp_support(&domain_id); + if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("error: 0x%x, defaulting to cDSP domain", hexagon_error); + } + } else if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("error in getting domains information"); + goto bail; + } else { + if (core_id != -1) { + if (core_id < 0 || core_id >= num_domains) { + GGMLHEXAGON_LOG_DEBUG("invalid core_id = %d for %s. core_id should be between 0 to %d", core_id, domain_type, num_domains - 1); + hexagon_error = AEE_EBADPARM; + goto bail; + } + } else { + core_id = 0; + } + use_logical_id = 1; + domain_id = domains_info[core_id].id; + } + } + } else { + GGMLHEXAGON_LOG_DEBUG("DSP domain is not provided, retrieving DSP information using Remote APIs"); + hexagon_error = ggmlhexagon_get_dsp_support(&domain_id); + if (hexagon_error != AEE_SUCCESS) { + GGMLHEXAGON_LOG_DEBUG("error: 0x%x, defaulting to cDSP domain", hexagon_error); + } + } + } + + if (0 == use_logical_id) { + if (!ggmlhexagon_is_valid_domain_id(domain_id, 0)) { + hexagon_error = AEE_EBADPARM; + GGMLHEXAGON_LOG_DEBUG("error 0x%x: invalid domain %d", hexagon_error, domain_id); + goto bail; + } + + my_domain = ggmlhexagon_get_domain(domain_id); + if (nullptr == my_domain) { + GGMLHEXAGON_LOG_DEBUG("unable to get domain struct %d", domain_id); + goto bail; + } + uri = my_domain->uri; + } + GGMLHEXAGON_LOG_DEBUG("temporary domain uri=%s\n", uri); + + if (1 == unsignedpd_flag) { + is_unsignedpd_enabled = ggmlhexagon_is_unsignedpd_supported(domain_id); + if (!is_unsignedpd_enabled) { + GGMLHEXAGON_LOG_DEBUG("overriding user request for unsigned PD, only signed offload is allowed on domain %d", domain_id); + unsignedpd_flag = 0; + } + } + + ctx->domain_id = domain_id; + GGMLHEXAGON_LOG_INFO("using Hexagon domain %d(%s)", domain_id, ggmlhexagon_get_dsp_name(domain_id)); + GGMLHEXAGON_LOG_INFO("unsignedpd_enabled %d", is_unsignedpd_enabled); + if (is_unsignedpd_enabled) { + if (remote_session_control) { + struct remote_rpc_control_unsigned_module data; + data.enable = 1; + data.domain = domain_id; + hexagon_error = remote_session_control(DSPRPC_CONTROL_UNSIGNED_MODULE, (void *)&data, sizeof(data)); + GGMLHEXAGON_LOG_DEBUG("remote_session_control returned %d for configuring unsigned PD success", hexagon_error); + if (AEE_SUCCESS != hexagon_error) { + GGMLHEXAGON_LOG_DEBUG("error 0x%x: remote_session_control failed", hexagon_error); + } + } else { + GGMLHEXAGON_LOG_DEBUG("unsigned PD not supported on this device"); + hexagon_error = AEE_EUNSUPPORTED; + GGMLHEXAGON_LOG_DEBUG("error 0x%x: remote_session_control interface is not supported on this device", hexagon_error); + } + } + + hexagon_error = ggmlhexagon_request_status_notifications(domain_id, (void *)STATUS_CONTEXT, ggmlhexagon_pd_status_notifier_callback); + if (AEE_SUCCESS != hexagon_error) { + if (AEE_EUNSUPPORTEDAPI != hexagon_error) { + GGMLHEXAGON_LOG_WARN("error 0x%x: hexagon_request_status_notifications failed", hexagon_error); + } + GGMLHEXAGON_LOG_WARN("error 0x%x: failed to compute on domain %d", hexagon_error, domain_id); + goto bail; + } + + ggmlop_domain_uri_len = strlen(ggmlop_URI) + MAX_DOMAIN_NAMELEN; + ggmlop_domain_uri = (char *)malloc(ggmlop_domain_uri_len); + snprintf(ggmlop_domain_uri, ggmlop_domain_uri_len, "%s%s", ggmlop_URI, uri); + GGMLHEXAGON_LOG_DEBUG("ggmlop domain uri:%s", ggmlop_domain_uri); + hexagon_error = ggmlop_dsp_open(ggmlop_domain_uri, &ctx->ggmlop_handle); + if (AEE_SUCCESS == hexagon_error) { + GGMLHEXAGON_LOG_INFO("succeed to open domain %d(%s)", domain_id, ggmlhexagon_get_dsp_name(domain_id)); + //FIXME: only support offload fp32 GGML_OP_MUL_MAT to cDSP + GGMLHEXAGON_LOG_INFO("only support offload fp32 GGML_OP_ADD and fp32 GGML_OP_MUL_MAT to cDSP currently"); + ggmlhexagon_probe_dspinfo(ctx); + //FIXME: re-use this function to pass thread_counts info to code on cDSP side before fully understand qidl mechanism + ggmlop_dsp_setclocks(ctx->ggmlop_handle, HAP_DCVS_VCORNER_TURBO_PLUS, 40, 1, g_hexagon_appcfg.thread_counts); + ggmlhexagon_set_rpc_latency(ctx->ggmlop_handle, RPC_POLL_QOS, 100); + int result = ggmlhexagon_init_rpcmempool(ctx); + if (0 != result) { + GGMLHEXAGON_LOG_INFO("failed to init rpc mempool"); + goto bail; + } + } else { + GGMLHEXAGON_LOG_INFO("error 0x%x: failed to open domain %d(%s)", hexagon_error, domain_id, + ggmlhexagon_get_dsp_name(domain_id)); + goto bail; + } + + //make sure test-backend-ops get the correct backend name when hwaccel approach is 2(HWACCEL_CDSP) + memcpy(g_hexagon_mgr[ctx->device].name, "Hexagon-cDSP", strlen("Hexagon-cDSP")); + + return 0; + +bail: + if (ggmlop_domain_uri) { + free(ggmlop_domain_uri); + } + + ggmlhexagon_deinit_cdsp(ctx); + + return -1; +} + +static void ggmlhexagon_compute(ggml_backend_hexagon_context * ctx, struct ggml_tensor * op) { + //skip sanity check because already checked in other place + struct dsptensor dsptensor_0; + struct dsptensor dsptensor_1; + struct dsptensor dsptensor_2; + std::string op_name; + const char * ggml_opname = ggml_op_name(op->op); + ggmlhexagon_get_opkey_from_op(op, op_name); + + int hexagon_error = AEE_SUCCESS; + ggmlhexagon_op_func_t op_func = nullptr; + size_t input_tensor_count = 2; + + ggml_tensor * src0 = op->src[0]; + ggml_tensor * src1 = op->src[1]; + ggml_tensor * dst = op; + + int input_size = ggml_nbytes(src0); + if (nullptr != src1) + input_size += ggml_nbytes(src1); + hexagon_perf op_perf(op_name, ggml_opname, input_size, ggml_nbytes(dst)); + op_perf.start(); + + input_tensor_count = ggmlhexagon_k_op_caps[ggmlhexagon_get_op_index(op)].input_param_count; + op_func = ggmlhexagon_k_op_caps[ggmlhexagon_get_op_index(op)].dsp_op_func; + if (nullptr == op_func) { + GGMLHEXAGON_LOG_DEBUG("op GGML_OP_%s and dsp func %s not supported on cCSP", ggml_op_name(op->op), ggmlhexagon_k_op_caps[ggmlhexagon_get_op_index(op)].hexagon_op_name); + return; + } + + //FIXME:try to fully understand the tech detail in qidl: + // qidl is a binary tool to generate some very complicated and hard-to customized bridge-layer codes + // between ARM-AP and cDSP. the mechanism in qidl/FastRPC is exactly similar to mechanism in TEE. + // try to find a better/efficient approach to exchange necessary data between ARM-AP side and cDSP side. + // manually modifying the important data structure ggml_tensor in ggml.h is not make-sense and not acceptable. + std::chrono::high_resolution_clock::time_point start_time = std::chrono::high_resolution_clock::now(); + dsptensor_0.data = src0->data; + dsptensor_0.data_len = ggml_nbytes(src0); + dsptensor_0.type = src0->type; + + dsptensor_0.ne[0] = src0->ne[0]; + dsptensor_0.ne[1] = src0->ne[1]; + dsptensor_0.ne[2] = src0->ne[2]; + dsptensor_0.ne[3] = src0->ne[3]; + + dsptensor_0.nb[0] = src0->nb[0]; + dsptensor_0.nb[1] = src0->nb[1]; + dsptensor_0.nb[2] = src0->nb[2]; + dsptensor_0.nb[3] = src0->nb[3]; + + if (2 == input_tensor_count) { + GGML_ASSERT(nullptr != src1); + dsptensor_1.data = src1->data; + dsptensor_1.type = src1->type; + dsptensor_1.data_len = ggml_nbytes(src1); + + dsptensor_1.ne[0] = src1->ne[0]; + dsptensor_1.ne[1] = src1->ne[1]; + dsptensor_1.ne[2] = src1->ne[2]; + dsptensor_1.ne[3] = src1->ne[3]; + + dsptensor_1.nb[0] = src1->nb[0]; + dsptensor_1.nb[1] = src1->nb[1]; + dsptensor_1.nb[2] = src1->nb[2]; + dsptensor_1.nb[3] = src1->nb[3]; + } + + dsptensor_2.data = dst->data; + dsptensor_2.data_len = ggml_nbytes(dst); + dsptensor_2.type = dst->type; + + dsptensor_2.ne[0] = dst->ne[0]; + dsptensor_2.ne[1] = dst->ne[1]; + dsptensor_2.ne[2] = dst->ne[2]; + dsptensor_2.ne[3] = dst->ne[3]; + + dsptensor_2.nb[0] = dst->nb[0]; + dsptensor_2.nb[1] = dst->nb[1]; + dsptensor_2.nb[2] = dst->nb[2]; + dsptensor_2.nb[3] = dst->nb[3]; + + memcpy(dsptensor_2.op_params, dst->op_params, GGML_MAX_OP_PARAMS / sizeof(int32_t)); + std::chrono::high_resolution_clock::time_point end_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration duration = end_time - start_time; + GGMLHEXAGON_LOG_DEBUG("pack duration %llu ns", duration.count()); + + hexagon_error = op_func(ctx->ggmlop_handle, &dsptensor_0, &dsptensor_1, &dsptensor_2); + if (AEE_SUCCESS != hexagon_error) { + GGMLHEXAGON_LOG_WARN("ggmlop %s computation fail on cdsp", ggml_op_name(op->op)); + } + + op_perf.info(); + return; +} + +// ================================================================================================= +// section-8: implementation of ggml-hexagon backend according to specification in ggml backend subsystem +// ================================================================================================= +static bool ggmlhexagon_can_handle_op_through_cdsp(ggml_backend_dev_t dev, const struct ggml_tensor * op_tensor) { + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)dev->context; + GGML_UNUSED(ctx); + if (op_tensor->op == GGML_OP_NONE) { + return true; + } + + if (!ggmlhexagon_k_op_caps[ggmlhexagon_get_op_index(op_tensor)].supported) { + return false; + } + + const ggml_tensor * src0 = op_tensor->src[0]; + const ggml_tensor * src1 = op_tensor->src[1]; + const int src0_rank = ggml_n_dims(src0); + const int64_t ne00 = src0->ne[0]; + int src1_rank = 0; + if (nullptr != src1) { + src1_rank = ggml_n_dims(src1); + } + switch (op_tensor->op) { + case GGML_OP_ADD: + { + //TODO:workaround approach to fix HWACCEL_CDSP can't works in ASR inference and LLM inference + // with some LLM models in a standard Android APP + if (ne00 < 1024) { + return false; + } + + if (!ggml_are_same_shape(src0, src1)) { + return false; + } + return (src0->type == GGML_TYPE_F32) && (src1->type == GGML_TYPE_F32) && (op_tensor->type == GGML_TYPE_F32); + } + case GGML_OP_MUL_MAT: + { + ggmlhexagon_dump_op_info(op_tensor); + //FIXME:keep same filter logic with QNN solution to compare NPU performance between cDSP approach + // and QNN-NPU approach, remove these filters in the future + if (src0_rank != src1_rank) + return false; + if (src0_rank != 2) + return false; + + if (1 == g_hexagon_appcfg.enable_q_mulmat) { + if (1 == g_hexagon_appcfg.enable_all_q_mulmat) { + return (src0->type == GGML_TYPE_F32 || ggml_is_quantized(src0->type)) && (src1->type == GGML_TYPE_F32); + } + + return (src0->type == GGML_TYPE_F32 + || src0->type == GGML_TYPE_Q4_0 || src0->type == GGML_TYPE_Q8_0 + || src0->type == GGML_TYPE_Q6_K || src0->type == GGML_TYPE_Q8_K + ) && (src1->type == GGML_TYPE_F32) && (op_tensor->type == GGML_TYPE_F32); + } else { + return (src0->type == GGML_TYPE_F32) && (src1->type == GGML_TYPE_F32) && + (op_tensor->type == GGML_TYPE_F32); + } + } + case GGML_OP_SOFT_MAX:{ + if (!ggml_is_contiguous(op_tensor)) + return false; + if (!ggml_are_same_shape(src0, op_tensor)) + return false; + } + case GGML_OP_RMS_NORM: + case GGML_OP_POOL_2D: + { + + ggmlhexagon_dump_op_info(op_tensor); + } + default: + break; + } + return false; +} + +static bool ggmlhexagon_can_handle_op_through_qnn(ggml_backend_dev_t dev, const struct ggml_tensor * op_tensor) { + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)dev->context; + if (op_tensor->op == GGML_OP_NONE) { + return true; + } + + if (!ggmlqnn_k_op_caps[ggmlhexagon_get_op_index(op_tensor)].supported) { + return false; + } + + struct ggml_tensor * src0 = op_tensor->src[0]; + struct ggml_tensor * src1 = op_tensor->src[1]; + const int64_t ne00 = src0->ne[0]; + const int src0_rank = ggml_n_dims(src0); + int src1_rank = 0; + if (nullptr != src1) { + src1_rank = ggml_n_dims(src1); + } + + switch (op_tensor->op) { + case GGML_OP_ADD: + case GGML_OP_SUB: + { + if (!ggml_are_same_shape(src0, src1)) { + return false; + } + + if (ne00 < 32) + return false; + + return ggmlhexagon_same_types(ctx, op_tensor); + } + + case GGML_OP_DIV: + case GGML_OP_MUL: { + if (ctx->device == HEXAGON_BACKEND_QNNNPU) + return false; + + if (!ggml_are_same_shape(src0, src1)) { + return false; + } + + if ((src0_rank != 2) || (src1_rank != 2)) //TODO: 3D and 4D matrix mul + return false; + + return ggmlhexagon_same_types(ctx, op_tensor); + } + case GGML_OP_MUL_MAT: + { + ggmlhexagon_dump_op_info(op_tensor); + if (src0_rank != src1_rank) // make QNN SDK happy + return false; + + if (src0_rank != 2) { + // FIXME: there are some limitations for mulmat in QNN SDK: rank >= 2. + // keep same filter logic with QNN solution to compare NPU performance between + // cDSP approach and QNN-NPU approach, remove these filters in the future + return false; + } + + if (ctx->device == HEXAGON_BACKEND_QNNNPU) { + if (1 == g_hexagon_appcfg.enable_q_mulmat) + return (src0->type == GGML_TYPE_F32 + || src0->type == GGML_TYPE_Q4_0 || src0->type == GGML_TYPE_Q8_0 + || src0->type == GGML_TYPE_Q6_K || src0->type == GGML_TYPE_Q8_K + ) && (src1->type == GGML_TYPE_F32) && (op_tensor->type == GGML_TYPE_F32); + else + return (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 && op_tensor->type == GGML_TYPE_F32); + } else { + return (src0->type == GGML_TYPE_F32 || ggml_is_quantized(src0->type)) + && (src1->type == GGML_TYPE_F32) && (op_tensor->type == GGML_TYPE_F32); + } + } + case GGML_OP_LOG: + { + if (ctx->device == HEXAGON_BACKEND_QNNNPU) + return false; + } + case GGML_OP_SQRT: + default: + return ggmlhexagon_same_types(ctx, op_tensor); + } +} + +static bool ggmlhexagon_compute_forward(ggml_backend_t backend, struct ggml_tensor * dst) { + ggmlqnn_op_func_t func = nullptr; + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)backend->context; + + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + ggmlhexagon_compute(ctx, dst); + return true; + } + + switch (dst->op) { + case GGML_OP_REPEAT: + ggmlqnn_compute_repeat(ctx, dst); + break; + case GGML_OP_GET_ROWS: + ggmlqnn_compute_get_rows(ctx, dst); + break; + case GGML_OP_DUP: + ggmlqnn_compute_dup(ctx, dst); + break; + case GGML_OP_ADD: + case GGML_OP_SUB: + case GGML_OP_MUL: + case GGML_OP_DIV: + case GGML_OP_SQRT: + case GGML_OP_LOG: + func = ggmlqnn_compute_elementwise; + break; + case GGML_OP_ACC: + ggmlqnn_compute_acc(ctx, dst); + break; + case GGML_OP_UNARY: + switch (ggml_get_unary_op(dst)) { + case GGML_UNARY_OP_GELU: + break; + case GGML_UNARY_OP_SILU: + break; + case GGML_UNARY_OP_GELU_QUICK: + break; + case GGML_UNARY_OP_TANH: + break; + case GGML_UNARY_OP_RELU: + break; + case GGML_UNARY_OP_HARDSIGMOID: + break; + case GGML_UNARY_OP_HARDSWISH: + break; + default: + return false; + } + break; + case GGML_OP_NORM: + ggmlqnn_compute_norm(ctx, dst); + break; + case GGML_OP_GROUP_NORM: + ggmlqnn_compute_group_norm(ctx, dst); + break; + case GGML_OP_CONCAT: + ggmlqnn_compute_concat(ctx, dst); + break; + case GGML_OP_UPSCALE: + ggmlqnn_compute_upsample_nearest2d(ctx, dst); + break; + case GGML_OP_PAD: + ggmlqnn_compute_pad(ctx, dst); + break; + case GGML_OP_ARANGE: + ggmlqnn_compute_arange(ctx, dst); + break; + case GGML_OP_TIMESTEP_EMBEDDING: + ggmlqnn_compute_timestep_embedding(ctx, dst); + break; + case GGML_OP_LEAKY_RELU: + ggmlqnn_compute_leaky_relu(ctx, dst); + break; + case GGML_OP_RMS_NORM: + ggmlqnn_compute_rms_norm(ctx, dst); + break; + case GGML_OP_MUL_MAT: + ggmlqnn_compute_mul_mat(ctx, dst); + break; + case GGML_OP_MUL_MAT_ID: + return false; + case GGML_OP_SCALE: + ggmlqnn_compute_scale(ctx, dst); + break; + case GGML_OP_SQR: + ggmlqnn_compute_sqr(ctx, dst); + break; + case GGML_OP_CLAMP: + ggmlqnn_compute_clamp(ctx, dst); + break; + case GGML_OP_CPY: + ggmlqnn_compute_cpy(ctx, dst); + break; + case GGML_OP_CONT: + ggmlqnn_compute_dup(ctx, dst); + break; + case GGML_OP_NONE: + case GGML_OP_RESHAPE: + case GGML_OP_VIEW: + case GGML_OP_PERMUTE: + case GGML_OP_TRANSPOSE: + break; + case GGML_OP_SOFT_MAX: + ggmlqnn_compute_softmax(ctx, dst); + break; + case GGML_OP_ROPE: + ggmlqnn_compute_rope(ctx, dst); + break; + case GGML_OP_IM2COL: + ggmlqnn_compute_im2col(ctx, dst); + break; + case GGML_OP_POOL_2D: + ggmlqnn_compute_pool2d(ctx, dst); + break; + case GGML_OP_SUM_ROWS: + ggmlqnn_compute_sum_rows(ctx, dst); + break; + case GGML_OP_ARGSORT: + ggmlqnn_compute_argsort(ctx, dst); + break; + default: + return false; + } + + if (nullptr != func) + func(ctx, dst); + + return true; +} + +struct ggml_backend_hexagon_buffer_context { + ~ggml_backend_hexagon_buffer_context() { + if (buffer) { + if ((g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + //do nothing here because rpc mempool was used for HWACCEL_CDSP + } else { + ggml_aligned_free(buffer, 0); + } + } + } + + void * buffer = nullptr; + size_t buffer_size = 0; + + struct ggml_backend_hexagon_context * backend_ctx = nullptr; +}; + +static void ggml_backend_hexagon_buffer_free_buffer(ggml_backend_buffer_t buffer) { + ggml_backend_hexagon_buffer_context * ctx = (ggml_backend_hexagon_buffer_context *)buffer->context; + delete ctx; +} + +static void * ggml_backend_hexagon_buffer_get_base(ggml_backend_buffer_t buffer) { + ggml_backend_hexagon_buffer_context * ctx = (ggml_backend_hexagon_buffer_context *)buffer->context; + return ctx->buffer; +} + +static enum ggml_status ggml_backend_hexagon_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor) { + ggml_backend_hexagon_buffer_context * ctx = (ggml_backend_hexagon_buffer_context *)buffer->context; + GGML_UNUSED(tensor); + GGML_UNUSED(ctx); + return GGML_STATUS_SUCCESS; +} + +static void ggml_backend_hexagon_buffer_set_tensor(ggml_backend_buffer_t buffer, + ggml_tensor * tensor, const void * data, + size_t offset, size_t size) { + GGML_UNUSED(buffer); + + memcpy((char *)tensor->data + offset, data, size); +} + +static void ggml_backend_hexagon_buffer_memset_tensor(ggml_backend_buffer_t buffer, + struct ggml_tensor * tensor, + uint8_t value, size_t offset, size_t size) { + GGML_UNUSED(buffer); + memset((char *)tensor->data + offset, value, size); +} + +static void ggml_backend_hexagon_buffer_get_tensor(ggml_backend_buffer_t buffer, + const ggml_tensor * tensor, + void * data, size_t offset, size_t size) { + GGML_UNUSED(buffer); + memcpy(data, (const char *)tensor->data + offset, size); +} + +static bool ggml_backend_hexagon_buffer_cpy_tensor(ggml_backend_buffer_t buffer, + const struct ggml_tensor * src, + struct ggml_tensor * dst) { + GGML_UNUSED(buffer); + if (ggml_backend_buffer_is_host(src->buffer)) { + memcpy(dst->data, src->data, ggml_nbytes(src)); + return true; + } + + return false; +} + +static void ggml_backend_hexagon_buffer_clear(ggml_backend_buffer_t buffer, uint8_t value) { + ggml_backend_hexagon_buffer_context * ctx = (ggml_backend_hexagon_buffer_context *)buffer->context; + memset(ctx->buffer, value, ctx->buffer_size); +} + +static ggml_backend_buffer_i ggml_backend_hexagon_buffer_interface = { + /* .free_buffer = */ ggml_backend_hexagon_buffer_free_buffer, + /* .get_base = */ ggml_backend_hexagon_buffer_get_base, + /* .init_tensor = */ ggml_backend_hexagon_buffer_init_tensor, + /* .memset_tensor = */ ggml_backend_hexagon_buffer_memset_tensor, + /* .set_tensor = */ ggml_backend_hexagon_buffer_set_tensor, + /* .get_tensor = */ ggml_backend_hexagon_buffer_get_tensor, + /* .cpy_tensor = */ ggml_backend_hexagon_buffer_cpy_tensor, + /* .clear = */ ggml_backend_hexagon_buffer_clear, + /* .reset = */ nullptr, +}; + +static const char * ggml_backend_hexagon_buffer_type_name(ggml_backend_buffer_type_t buft) { + GGML_UNUSED(buft); + if ((g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + return "hexagon-ion-buffer"; + } + + return "hexagon-normal-buffer"; +} + +static ggml_backend_buffer_t ggml_backend_hexagon_buffer_type_alloc_buffer( + ggml_backend_buffer_type_t buft, size_t size) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + struct ggml_backend_hexagon_context * ctx = static_cast(buft->context); + GGML_ASSERT(nullptr != ctx); + ggml_backend_hexagon_buffer_context * buffer_ctx = new ggml_backend_hexagon_buffer_context; + + size_t size_page = 0; +#if defined(__ANDROID__) || defined(__linux__) + size_page = sysconf(_SC_PAGESIZE); +#else + SYSTEM_INFO systeminfo; + GetSystemInfo(&systeminfo); + size_page = systeminfo.dwPageSize; +#endif + size_t size_aligned = size; + if (0 != (size_aligned % size_page)) { + size_aligned += (size_page - (size_aligned % size_page)); + } + + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + GGMLHEXAGON_LOG_DEBUG("device %d(%s)", ctx->device, ggml_backend_hexagon_get_devname(ctx->device)); + GGML_ASSERT(nullptr != ctx->rpc_mempool); + GGMLHEXAGON_LOG_DEBUG("size %ld(%d MiB), rpc_mempool_usage %ld(%d MiB), rpc_mempool_len %ld(%d MiB)", + size, size / SIZE_IN_MB, ctx->rpc_mempool_usage, ctx->rpc_mempool_usage / SIZE_IN_MB, + ctx->rpc_mempool_len, ctx->rpc_mempool_len / SIZE_IN_MB); + GGML_ASSERT(size + ctx->rpc_mempool_usage <= ctx->rpc_mempool_len); + buffer_ctx->buffer = (static_cast(ctx->rpc_mempool)) + ctx->rpc_mempool_usage; + GGMLHEXAGON_LOG_DEBUG("buffer_ctx->buffer %p", buffer_ctx->buffer); + GGML_ASSERT(nullptr != buffer_ctx->buffer); + ctx->rpc_mempool_usage += size_aligned; + } else { + buffer_ctx->buffer = ggml_aligned_malloc(size_aligned); + } + buffer_ctx->buffer_size = size_aligned; + if (nullptr == buffer_ctx->buffer) { + GGMLHEXAGON_LOG_WARN("%s: failed to allocate %d MiB\n", __func__, size / SIZE_IN_MB); + return nullptr; + } else { + //GGMLHEXAGON_LOG_DEBUG("%s: succeed to allocate %d MiB\n", __func__, size / SIZE_IN_MB); + } + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return ggml_backend_buffer_init(buft, ggml_backend_hexagon_buffer_interface, buffer_ctx, size); +} + +/** + * @param buft pointer to the buffer type context + * @return alignment requirement in bytes + */ +static size_t ggml_backend_hexagon_buffer_type_get_alignment(ggml_backend_buffer_type_t buft) { + GGML_UNUSED(buft); + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + return 128; + } else { + return 32; + } +} + +static size_t ggml_backend_hexagon_buffer_type_get_max_size(ggml_backend_buffer_type_t buft) { + struct ggml_backend_hexagon_context * ctx = static_cast(buft->context); + GGML_ASSERT(nullptr != ctx); + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + GGML_ASSERT(ctx->rpc_mempool_len > (8 * SIZE_IN_MB)); + return ctx->rpc_mempool_len - (8 * SIZE_IN_MB); + } else { + //TODO:this is an experimental value for LLM models + return (1024 * SIZE_IN_MB); + } +} + +static bool ggml_backend_buft_is_hexagon(ggml_backend_buffer_type_t buft) { + return buft->iface.get_name == ggml_backend_hexagon_buffer_type_name; +} + +static bool ggml_backend_hexagon_buffer_is_host(ggml_backend_buffer_type_t buft) { + struct ggml_backend_hexagon_context * ctx = static_cast(buft->context); + GGML_ASSERT(nullptr != ctx); + GGML_UNUSED(ctx); + return true; +} + +static const char * ggml_backend_hexagon_name(ggml_backend_t backend) { + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *) backend->context; + return g_hexagon_mgr[ctx->device].name; +} + +static void ggml_backend_hexagon_free(ggml_backend_t backend) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)backend->context; + + qnn_instance * instance = (qnn_instance*)g_hexagon_mgr[ctx->device].instance; + if (nullptr != instance) { + for (auto & [graph_name, graph_res] : ctx->qnn_singlenode_graph_map) { + auto & graph_handle = std::get<0>(graph_res); + auto & ptensors = std::get<1>(graph_res); + for (auto & tensor : ptensors) { + ggmlqnn_free_qnntensor(tensor); + } + GGML_UNUSED(graph_handle); + GGMLHEXAGON_LOG_DEBUG("graph handle %p", graph_handle); + GGMLHEXAGON_LOG_DEBUG("clean up graph:%s", graph_name.c_str()); + } + + ctx->qnn_singlenode_graph_map.clear(); + + instance->qnn_finalize(); + delete instance; + g_hexagon_mgr[ctx->device].instance = nullptr; + } + + if (nullptr != g_hexagon_mgr[ctx->device].backend) { + //print timestamp and dsp information before deinit cdsp, useful for troubleshooting + ggmlhexagon_print_running_timestamp(ctx); + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + ggmlhexagon_deinit_cdsp(ctx); + } + + delete backend; + g_hexagon_mgr[ctx->device].backend = nullptr; + } + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); +} + +static enum ggml_status ggmlhexagon_backend_graph_compute_general(ggml_backend_t backend, struct ggml_cgraph * cgraph) { + enum ggml_status result = GGML_STATUS_SUCCESS; + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)backend->context; + GGML_UNUSED(ctx); + + for (int i = 0; i < cgraph->n_nodes; i++) { + ggml_tensor * node = cgraph->nodes[i]; + if (ggml_is_empty(node) || node->op == GGML_OP_RESHAPE + || node->op == GGML_OP_TRANSPOSE || node->op == GGML_OP_VIEW + || node->op == GGML_OP_PERMUTE || node->op == GGML_OP_NONE) { + continue; + } + bool ok = ggmlhexagon_compute_forward(backend, node); + if (!ok) { + GGMLHEXAGON_LOG_DEBUG("%s: error: op not supported %s (%s)\n", __func__, node->name, ggml_op_name(node->op)); + } + } + + return result; +} + +static const char * ggml_backend_hexagon_device_get_name(ggml_backend_dev_t dev) { + struct ggml_backend_hexagon_context * ctx = static_cast(dev->context); + if (nullptr == ctx) { + GGMLHEXAGON_LOG_ERROR("pls check why ctx is null"); + return "unknown"; + } + return ctx->name; +} + +static const char * ggml_backend_hexagon_device_get_description(ggml_backend_dev_t dev) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__); + struct ggml_backend_hexagon_context * ctx = static_cast(dev->context); + static char hexagon_device_desc[GGMLHEXAGON_TMPBUF_LEN]; + if (nullptr == ctx) { + GGMLHEXAGON_LOG_ERROR("pls check why ctx is null"); + return "unknown"; + } + + if (0 == strncmp(ctx->name, "qnn-npu", 7)) { + const char * soc_info = ggmlhexagon_get_socmodel_desc(ctx->socinfo.soc_model); + const char * htp_arch = ggmlhexagon_get_htparch_desc(ctx->socinfo.htp_arch); + std::string dev_desc = std::string(ctx->desc) + + std::string(soc_info) + "_" + std::string(htp_arch) + + "," + std::string(ctx->socinfo.soc_desc); + memset(hexagon_device_desc, 0, GGMLHEXAGON_TMPBUF_LEN); + memcpy(hexagon_device_desc, dev_desc.c_str(), strlen(dev_desc.c_str())); + return hexagon_device_desc; + } else { + return ctx->desc; + } +} + +static void ggml_backend_hexagon_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) { + struct ggml_backend_hexagon_context * ctx = static_cast(dev->context); + if ((nullptr == ctx) || (ctx->device > HEXAGON_BACKEND_GGML)) { + GGMLHEXAGON_LOG_ERROR("pls check params"); + *free = 0; + *total = 0; + } + + if (HEXAGON_BACKEND_QNNCPU == ctx->device || HEXAGON_BACKEND_GGML == ctx->device) { + *total = ggmlhexagon_get_system_total_memory_in_bytes(); + *free = ggmlhexagon_get_system_free_memory_in_bytes(); + } else if (HEXAGON_BACKEND_QNNGPU == ctx->device) { + //TODO: probe GPU info in Qualcomm Adreno GPU + *total = ggmlhexagon_get_system_total_memory_in_bytes(); + *free = ggmlhexagon_get_system_free_memory_in_bytes(); + } else if (HEXAGON_BACKEND_QNNNPU == ctx->device) { + size_t rpc_ion_memsize = 0; + size_t rpc_ion_usage = 0; + GGML_ASSERT(nullptr != ctx->instance); + rpc_ion_memsize = ctx->instance->get_rpcmem_capacity(); + rpc_ion_usage = ctx->instance->get_rpcmem_usage(); + *total = rpc_ion_memsize; + *free = (rpc_ion_memsize - rpc_ion_usage); + GGMLHEXAGON_LOG_DEBUG("rpc memsize %d MiB", rpc_ion_memsize / SIZE_IN_MB); + GGMLHEXAGON_LOG_DEBUG("rpc usage %d MiB\n\n", rpc_ion_usage / SIZE_IN_MB); + } else if (HEXAGON_BACKEND_CDSP == ctx->device) { + size_t rpc_ion_memsize = 0; + size_t rpc_ion_usage = 0; + rpc_ion_memsize = ctx->rpc_mempool_capacity; + rpc_ion_usage = ctx->rpc_mempool_usage; + *total = rpc_ion_memsize; + *free = (rpc_ion_memsize - rpc_ion_usage); + GGMLHEXAGON_LOG_DEBUG("rpc memsize %d MiB", rpc_ion_memsize / SIZE_IN_MB); + GGMLHEXAGON_LOG_DEBUG("rpc usage %d MiB\n\n", rpc_ion_usage / SIZE_IN_MB); + } +} + +static enum ggml_backend_dev_type ggml_backend_hexagon_device_get_type(ggml_backend_dev_t dev) { + struct ggml_backend_hexagon_context * ctx = static_cast(dev->context); + + if (HEXAGON_BACKEND_QNNCPU == ctx->device) + return GGML_BACKEND_DEVICE_TYPE_ACCEL; + else if (HEXAGON_BACKEND_QNNGPU == ctx->device) + return GGML_BACKEND_DEVICE_TYPE_ACCEL; + else if (HEXAGON_BACKEND_QNNNPU == ctx->device) + return GGML_BACKEND_DEVICE_TYPE_ACCEL; + else if (HEXAGON_BACKEND_CDSP == ctx->device) + return GGML_BACKEND_DEVICE_TYPE_GPU; + else + return GGML_BACKEND_DEVICE_TYPE_CPU; +} + +static void ggml_backend_hexagon_device_get_props(ggml_backend_dev_t dev, + struct ggml_backend_dev_props * props) { + props->name = ggml_backend_hexagon_device_get_name(dev); + props->description = ggml_backend_hexagon_device_get_description(dev); + props->type = ggml_backend_hexagon_device_get_type(dev); + ggml_backend_hexagon_device_get_memory(dev, &props->memory_free, &props->memory_total); + props->caps = { + /* .async = */ false, + /* .host_buffer = */ true, + /* .buffer_from_host_ptr = */ false, + /* .events = */ false, + }; + + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + //don't use system memory in this scenario + props->caps.host_buffer = false; + } +} + +static ggml_backend_t ggml_backend_hexagon_device_init_backend(ggml_backend_dev_t dev, const char * params) { + GGML_UNUSED(dev); + GGMLHEXAGON_LOG_DEBUG("enter %s\n", __func__); + size_t dev_index = 0; + + //case-1: test-backend-ops or other similar scenario: calling ggml_backend_dev_init(dev, reinterpret_cast(i)) directly in user's code + ggmlhexagon_load_cfg(); + if (!ggmlhexagon_check_valid_appcfg()) { + return nullptr; + } + + if (nullptr == params) { + GGMLHEXAGON_LOG_DEBUG("program specified param is nullptr"); + dev_index = (g_hexagon_appcfg.hexagon_backend > 0) ? g_hexagon_appcfg.hexagon_backend : 0; + if (dev_index >= GGML_HEXAGON_MAX_DEVICES) { + GGMLHEXAGON_LOG_INFO("assume the default ggml backend"); + return nullptr; + } + } else { + GGMLHEXAGON_LOG_INFO("program specified param is not nullptr"); + //user's program calling ggml_backend_hexagon_device_init_backend directly + dev_index = (int)(intptr_t)params; + g_hexagon_appcfg.hexagon_backend = dev_index; + GGMLHEXAGON_LOG_INFO("program specified dev_index %d\n", dev_index); + } + GGMLHEXAGON_LOG_DEBUG("hexagon_backend=%d", dev_index); + ggml_backend_t hexagon_backend = ggml_backend_hexagon_init(dev_index, g_hexagon_appcfg.runtime_libpath); + GGMLHEXAGON_LOG_DEBUG("leave %s\n", __func__); + + return hexagon_backend; +} + +static ggml_backend_buffer_type_t ggml_backend_hexagon_buffer_type(size_t device_index) { + static std::mutex mutex; + std::lock_guard lock(mutex); + GGMLHEXAGON_LOG_DEBUG("enter %s, device_index %d", __func__, device_index); + if (device_index >= GGML_HEXAGON_MAX_DEVICES) { + GGMLHEXAGON_LOG_DEBUG("ggml_backend_hexagon_buffer_type error: device_index:%d is out of range [0, %d]\n", + device_index, GGML_HEXAGON_MAX_DEVICES - 1); + return nullptr; + } + + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + //cover following special case: + // toggle back and forth frequently between cDSP and ggml in a standard Android APP or in + // a same running process + if (device_index != (size_t)(g_hexagon_appcfg.hexagon_backend)) { + GGMLHEXAGON_LOG_INFO("device_index %d, backend %d", device_index, g_hexagon_appcfg.hexagon_backend); + + g_hexagon_appcfg.hexagon_backend = device_index; + } + } + + static struct ggml_backend_buffer_type ggml_backend_hexagon_buffer_types[GGML_HEXAGON_MAX_DEVICES]; + static bool ggml_backend_hexagon_buffer_type_initialized = false; + if (!ggml_backend_hexagon_buffer_type_initialized) { + for (int i = 0; i < GGML_HEXAGON_MAX_DEVICES; i++) { + ggml_backend_hexagon_buffer_types[i] = { + /* .iface = */ { + /* .get_name = */ ggml_backend_hexagon_buffer_type_name, + /* .alloc_buffer = */ ggml_backend_hexagon_buffer_type_alloc_buffer, + /* .get_alignment = */ ggml_backend_hexagon_buffer_type_get_alignment, + /* .get_max_size = */ ggml_backend_hexagon_buffer_type_get_max_size, + /* .get_alloc_size = */ nullptr,// defaults to ggml_nbytes + /* .is_host = */ ggml_backend_hexagon_buffer_is_host + }, + /* .device = */ ggml_backend_reg_dev_get(ggml_backend_hexagon_reg(), i), + /* .context = */ &g_hexagon_mgr[device_index], + }; + } + ggml_backend_hexagon_buffer_type_initialized = true; + } + + + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + GGML_ASSERT(HEXAGON_BACKEND_CDSP == g_hexagon_appcfg.hexagon_backend); + //FIXME:this is workaround for cover following special case: + // toggle back and forth frequently between cDSP and ggml in a standard Android APP or in a same running process + // there is unknown issue with this workaround when toggle back and forth frequently in a standard Android APP + int result = ggmlhexagon_init_dsp(&g_hexagon_mgr[HEXAGON_BACKEND_CDSP]); + if (0 != result) { + GGMLHEXAGON_LOG_INFO("init hexagon dsp failure"); + return nullptr; + } + } + + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return &ggml_backend_hexagon_buffer_types[device_index]; +} + +static const char * ggml_backend_hexagon_host_buffer_type_name(ggml_backend_buffer_type_t buft) { + GGML_UNUSED(buft); + return "Hexagon_Host"; +} + +static const char * ggml_backend_hexagon_host_buffer_name(ggml_backend_buffer_t buffer) { + GGML_UNUSED(buffer); + return "Hexagon_Host"; +} + +static void ggml_backend_hexagon_host_buffer_free(ggml_backend_buffer_t buffer) { + if (0 == g_hexagon_appcfg.enable_pinned_memory) { + ggml_aligned_free(buffer->context, 0); + } else { + rpcmem_free(buffer->context); + } +} + +static void * ggml_hexagon_host_malloc(ggml_backend_buffer_type_t buft, size_t size) { + if (0 == g_hexagon_appcfg.enable_pinned_memory) { + return ggml_aligned_malloc(size); + } else { + //TODO: there are no corresponding APIs in existing Hexagon SDK, here try to re-use camera ion heap as a pinned memory + return rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, ION_CAMERA_HEAP_ID | RPCMEM_TRY_MAP_STATIC, size); + } +} + +static ggml_backend_buffer_t ggml_backend_hexagon_host_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft, size_t size) { + void * host_ptr = ggml_hexagon_host_malloc(buft, size); + + if (nullptr == host_ptr) { + GGMLHEXAGON_LOG_INFO("failed to alloc host buffer"); + //TODO: use assertion here before find a better approach to release "correct" host buffer + // in function ggml_backend_hexagon_host_buffer_free + GGML_ASSERT(nullptr != host_ptr); + return ggml_backend_buft_alloc_buffer(ggml_backend_cpu_buffer_type(), size); + } else { + GGMLHEXAGON_LOG_INFO("succeed to alloc host buffer %d MiB", size / SIZE_IN_MB); + } + + ggml_backend_buffer_t buffer = ggml_backend_cpu_buffer_from_ptr(host_ptr, size); + buffer->buft = buft; + buffer->iface.free_buffer = ggml_backend_hexagon_host_buffer_free; + + return buffer; +} + +static ggml_backend_buffer_type_t ggml_backend_hexagon_host_buffer_type() { + static struct ggml_backend_buffer_type ggml_backend_hexagon_buffer_type_host = { + /* .iface = */ { + /* .get_name = */ ggml_backend_hexagon_host_buffer_type_name, + /* .alloc_buffer = */ ggml_backend_hexagon_host_buffer_type_alloc_buffer, + /* .get_alignment = */ ggml_backend_cpu_buffer_type()->iface.get_alignment, + /* .get_max_size = */ nullptr, + /* .get_alloc_size = */ ggml_backend_cpu_buffer_type()->iface.get_alloc_size, + /* .is_host = */ ggml_backend_cpu_buffer_type()->iface.is_host, + }, + /* .device = */ ggml_backend_reg_dev_get(ggml_backend_hexagon_reg(), 0), + /* .context = */ nullptr, + }; + + return &ggml_backend_hexagon_buffer_type_host; +} + +static ggml_backend_buffer_type_t ggml_backend_hexagon_device_get_host_buffer_type(ggml_backend_dev_t dev) { + GGML_UNUSED(dev); + return ggml_backend_hexagon_host_buffer_type(); +} + +static ggml_backend_buffer_type_t ggml_backend_hexagon_device_get_buffer_type(ggml_backend_dev_t dev) { + ggml_backend_hexagon_context * ctx = (ggml_backend_hexagon_context *)dev->context; + return ggml_backend_hexagon_buffer_type(ctx->device); +} + +static ggml_backend_buffer_t ggml_backend_hexagon_device_buffer_from_host_ptr(ggml_backend_dev_t dev, + void * ptr, size_t size, size_t max_tensor_size) { + return ggml_backend_cpu_buffer_from_ptr(ptr, size); + + GGML_UNUSED(dev); + GGML_UNUSED(max_tensor_size); +} + +static bool ggml_backend_hexagon_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) { + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + if (ggml_backend_buft_is_hexagon(buft)) { + ggml_backend_hexagon_context * dev_ctx = (ggml_backend_hexagon_context *)dev->context; + ggml_backend_hexagon_context * buft_ctx = (ggml_backend_hexagon_context *)buft->context; + return buft_ctx->device == dev_ctx->device; + } + } + + return ggml_backend_buft_is_host(buft); +} + +static struct ggml_backend_device_i ggml_backend_hexagon_device_interface = { + /* .get_name = */ ggml_backend_hexagon_device_get_name, + /* .get_description = */ ggml_backend_hexagon_device_get_description, + /* .get_memory = */ ggml_backend_hexagon_device_get_memory, + /* .get_type = */ ggml_backend_hexagon_device_get_type, + /* .get_props = */ ggml_backend_hexagon_device_get_props, + /* .init_backend = */ ggml_backend_hexagon_device_init_backend, + /* .get_buffer_type = */ ggml_backend_hexagon_device_get_buffer_type, + /* .get_host_buffer_type = */ ggml_backend_hexagon_device_get_host_buffer_type, + /* .buffer_from_host_ptr = */ ggml_backend_hexagon_device_buffer_from_host_ptr, + /* .supports_op = */ nullptr, + /* .supports_buft = */ ggml_backend_hexagon_device_supports_buft, + /* .offload_op = */ nullptr, + /* .event_new = */ nullptr, + /* .event_free = */ nullptr, + /* .event_synchronize = */ nullptr, +}; + +static ggml_backend_i ggml_backend_hexagon_interface = { + /* .get_name = */ ggml_backend_hexagon_name, + /* .free = */ ggml_backend_hexagon_free, + /* .set_tensor_async = */ nullptr, + /* .get_tensor_async = */ nullptr, + /* .cpy_tensor_async = */ nullptr, + /* .synchronize = */ nullptr, + /* .graph_plan_create = */ nullptr, + /* .graph_plan_free = */ nullptr, + /* .graph_plan_update = */ nullptr, + /* .graph_plan_compute = */ nullptr, + /* .graph_compute = */ nullptr, + /* .event_record = */ nullptr, + /* .event_wait = */ nullptr, +}; + +//FIXME: this guid is not make sense +static ggml_guid_t ggml_backend_hexagon_guid() { + static ggml_guid guid = { + 0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81, + 0x92, 0xa3, 0xb4, 0xc5, 0xd6, 0xe7, 0xf8, 0x09 + }; + return &guid; +} + +bool ggml_backend_is_hexagon(ggml_backend_t backend) { + return backend != nullptr && ggml_guid_matches(backend->guid, ggml_backend_hexagon_guid()); +} + +static void ggml_backend_hexagon_set_n_threads(ggml_backend_t backend, int n_threads) { + GGML_ASSERT(ggml_backend_is_hexagon(backend)); + + struct ggml_backend_hexagon_context * ctx = (struct ggml_backend_hexagon_context *)backend->context; + ctx->n_threads = n_threads; +} + +int ggml_backend_hexagon_get_device_count() { + if (g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP) { + //there only 1 backend_device when g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP + //so return 1 + return 1; + } else { + //QNN-CPU, QNN-GPU, QNN-NPU + return GGML_HEXAGON_MAX_DEVICES - 1; + } +} + +struct ggml_backend_hexagon_reg_context { + std::vector devices; +}; + +static const char * ggml_backend_hexagon_reg_get_name(ggml_backend_reg_t reg) { + GGML_UNUSED(reg); + //return "ggml-hexagon"; + + //return accurate backend name rather than "ggml-hexagon" to + //make compare NPU performance through llama-bench more clear + if (HEXAGON_BACKEND_QNNNPU == g_hexagon_appcfg.hexagon_backend) + return "QNN-NPU"; + + if (HEXAGON_BACKEND_QNNGPU == g_hexagon_appcfg.hexagon_backend) + return "QNN-GPU"; + + if (HEXAGON_BACKEND_QNNCPU == g_hexagon_appcfg.hexagon_backend) + return "QNN-CPU"; + + if (HEXAGON_BACKEND_CDSP == g_hexagon_appcfg.hexagon_backend) + return "Hexagon-cDSP"; + + return "ggml"; +} + +static size_t ggml_backend_hexagon_reg_get_device_count(ggml_backend_reg_t reg) { + GGML_UNUSED(reg); + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + GGML_ASSERT(g_hexagon_appcfg.hexagon_backend == HEXAGON_BACKEND_CDSP); + //there only 1 backend_device when g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP + //so return 1 + return 1; + } else { + //QNN-CPU, QNN-GPU, QNN-NPU + return GGML_HEXAGON_MAX_DEVICES - 1; + } +} + +static ggml_backend_dev_t ggml_backend_hexagon_reg_get_device(ggml_backend_reg_t reg, size_t index) { + GGML_UNUSED(reg); + GGML_UNUSED(index); + + GGMLHEXAGON_LOG_DEBUG("index %d", index); + ggml_backend_hexagon_reg_context * ctx = (ggml_backend_hexagon_reg_context *)reg->context; + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + GGML_ASSERT(g_hexagon_appcfg.hexagon_backend == HEXAGON_BACKEND_CDSP); + //there only 1 backend_device when g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP + //so return ctx->devices[0] + return ctx->devices[0]; + } else { + GGML_ASSERT(index <= ctx->devices.size()); + return ctx->devices[index]; + } +} + +static void * ggml_backend_hexagon_reg_get_proc_address(ggml_backend_reg_t reg, const char * name) { + GGML_UNUSED(reg); + + if (nullptr == name) + return nullptr; + + const char * slot_name = "ggml_backend_set_n_threads"; + if (0 == memcmp(name, slot_name, strlen(slot_name))) { + return (void *)ggml_backend_hexagon_set_n_threads; + } + + return nullptr; +} + +static const ggml_backend_reg_i ggml_backend_hexagon_reg_interface = { + /* .get_name = */ ggml_backend_hexagon_reg_get_name, + /* .get_device_count = */ ggml_backend_hexagon_reg_get_device_count, + /* .get_device = */ ggml_backend_hexagon_reg_get_device, + /* .get_proc_address = */ ggml_backend_hexagon_reg_get_proc_address, +}; + +ggml_backend_reg_t ggml_backend_hexagon_reg() { + static ggml_backend_reg reg; + //TODO: the existing codes can't cover following special case: + // toggle back and forth frequently between QNN-NPU and cDSP and ggml in a standard Android APP or in + // a same running process + // supportive of such special case is easy but it will significantly increase the size of APK + static bool initialized = false; + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__); + + //case-2: normal scenario, such as llama-cli or UI applicaton + ggmlhexagon_load_cfg(); + if (!ggmlhexagon_check_valid_appcfg()) { + return nullptr; + } + + { + static std::mutex mutex; + std::lock_guard lock(mutex); + if (!initialized) { + ggml_backend_hexagon_reg_context * ctx = new ggml_backend_hexagon_reg_context; + + for (int i = 0; i < ggml_backend_hexagon_get_device_count(); i++) { + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + ggml_backend_hexagon_device_interface.supports_op = ggmlhexagon_can_handle_op_through_cdsp; + } else { + ggml_backend_hexagon_device_interface.supports_op = ggmlhexagon_can_handle_op_through_qnn; + } + + if ((HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) && (1 == g_hexagon_appcfg.enable_rpc_ion_mempool)) { + if (0 == g_hexagon_appcfg.enable_pinned_memory) { + //don't use system memory in this scenario + ggml_backend_hexagon_device_interface.get_host_buffer_type = nullptr; + } + } + + GGMLHEXAGON_LOG_DEBUG("create backend device for device %d", i); + ggml_backend_dev_t dev = new ggml_backend_device{ + /* .iface = */ ggml_backend_hexagon_device_interface, + /* .reg = */ ®, + /* .context = */ &g_hexagon_mgr[i] + }; + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + //there only 1 backend_device when g_hexagon_appcfg.hwaccel_approach == HWACCEL_CDSP + //so context is g_hexagon_mgr[HEXAGON_BACKEND_CDSP] rather than g_hexagon_mgr[0] + //attention here: + dev->context = &g_hexagon_mgr[HEXAGON_BACKEND_CDSP]; + } + + ctx->devices.push_back(dev); + + //make cDSP rpc memory pool happy because ggml's backend subsystem need this + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + GGML_ASSERT(HEXAGON_BACKEND_CDSP == g_hexagon_appcfg.hexagon_backend); + int result = ggmlhexagon_init_dsp(&g_hexagon_mgr[HEXAGON_BACKEND_CDSP]); + if (0 != result) { + GGMLHEXAGON_LOG_INFO("init hexagon dsp failure"); + return nullptr; + } + //GGML_ASSERT(0 == result); + } + } + + reg = ggml_backend_reg { + /* .api_version = */ GGML_BACKEND_API_VERSION, + /* .iface = */ ggml_backend_hexagon_reg_interface, + /* .context = */ ctx + }; + } + + initialized = true; + } + GGMLHEXAGON_LOG_DEBUG("leave ggml_backend_hexagon_reg"); + + return ® +} + +const char * ggml_backend_hexagon_get_devname(size_t dev_num) { + switch (dev_num) { + case HEXAGON_BACKEND_QNNCPU: + return "HEXAGON_BACKEND_QNN_CPU"; + case HEXAGON_BACKEND_QNNGPU: + return "HEXAGON_BACKEND_QNN_GPU"; + case HEXAGON_BACKEND_QNNNPU: + return "HEXAGON_BACKEND_QNN_NPU"; + case HEXAGON_BACKEND_CDSP: + return "HEXAGON_BACKEND_CDSP"; + case HEXAGON_BACKEND_GGML: + return "ggml"; //"fake" hexagon backend, used for compare performance between hexagon backend and the default ggml backend + default: + return "unknown"; + } +} + +static qnn_instance * ggmlqnn_init_qnn_instance(size_t device, const char * qnn_lib_path) { + int result = 0; + GGMLHEXAGON_LOG_INFO("device=%d, hwaccel approach=%d(%s)", device, g_hexagon_appcfg.hwaccel_approach, + ggmlhexagon_get_hwaccel_approach_name(g_hexagon_appcfg.hwaccel_approach)); + + qnn_instance * instance = nullptr; + instance = new qnn_instance(qnn_lib_path, g_hexagon_mgr[device].lib, ""); + result = instance->qnn_init(nullptr); + if (0 != result) { + GGMLHEXAGON_LOG_WARN("init qnn subsystem failed with qnn backend %s, pls check why\n", + ggml_backend_hexagon_get_devname(device)); + delete instance; + return nullptr; + } + qnn_interface qnn_interface = instance->get_qnn_interface(); + if (!qnn_interface.is_loaded()) { + GGMLHEXAGON_LOG_WARN("qnn subsystem failure\n"); + delete instance; + return nullptr; + } + + std::string device_name = ggml_backend_hexagon_get_devname(device); + GGMLHEXAGON_LOG_INFO("qnn device name %s", device_name.c_str()); + g_hexagon_mgr[device].instance = instance; + g_hexagon_mgr[device].raw_interface = instance->get_qnn_raw_interface(); + g_hexagon_mgr[device].raw_system_interface = instance->get_qnn_raw_system_interface(); + + return instance; +} + +/** + * + * @param device 0: HEXAGON_BACKEND_QNNCPU 1: HEXAGON_BACKEND_QNNGPU 2: HEXAGON_BACKEND_QNNNPU 3: HEXAGON_BACKEND_CDSP 4: ggml + * @param runtime_libpath binary runtime library path, such as "/data/local/tmp/" on Android or specified in user's code + * @return + */ +ggml_backend_t ggml_backend_hexagon_init(size_t device, const char * runtime_libpath) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__); + if (nullptr == runtime_libpath) + return nullptr; + + //case-3: calling ggml_backend_hexagon_init() directly in user's code + ggmlhexagon_load_cfg(); + if (!ggmlhexagon_check_valid_appcfg()) { + return nullptr; + } + + GGMLHEXAGON_LOG_DEBUG("device %d", device); + GGMLHEXAGON_LOG_DEBUG("runtime libpath %s", runtime_libpath); + if (device >= GGML_HEXAGON_MAX_DEVICES) { + GGMLHEXAGON_LOG_ERROR("invalid device %d", device); + return nullptr; + } + + if (0 != memcmp(runtime_libpath, g_hexagon_appcfg.runtime_libpath, strlen(g_hexagon_appcfg.runtime_libpath))) { + //re-setting runtime libpath + ggmlhexagon_set_runtime_path(device, runtime_libpath); + } + + if (nullptr != g_hexagon_mgr[device].backend) { + GGMLHEXAGON_LOG_DEBUG("backend %d(%s) already loaded", device, + ggml_backend_hexagon_get_devname(device)); + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__); + return g_hexagon_mgr[device].backend; + } + + //don't initialize QNN when hwaccel approach is offload ggml op to Hexagon cDSP directly + if (HWACCEL_CDSP != g_hexagon_appcfg.hwaccel_approach) { + qnn_instance * instance = ggmlqnn_init_qnn_instance(device, runtime_libpath); + if (nullptr == instance) + return nullptr; + } + ggml_backend_hexagon_interface.graph_compute = ggmlhexagon_backend_graph_compute_general; + ggml_backend_t hexagon_backend = new ggml_backend{ + /* .guid = */ ggml_backend_hexagon_guid(), + /* .iface = */ ggml_backend_hexagon_interface, + /* .device = */ ggml_backend_reg_dev_get(ggml_backend_hexagon_reg(), device), + /* .context = */ &g_hexagon_mgr[device] + }; + + g_hexagon_mgr[device].backend = hexagon_backend; + if (HWACCEL_CDSP == g_hexagon_appcfg.hwaccel_approach) { + int result = ggmlhexagon_init_dsp(&g_hexagon_mgr[device]); + if (0 != result) { + GGMLHEXAGON_LOG_INFO("init hexagon dsp failure"); + ggml_backend_hexagon_free(hexagon_backend); + return nullptr; + } + } else { + //get fully description of SoC when hwaccel approach is HWACCEL_QNN and backend is HEXAGON_BACKEND_QNNNPU + GGMLHEXAGON_LOG_INFO("device name %s", ggml_backend_hexagon_device_get_description(hexagon_backend->device)); + } + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__); + + return hexagon_backend; +} + +GGML_BACKEND_DL_IMPL(ggml_backend_hexagon_reg) diff --git a/ggml/src/ggml-hexagon/kernels/Makefile b/ggml/src/ggml-hexagon/kernels/Makefile new file mode 100755 index 0000000000000..0e6b3fa2e4df6 --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/Makefile @@ -0,0 +1,40 @@ +#following vars already defined in CMakeLists.txt +#HTP_ARCH_VERSION=v79 +#DEBUG_FLAG=-DNDEBUG -Wall +#HEXAGON_SDK_PATH=/opt/qcom/Hexagon_SDK/6.2.0.1 + +HEXAGON_COMPUTE=compute${HTP_ARCH_VERSION} +HEXAGON_CC=${HEXAGON_SDK_PATH}/tools/HEXAGON_Tools/8.8.06/Tools/bin/hexagon-clang +HEXAGON_CXX=${HEXAGON_SDK_PATH}/tools/HEXAGON_Tools/8.8.06/Tools/bin/hexagon-clang + +TARGET=libggmlop-skel.so + +$(info HEXAGON_SDK_PATH:${HEXAGON_SDK_PATH}) +$(info HTP_ARCH_VERSION:${HTP_ARCH_VERSION}) +$(info DEBUG_FLAG:${DEBUG_FLAG}) +$(info HEXAGON_COMPUTE:${HEXAGON_COMPUTE}) + +INCS=-I${HEXAGON_SDK_PATH}/incs -I${HEXAGON_SDK_PATH}/libs/qprintf/inc -I${HEXAGON_SDK_PATH}/incs/stddef -I${HEXAGON_SDK_PATH}/ipc/fastrpc/incs -I${HEXAGON_SDK_PATH}/ipc/fastrpc/rpcmem/inc -I${HEXAGON_SDK_PATH}/ipc/fastrpc/rtld/ship/inc -I${HEXAGON_SDK_PATH}/libs/atomic/inc -I${HEXAGON_SDK_PATH}/utils/sim_utils/inc -I${HEXAGON_SDK_PATH}/utils/sim_utils/inc -I${HEXAGON_SDK_PATH}/rtos/qurt/${HEXAGON_COMPUTE}/include/posix -I${HEXAGON_SDK_PATH}/rtos/qurt/${HEXAGON_COMPUTE}/include/qurt/ + +CFLAGS=-m${HTP_ARCH_VERSION} -c -Ofast -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fdata-sections -fpic -D__V_DYNAMIC__ -mhvx -mhvx-length=128B ${INCS} -fno-finite-math-only + +LDFLAGS=-m${HTP_ARCH_VERSION} -Wl,--defsym=ISDB_TRUSTED_FLAG=2 -Wl,--defsym=ISDB_SECURE_FLAG=2 -Wl,--no-threads -fpic -shared -Wl,-Bsymbolic -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=free -Wl,--wrap=realloc -Wl,--wrap=memalign -lc -Wl,-soname=${TARGET} + +#SRCS = $(wildcard *.c) +SRCS = ggml-dsp.c skel.c entry.c add.c mulmat.c +OBJS = $(patsubst %.c, %.o, $(SRCS)) + +ALL:$(OBJS) + ${HEXAGON_CC} ${LDFLAGS} -o ${TARGET} -Wl,--start-group ${OBJS} -Wl,--end-group + @ls -l ${TARGET} + /bin/cp -fv ${TARGET} ../../../../out/android/bin/ + /bin/cp -fv ${TARGET} ../../../../out/android/bin/libggmlop-skel${HTP_ARCH_VERSION}.so + /bin/rm -f *.so + +%.o:%.c + @echo "${HEXAGON_CC} ${CFLAGS} ${DEBUG_FLAG} -D__FILENAME__=\"$<\" -o $@ -c $<" + ${HEXAGON_CC} ${CFLAGS} ${DEBUG_FLAG} -D__FILENAME__=\"$<\" -o $@ -c $< + @echo "\n" + +clean: + rm -f *.o diff --git a/ggml/src/ggml-hexagon/kernels/add.c b/ggml/src/ggml-hexagon/kernels/add.c new file mode 100644 index 0000000000000..25a2d73e23536 --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/add.c @@ -0,0 +1,143 @@ +#include "ggml-dsp.h" + +static inline void l2fetch(const void * p, uint32_t stride, + uint32_t width, uint32_t height, + uint32_t dir) { + uint64_t control = HEXAGON_V64_CREATE_H(dir, stride, width, height); + __asm__ __volatile__ (" l2fetch(%0,%1) " : :"r"(p),"r"(control)); +} + +static inline void ggmlhexagon_dsp_add_f32(const int n, float * GGML_RESTRICT z, const float * GGML_RESTRICT x, const float * GGML_RESTRICT y) { + HVX_Vector * va; + HVX_Vector * vb; + HVX_Vector * vc; + HVX_Vector qf32; + const size_t FLOATS_PER_VECTOR = 128 / sizeof(float); + const size_t block = n / FLOATS_PER_VECTOR; + const size_t left = n % FLOATS_PER_VECTOR; + const size_t blocks = block * FLOATS_PER_VECTOR; + + if ((((uintptr_t)z | (uintptr_t)x | (uintptr_t)y) % ALIGN_128_BYTE) != 0) { + GGMLHEXAGON_LOG_DEBUG("memaddress mismatch alignment 128 bytes z:%p x:%p y:%p", z, x, y); + for (size_t i = 0; i < n; ++i) + z[i] = x[i] + y[i]; + + return; + } + + va = (HVX_Vector *)x; + vb = (HVX_Vector *)y; + vc = (HVX_Vector *)z; + //unroll is better but need more carefully check for various cases and I think DSP also don't like branch predication + for (size_t i = 0; i < block; ++i) { + l2fetch(va + VLEN, VLEN, VLEN, 1, 0); + l2fetch(vb + VLEN, VLEN, VLEN, 1, 0); + //*vc++ = Q6_Vsf_vadd_VsfVsf(*va++, *vb++); + qf32 = Q6_Vqf32_vadd_VsfVsf(*va++, *vb++); + *vc++ = Q6_Vsf_equals_Vqf32(qf32); + } + + if (left > 0) { + for (size_t i = 0; i < left; ++i) + z[i + blocks] = x[i + blocks] + y[i + blocks]; + } +} + +static void ggml_compute_forward_add_f32( + const struct ggml_tensor * src0, + const struct ggml_tensor * src1, + struct ggml_tensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + uint64_t start_time = ggml_time_us(); + + memcpy(dst->ne, src1->ne, 16); + memcpy(dst->nb, src1->nb, 16); + ggmlhexagon_dump_tensor(src0, 1); + ggmlhexagon_dump_tensor(src1, 1); + ggmlhexagon_dump_tensor(dst, 1); + + GGML_ASSERT(ggml_can_repeat(src1, src0) && ggml_are_same_shape(src0, dst)); + + const int rank = ggml_n_dims(src0); + if (1 == rank) { + //element-wise addition with vector + const size_t len = src0->ne[0]; + float * dst_ptr = (float *) (dst->data); + float * src0_ptr = (float *) (src0->data); + float * src1_ptr = (float *) (src1->data); + ggmlhexagon_dsp_add_f32(len, dst_ptr, src0_ptr, src1_ptr); + return; + } + + const int ith = 0; + const int nth = 1; + + const int nr = ggml_nrows(src0); + GGML_TENSOR_BINARY_OP_LOCALS + + GGML_ASSERT( nb0 == sizeof(float)); + GGML_ASSERT(nb00 == sizeof(float)); + + const int dr = (nr + nth - 1)/nth; + const int ir0 = dr*ith; + const int ir1 = MIN(ir0 + dr, nr); + if (nb10 == sizeof(float)) { + for (int ir = ir0; ir < ir1; ++ir) { + // src1 is broadcastable across src0 and dst in i1, i2, i3 + const int32_t i03 = ir/(ne02*ne01); + const int32_t i02 = (ir - i03*ne02*ne01)/ne01; + const int32_t i01 = (ir - i03*ne02*ne01 - i02*ne01); + + const int32_t i13 = i03 % ne13; + const int32_t i12 = i02 % ne12; + const int32_t i11 = i01 % ne11; + const int32_t nr0 = ne00 / ne10; + + float * dst_ptr = (float *) ((char *) dst->data + i03*nb3 + i02*nb2 + i01*nb1 ); + float * src0_ptr = (float *) ((char *) src0->data + i03*nb03 + i02*nb02 + i01*nb01); + float * src1_ptr = (float *) ((char *) src1->data + i13*nb13 + i12*nb12 + i11*nb11); + for (int32_t r = 0; r < nr0; ++r) { + ggmlhexagon_dsp_add_f32(ne10, dst_ptr + r*ne10, src0_ptr + r*ne10, src1_ptr); + } + } + } else { + // src1 is not contiguous + for (int ir = ir0; ir < ir1; ++ir) { + // src1 is broadcastable across src0 and dst in i1, i2, i3 + const int32_t i03 = ir/(ne02*ne01); + const int32_t i02 = (ir - i03*ne02*ne01)/ne01; + const int32_t i01 = (ir - i03*ne02*ne01 - i02*ne01); + + const int32_t i13 = i03 % ne13; + const int32_t i12 = i02 % ne12; + const int32_t i11 = i01 % ne11; + + float * dst_ptr = (float *) ((char *) dst->data + i03*nb3 + i02*nb2 + i01*nb1 ); + float * src0_ptr = (float *) ((char *) src0->data + i03*nb03 + i02*nb02 + i01*nb01); + + for (int32_t i0 = 0; i0 < ne0; ++i0) { + const int32_t i10 = i0 % ne10; + float * src1_ptr = (float *) ((char *) src1->data + i13*nb13 + i12*nb12 + i11*nb11 + i10*nb10); + + dst_ptr[i0] = src0_ptr[i0] + *src1_ptr; + } + } + } + + uint64_t end_time = ggml_time_us(); + uint64_t duration = (end_time - start_time); + GGMLHEXAGON_LOG_DEBUG("duration %llu us", duration); +#if !GGMLHEXAGON_DEBUG + UNUSED(duration); +#endif + + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); +} + +//FIXME: why failed with test-backend-ops when disable ion rpc mempool +int ggmlop_dsp_add(remote_handle64 h, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s\n", __func__); + ggml_compute_forward_add_f32(src0, src1, dst); + GGMLHEXAGON_LOG_DEBUG("leave %s\n", __func__); + return 0; +} diff --git a/ggml/src/ggml-hexagon/kernels/entry.c b/ggml/src/ggml-hexagon/kernels/entry.c new file mode 100644 index 0000000000000..ea38beea673c0 --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/entry.c @@ -0,0 +1,115 @@ +#include "ggml-dsp.h" + +static int32 g_thread_counts = 1; + +int ggmlop_dsp_open(const char * uri, remote_handle64 * handle) { + void * tptr = NULL; + GGMLHEXAGON_LOG_DEBUG("uri %s", uri); + tptr = (void *)malloc(1); + GGML_ASSERT(NULL != tptr); + *handle = (remote_handle64)tptr; + + GGMLHEXAGON_LOG_DEBUG("api_version = 0x%x", qurt_api_version()); + GGMLHEXAGON_LOG_DEBUG("hvx units = 0x%d", qurt_hvx_get_units()); + qurt_arch_version_t vers; + qurt_sysenv_get_arch_version(&vers); + GGMLHEXAGON_LOG_DEBUG("arch_version=0x%x", vers.arch_version); + + qurt_sysenv_app_heap_t aheap; + qurt_sysenv_get_app_heap(&aheap); + GGMLHEXAGON_LOG_DEBUG("aheap.heap_base=0x%x, aheap.heap_limit=0x%x", aheap.heap_base, aheap.heap_limit); + + qurt_sysenv_max_hthreads_t mhwt; + qurt_sysenv_get_max_hw_threads(&mhwt); + GGMLHEXAGON_LOG_DEBUG("max hardware threads counts=%d", mhwt.max_hthreads); + g_thread_counts = mhwt.max_hthreads; + + return 0; +} + +int ggmlop_dsp_close(remote_handle64 handle) { + if (handle) + free((void*)handle); + + return 0; +} + +AEEResult ggmlop_dsp_setclocks(remote_handle64 handle, int32 power_level, int32 latency, int32 dcvs_enabled, int32 thread_counts) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__); + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t)); + request.type = HAP_power_set_apptype; + request.apptype = HAP_POWER_COMPUTE_CLIENT_CLASS; + + GGMLHEXAGON_LOG_DEBUG("user specified thread_counts %d", thread_counts); + if (thread_counts > 1) + g_thread_counts = (thread_counts > g_thread_counts) ? g_thread_counts : thread_counts; + else + g_thread_counts = 1; + GGMLHEXAGON_LOG_DEBUG("real thread_counts %d", g_thread_counts); + + void * ggmop_ctx = (void*)(handle); + int retval = HAP_power_set(ggmop_ctx, &request); + if (retval) { + GGMLHEXAGON_LOG_DEBUG("failed first power vote"); + return AEE_EFAILED; + } + + //configure clocks & DCVS mode + memset(&request, 0, sizeof(HAP_power_request_t)); + request.type = HAP_power_set_DCVS_v2; + request.dcvs_v2.dcvs_enable = TRUE; + request.dcvs_v2.dcvs_params.target_corner = (HAP_dcvs_voltage_corner_t)power_level; + if (dcvs_enabled) { + request.dcvs_v2.dcvs_params.min_corner = HAP_DCVS_VCORNER_DISABLE; + request.dcvs_v2.dcvs_params.max_corner = HAP_DCVS_VCORNER_DISABLE; + } else { + request.dcvs_v2.dcvs_params.min_corner = request.dcvs_v2.dcvs_params.target_corner; + request.dcvs_v2.dcvs_params.max_corner = request.dcvs_v2.dcvs_params.target_corner; + } + request.dcvs_v2.dcvs_option = HAP_DCVS_V2_PERFORMANCE_MODE; + request.dcvs_v2.set_dcvs_params = TRUE; + request.dcvs_v2.set_latency = TRUE; + request.dcvs_v2.latency = latency; + retval = HAP_power_set(ggmop_ctx, &request); + if (retval) { + GGMLHEXAGON_LOG_DEBUG("failed to vote for performance mode"); + return AEE_EFAILED; + } + + memset(&request, 0, sizeof(HAP_power_request_t)); + request.type = HAP_power_set_HVX; + request.hvx.power_up = TRUE; + retval = HAP_power_set(ggmop_ctx, &request); + if (retval) { + GGMLHEXAGON_LOG_DEBUG("failed to vote for HVX power"); + return AEE_EFAILED; + } + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return AEE_SUCCESS; +} + +// ================================================================================================= +// implementation of ggml-hexagon kernel, it's better to put every hexagon-kernel to a single file +// ================================================================================================= +int ggmlop_dsp_softmax(remote_handle64 h, const dsptensor * src0, const dsptensor * src1, dsptensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return 0; +} + +int ggmlop_dsp_rmsnorm(remote_handle64 h, const dsptensor * src0, const dsptensor * src1, dsptensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return 0; +} + +int ggmlop_dsp_pool2d(remote_handle64 h, const dsptensor * src0, const dsptensor * src1, dsptensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return 0; +} + +int ggmlop_get_thread_counts(void) { + return g_thread_counts; +} diff --git a/ggml/src/ggml-hexagon/kernels/ggml-dsp.c b/ggml/src/ggml-hexagon/kernels/ggml-dsp.c new file mode 100644 index 0000000000000..b64209971a0dc --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/ggml-dsp.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2025 The ggml authors + * + * Qualcomm Hexagon SDK and reference tech guides could be found at: + * https://developer.qualcomm.com/software/hexagon-dsp-sdk/tools + * + * this single-source-file or self-contained file is implementation of ggml-dsp: + * - a customized tiny ggml running on Qualcomm Hexagon cDSP + * - ported from original ggml + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "ggml-dsp.h" + +void ggmlhexagon_log_internal(int level, const char *file, const char *func, int line, const char *format, ...) { +#if !GGMLHEXAGON_DEBUG + return; +#endif + static char s_ggmlhexagon_log_internal_buf[GGMLHEXAGON_LOGBUF_LEN]; + va_list args; + va_start(args, format); + int len_prefix = snprintf(s_ggmlhexagon_log_internal_buf, GGMLHEXAGON_LOGBUF_LEN, "[%s, %d]: ", + func, line); + int len = vsnprintf(s_ggmlhexagon_log_internal_buf + len_prefix, + GGMLHEXAGON_LOGBUF_LEN - len_prefix, format, args); + if (len < (GGMLHEXAGON_LOGBUF_LEN - len_prefix)) { + FARF(ALWAYS, "%s\n", s_ggmlhexagon_log_internal_buf); + } + va_end(args); +} + +void ggmlhexagon_dump_tensor_elements(const ggml_tensor * tensor) { +#if !GGMLHEXAGON_DEBUG + return; +#endif + float value = 0; + char tmpbuf[GGMLHEXAGON_LOGBUF_LEN]; + size_t buflen = 0; + if (tensor->type == GGML_TYPE_F32) { + memset(tmpbuf, 0, GGMLHEXAGON_LOGBUF_LEN); + for (int h = 0; h < tensor->ne[3]; h++) { + for (int i = 0; i < tensor->ne[2]; i++) { + for (int j = 0; j < tensor->ne[1]; j++) { + for (int k = 0; k < tensor->ne[0]; k++) { + value = ((float *) tensor->data)[h * tensor->ne[2] + i * tensor->ne[1] + + j * tensor->ne[0] + k]; + buflen += snprintf(tmpbuf + buflen, GGMLHEXAGON_LOGBUF_LEN - buflen, "%-4.2f\t", value); + } + buflen += snprintf(tmpbuf + buflen, GGMLHEXAGON_LOGBUF_LEN - buflen, "\n"); + } + } + } + GGMLHEXAGON_LOG_DEBUG("\n%s\n", tmpbuf); + } + + GGMLHEXAGON_LOG_DEBUG("\n"); +} + +void ggmlhexagon_dump_tensor(const ggml_tensor * tensor, int dump_tensor_data) { + GGMLHEXAGON_LOG_DEBUG("ne = %5d x %5d x %5d x %5d , nb = (%5zi, %5zi, %5zi, %5zi)\n", + tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3], + tensor->nb[0], tensor->nb[1], tensor->nb[2], tensor->nb[3]); + + if ((1 == dump_tensor_data) && (ggml_nbytes(tensor) < 320)) { + ggmlhexagon_dump_tensor_elements(tensor); + } +} + +size_t ggml_row_size(enum ggml_type type, int64_t ne) { + return 4*ne; +} + +size_t ggml_nbytes(const struct ggml_tensor * tensor) { + size_t nbytes; + const size_t blck_size = 1; + if (blck_size == 1) { + nbytes = 4; + for (int i = 0; i < GGML_MAX_DIMS; ++i) { + nbytes += (tensor->ne[i] - 1)*tensor->nb[i]; + } + } else { + nbytes = tensor->ne[0]*tensor->nb[0]/blck_size; + for (int i = 1; i < GGML_MAX_DIMS; ++i) { + nbytes += (tensor->ne[i] - 1)*tensor->nb[i]; + } + } + + return nbytes; +} + +bool ggml_is_empty(const struct ggml_tensor * tensor) { + for (int i = 0; i < GGML_MAX_DIMS; ++i) { + if (tensor->ne[i] == 0) { + return true; + } + } + return false; +} + +bool ggml_can_repeat(const struct ggml_tensor * t0, const struct ggml_tensor * t1) { + static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function"); + + return ggml_is_empty(t0) ? ggml_is_empty(t1) : + (t1->ne[0]%t0->ne[0] == 0) && + (t1->ne[1]%t0->ne[1] == 0) && + (t1->ne[2]%t0->ne[2] == 0) && + (t1->ne[3]%t0->ne[3] == 0); +} + +bool ggml_are_same_shape(const struct ggml_tensor * t0, const struct ggml_tensor * t1) { + static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function"); + return + (t0->ne[0] == t1->ne[0]) && + (t0->ne[1] == t1->ne[1]) && + (t0->ne[2] == t1->ne[2]) && + (t0->ne[3] == t1->ne[3]); +} + +int64_t ggml_nrows(const struct ggml_tensor * tensor) { + static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function"); + + return tensor->ne[1]*tensor->ne[2]*tensor->ne[3]; +} + +bool ggml_is_transposed(const struct ggml_tensor * tensor) { + return tensor->nb[0] > tensor->nb[1]; +} + +bool ggml_is_contiguous_n(const struct ggml_tensor * tensor, int n) { + size_t next_nb = 4; + if (tensor->ne[0] != 1 && tensor->nb[0] != next_nb) { + return false; + } + next_nb *= tensor->ne[0]; + for (int i = 1; i < GGML_MAX_DIMS; i++) { + if (tensor->ne[i] != 1) { + if (i > n) { + if (tensor->nb[i] != next_nb) { + return false; + } + next_nb *= tensor->ne[i]; + } else { + // this dimension does not need to be contiguous + next_nb = tensor->ne[i]*tensor->nb[i]; + } + } + } + return true; +} + +int64_t ggml_nelements(const struct ggml_tensor * tensor) { + static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function"); + + return tensor->ne[0]*tensor->ne[1]*tensor->ne[2]*tensor->ne[3]; +} + +static bool ggml_is_contiguous_0(const struct ggml_tensor * tensor) { + return ggml_is_contiguous_n(tensor, 0); +} + +bool ggml_is_contiguous(const struct ggml_tensor * tensor) { + return ggml_is_contiguous_0(tensor); +} + +int ggml_n_dims(const struct ggml_tensor * tensor) { + for (int i = GGML_MAX_DIMS - 1; i >= 1; --i) { + if (tensor->ne[i] > 1) { + return i + 1; + } + } + return 1; +} + +void ggml_abort(const char * file, int line, const char * fmt, ...) { + GGMLHEXAGON_LOG_DEBUG("enter ggml_abort"); + abort(); +} + +static inline uint64 hexagon_perf_get_time_us(void) { + unsigned long long count; + asm volatile (" %0 = c31:30 " : "=r"(count)); + return (uint64)(count) * 10ull / 192ull; +} + +int64_t ggml_time_ms(void) { + return hexagon_perf_get_time_us() * 1000; +} + +int64_t ggml_time_us(void) { + return hexagon_perf_get_time_us(); +} diff --git a/ggml/src/ggml-hexagon/kernels/ggml-dsp.h b/ggml/src/ggml-hexagon/kernels/ggml-dsp.h new file mode 100644 index 0000000000000..103b46b8ee7fc --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/ggml-dsp.h @@ -0,0 +1,168 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "HAP_perf.h" +#include "HAP_farf.h" +#include "HAP_power.h" +#include "HAP_vtcm_mgr.h" +#include "HAP_compute_res.h" + +#include "qurt.h" +#include "AEEStdErr.h" +#include "hexagon_types.h" +#include "hexagon_protos.h" + +#include "skel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ggml_tensor dsptensor + +#define GGML_MAX_DIMS 4 + +#define ALIGN_128_BYTE 128 + +#define VLEN 128 + +#define GGML_UNUSED(x) (void)(x) + +#define UNUSED GGML_UNUSED + +#define GGML_PAD(x, n) (((x) + (n) - 1) & ~((n) - 1)) + +#define GGML_ABORT(...) ggml_abort(__FILE__, __LINE__, __VA_ARGS__) + +#define GGML_ASSERT(x) if (!(x)) GGML_ABORT("GGML_ASSERT(%s) failed", #x) + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#if UINTPTR_MAX == 0xFFFFFFFF +#define GGML_MEM_ALIGN 4 +#else +#define GGML_MEM_ALIGN 16 +#endif + +#define GGML_API extern + +#ifdef __cplusplus +// restrict not standard in C++ +# if defined(__GNUC__) +# define GGML_RESTRICT __restrict__ +# elif defined(__clang__) +# define GGML_RESTRICT __restrict +# elif defined(_MSC_VER) +# define GGML_RESTRICT __restrict +# else +# define GGML_RESTRICT +# endif +#else +# if defined (_MSC_VER) && (__STDC_VERSION__ < 201112L) +# define GGML_RESTRICT __restrict +# else +# define GGML_RESTRICT restrict +# endif +#endif + +#ifndef __cplusplus +#ifndef static_assert + #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201100L) + #define static_assert(cond, msg) _Static_assert(cond, msg) + #else + #define static_assert(cond, msg) struct global_scope_noop_trick + #endif +#endif +#endif // __cplusplus + + +//NPU performance will be slower when enable GGMLHEXAGON_DEBUG +#ifdef NDEBUG +#define GGMLHEXAGON_DEBUG 0 +#else +#define GGMLHEXAGON_DEBUG 1 +#endif + +#define GGMLHEXAGON_LOGBUF_LEN 4096 +#define GGMLHEXAGON_TMPBUF_LEN 256 +#if GGMLHEXAGON_DEBUG +#define GGMLHEXAGON_LOG_DEBUG(...) ggmlhexagon_log_internal(GGMLHEXAGON_LOG_LEVEL_DEBUG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) +#else +#define GGMLHEXAGON_LOG_DEBUG(...) +#endif + +#define GGML_TENSOR_LOCALS_1(type, prefix, pointer, array) \ + const type prefix##0 = (pointer)->array[0]; \ + GGML_UNUSED(prefix##0); +#define GGML_TENSOR_LOCALS_2(type, prefix, pointer, array) \ + GGML_TENSOR_LOCALS_1 (type, prefix, pointer, array) \ + const type prefix##1 = (pointer)->array[1]; \ + GGML_UNUSED(prefix##1); +#define GGML_TENSOR_LOCALS_3(type, prefix, pointer, array) \ + GGML_TENSOR_LOCALS_2 (type, prefix, pointer, array) \ + const type prefix##2 = (pointer)->array[2]; \ + GGML_UNUSED(prefix##2); +#define GGML_TENSOR_LOCALS(type, prefix, pointer, array) \ + GGML_TENSOR_LOCALS_3 (type, prefix, pointer, array) \ + const type prefix##3 = (pointer)->array[3]; \ + GGML_UNUSED(prefix##3); + +#define GGML_TENSOR_UNARY_OP_LOCALS \ + GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne) \ + GGML_TENSOR_LOCALS(size_t, nb0, src0, nb) \ + GGML_TENSOR_LOCALS(int64_t, ne, dst, ne) \ + GGML_TENSOR_LOCALS(size_t, nb, dst, nb) + +#define GGML_TENSOR_BINARY_OP_LOCALS \ + GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne) \ + GGML_TENSOR_LOCALS(size_t, nb0, src0, nb) \ + GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne) \ + GGML_TENSOR_LOCALS(size_t, nb1, src1, nb) \ + GGML_TENSOR_LOCALS(int64_t, ne, dst, ne) \ + GGML_TENSOR_LOCALS(size_t, nb, dst, nb) + +#define GGML_TENSOR_BINARY_OP_LOCALS01 \ + GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne) \ + GGML_TENSOR_LOCALS(size_t, nb0, src0, nb) \ + GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne) \ + GGML_TENSOR_LOCALS(size_t, nb1, src1, nb) + +enum ggmlhexagon_log_level { + GGMLHEXAGON_LOG_LEVEL_NONE = 0, + GGMLHEXAGON_LOG_LEVEL_DEBUG = 1, +}; + +enum ggml_type { + GGML_TYPE_F32 = 0, +}; + +typedef double ggml_float; + +GGML_API int64_t ggml_time_ms(void); +GGML_API int64_t ggml_time_us(void); + +GGML_API size_t ggml_nbytes(const struct ggml_tensor * tensor); +GGML_API int64_t ggml_nrows(const struct ggml_tensor * tensor); +GGML_API int ggml_n_dims(const struct ggml_tensor * tensor); +GGML_API bool ggml_is_contiguous(const struct ggml_tensor * tensor); +GGML_API void ggml_abort(const char * file, int line, const char * fmt, ...); +GGML_API bool ggml_can_repeat(const struct ggml_tensor * t0, const struct ggml_tensor * t1); +GGML_API bool ggml_are_same_shape(const struct ggml_tensor * t0, const struct ggml_tensor * t1); + +GGML_API void ggmlhexagon_dump_tensor_elements(const ggml_tensor * tensor); +GGML_API void ggmlhexagon_dump_tensor(const ggml_tensor * tensor, int dump_tensor_data); +GGML_API void ggmlhexagon_log_internal(int level, const char *file, const char *func, int line, const char *format, ...); + +GGML_API int ggmlop_get_thread_counts(void); + +#ifdef __cplusplus +} +#endif diff --git a/ggml/src/ggml-hexagon/kernels/mulmat.c b/ggml/src/ggml-hexagon/kernels/mulmat.c new file mode 100644 index 0000000000000..f7494c8eaacf4 --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/mulmat.c @@ -0,0 +1,290 @@ +#include "ggml-dsp.h" + +// 128 byte vectors +#define VSIZE_BYTES 128 +#define VSIZE_WORDS VSIZE_BYTES/4 + +union ui32f { int32_t i; float f; }; + +// create a vector of floats from a float +static __attribute__((always_inline)) HVX_Vector create_sfv_from_sf(float value) { + union ui32f cvt; + cvt.f = value; + HVX_Vector tmp = Q6_V_vsplat_R(cvt.i); + return tmp; +} + +// create a vector of qf32's from a float +static __attribute__((always_inline)) HVX_Vector create_qf32v_from_sf(float value) { + HVX_Vector tmp = Q6_Vqf32_vadd_Vqf32Vsf(Q6_V_vsplat_R(0), create_sfv_from_sf(value)); + return tmp; +} + +// convert qf32 vector to float vector +static __attribute__((always_inline)) HVX_Vector convert_qf32v_to_fltv(HVX_Vector vect) { + HVX_Vector tmp = Q6_Vsf_equals_Vqf32(vect); + return tmp; +} + +// get lowest float from a vector of floats +static __attribute__((always_inline)) float get_flt0_from_fltv(HVX_Vector vect) { + union ui32f cvt; + cvt.i = vect[0]; + return cvt.f; +} + +// get lowest float from a vector of qf32's +static __attribute__((always_inline)) float get_flt0_from_qf32v(HVX_Vector vect) { + union ui32f cvt; + HVX_Vector tmp = convert_qf32v_to_fltv(vect); + cvt.i = tmp[0]; + return cvt.f; +} + +static void vec_dot_f32(int n, float *GGML_RESTRICT s, size_t bs, const float *GGML_RESTRICT x, + size_t bx, const float *GGML_RESTRICT y, size_t by, int nrc) { + assert(nrc == 1); + UNUSED(nrc); + UNUSED(bx); + UNUSED(by); + UNUSED(bs); + // scalar + ggml_float sumf = 0.0; + for (int i = 0; i < n; ++i) { + sumf += (ggml_float) (x[i] * y[i]); + } + *s = sumf; +} + +static void ggml_compute_forward_mul_mat_one_chunk(const ggml_tensor *src0, const ggml_tensor *src1, + struct ggml_tensor *dst, + const enum ggml_type type, + const int32_t num_rows_per_vec_dot, + const int32_t ir0_start, const int32_t ir0_end, + const int32_t ir1_start, const int32_t ir1_end) { + ggmlhexagon_dump_tensor(src0, 0); + ggmlhexagon_dump_tensor(src1, 0); + ggmlhexagon_dump_tensor(dst, 0); + + dst->ne[0] = src0->ne[1]; + dst->ne[1] = src1->ne[1]; + dst->ne[2] = src1->ne[2]; + dst->ne[3] = src1->ne[3]; + + dst->nb[0] = 4; + dst->nb[1] = dst->nb[0] * dst->ne[0]; + dst->nb[2] = dst->nb[1] * dst->ne[1]; + dst->nb[3] = dst->nb[2] * dst->ne[2]; + ggmlhexagon_dump_tensor(dst, 0); + + GGML_TENSOR_BINARY_OP_LOCALS + + const bool src1_cont = ggml_is_contiguous(src1); + + // broadcast factors + const int32_t r2 = ne12 / ne02; + const int32_t r3 = ne13 / ne03; + + if (ir0_start >= ir0_end || ir1_start >= ir1_end) { + return; + } + + const void * wdata = src1->data; + const size_t row_size = 4* ne10; + + assert(ne12 % ne02 == 0); + assert(ne13 % ne03 == 0); + + // block-tiling attempt + const int32_t blck_0 = 16; + const int32_t blck_1 = 16; + + const size_t src1_col_stride = src1_cont || nb11; + + // attempt to reduce false-sharing (does not seem to make a difference) + // 16 * 2, accounting for mmla kernels + float tmp[32]; + + for (int32_t iir1 = ir1_start; iir1 < ir1_end; iir1 += blck_1) { + for (int32_t iir0 = ir0_start; iir0 < ir0_end; iir0 += blck_0) { + for (int32_t ir1 = iir1; ir1 < iir1 + blck_1 && ir1 < ir1_end; ir1 += num_rows_per_vec_dot) { + const int32_t i13 = (ir1 / (ne12 * ne1)); + const int32_t i12 = (ir1 - i13 * ne12 * ne1) / ne1; + const int32_t i11 = (ir1 - i13 * ne12 * ne1 - i12 * ne1); + + // broadcast src0 into src1 + const int32_t i03 = i13 / r3; + const int32_t i02 = i12 / r2; + + const int32_t i1 = i11; + const int32_t i2 = i12; + const int32_t i3 = i13; + + const char * src0_row = (const char*)src0->data + (0 + i02 * nb02 + i03 * nb03); + + // desc: when src1 is not a contiguous memory block we have to calculate the offset using the strides + // if it is, then we have either copied the data to params->wdata and made it contiguous or we are using + // the original src1 data pointer, so we should index using the indices directly + const char * src1_col = (const char*)wdata + + (src1_cont + ? (i11 + i12 * ne11 + i13 * ne12 * ne11) * row_size + : (i11 * nb11 + i12 * nb12 + i13 * nb13)); + float * dst_col = (float*)((char*)dst->data + (i1 * nb1 + i2 * nb2 + i3 * nb3)); + + for (int32_t ir0 = iir0; ir0 < iir0 + blck_0 && ir0 < ir0_end; ir0 += num_rows_per_vec_dot) { + vec_dot_f32(ne00, &tmp[ir0 - iir0], (num_rows_per_vec_dot > 1 ? 16 : 0), + (float*)(src0_row + ir0 * nb01), (num_rows_per_vec_dot > 1 ? nb01 : 0), + (float*)src1_col, (num_rows_per_vec_dot > 1 ? src1_col_stride : 0), num_rows_per_vec_dot); + } + + for (int cn = 0; cn < num_rows_per_vec_dot; ++cn) { + memcpy(&dst_col[iir0 + cn * nb1 / nb0], tmp + (cn * 16), (MIN(iir0 + blck_0, ir0_end) - iir0) * sizeof(float)); + } + } + } + } +} + +//TODO: only support fp32 mulmat on cDSP +static int ggmlop_dsp_mulmat_singlethread(remote_handle64 h, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + ggmlhexagon_dump_tensor(src0, 0); + ggmlhexagon_dump_tensor(src1, 0); + ggmlhexagon_dump_tensor(dst, 0); + + dst->ne[0] = src0->ne[1]; + dst->ne[1] = src1->ne[1]; + dst->ne[2] = src1->ne[2]; + dst->ne[3] = src1->ne[3]; + + dst->nb[0] = 4; + dst->nb[1] = dst->nb[0] * dst->ne[0]; + dst->nb[2] = dst->nb[1] * dst->ne[1]; + dst->nb[3] = dst->nb[2] * dst->ne[2]; + ggmlhexagon_dump_tensor(dst, 0); + + GGML_TENSOR_BINARY_OP_LOCALS + + int32_t const vec_dot_num_rows = 1; + + GGML_ASSERT(ne0 == ne01); + GGML_ASSERT(ne1 == ne11); + GGML_ASSERT(ne2 == ne12); + GGML_ASSERT(ne3 == ne13); + + // we don't support permuted src0 or src1 + GGML_ASSERT(nb00 == 4); + GGML_ASSERT(nb10 == 4); + + // dst cannot be transposed or permuted + GGML_ASSERT(nb0 == sizeof(float)); + GGML_ASSERT(nb0 <= nb1); + GGML_ASSERT(nb1 <= nb2); + GGML_ASSERT(nb2 <= nb3); + +#if 0 //naive algorithm for fp32, can pass various case in UT + { + //ggml_dump_tensor(src0); + //ggml_dump_tensor(src1); + + float * a = (float*)src0->data; + float * b = (float*)src1->data; + float * c = (float*)dst->data; + int M = src0->ne[1]; + int K = src0->ne[0]; + int N = src1->ne[1]; + float sum = 0; + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + sum = 0; + for (int h = 0; h < K; h++) { + sum += a[i * K + h] * b[h * N + j]; + } + c[i * N + j] = sum; + } + } + return 0; + } +#endif + + // This is the size of the first dimension of the result, so we can iterate that way. (see the ASSERT above, these are the same numbers) + const int32_t nr0 = ne0; + + // This is the size of the rest of the dimensions of the result + const int32_t nr1 = ne1 * ne2 * ne3; + + // Now select a reasonable chunk size. + int chunk_size = 16; + + // We need to step up the size if it's small + if (nr0 == 1 || nr1 == 1) { + chunk_size = 64; + } + + // distribute the work across the inner or outer loop based on which one is larger + // The number of chunks in the 0/1 dim. + // CEIL(nr0/chunk_size) + int32_t nchunk0 = (nr0 + chunk_size - 1) / chunk_size; + int32_t nchunk1 = (nr1 + chunk_size - 1) / chunk_size; + + // If the chunking is poor for the number of threads on this setup, scrap the whole plan. Re-chunk it by thread. + // Also, chunking by thread was measured to have perform better on NUMA systems. See https://github.com/ggml-org/llama.cpp/pull/6915 + // In theory, chunking should be just as useful on NUMA and non NUMA systems, but testing disagreed with that. + if (nchunk0 * nchunk1 < 4) { + // distribute the thread work across the inner or outer loop based on which one is larger + nchunk0 = 1; // parallelize by src0 rows + nchunk1 = 1; // parallelize by src1 rows + } + + // The number of elements in each chunk + const int32_t dr0 = (nr0 + nchunk0 - 1) / nchunk0; + const int32_t dr1 = (nr1 + nchunk1 - 1) / nchunk1; + + // The first chunk comes from our thread_id, the rest will get auto-assigned. + int current_chunk = 0; + + while (current_chunk < nchunk0 * nchunk1) { + const int32_t ith0 = current_chunk % nchunk0; + const int32_t ith1 = current_chunk / nchunk0; + + const int32_t ir0_start = dr0 * ith0; + const int32_t ir0_end = MIN(ir0_start + dr0, nr0); + + const int32_t ir1_start = dr1 * ith1; + const int32_t ir1_end = MIN(ir1_start + dr1, nr1); + + // dot kernels can handle 1 row and col at a time, but mmla kernels can process 2 rows and cols + int32_t num_rows_per_vec_dot = vec_dot_num_rows; + + // these checks are needed to avoid crossing dim1 boundaries + // can be optimized, but the logic would become more complicated, so keeping it like this for simplicity + if ((nr0 % 2 != 0) || (ne11 % 2 != 0) || ((ir0_end - ir0_start) % 2 != 0) || ((ir1_end - ir1_start) % 2 != 0)) { + num_rows_per_vec_dot = 1; + } + ggml_compute_forward_mul_mat_one_chunk(src0, src1, dst, src0->type, num_rows_per_vec_dot, + ir0_start, ir0_end, ir1_start, ir1_end); + + if (1 >= nchunk0 * nchunk1) { + break; + } + current_chunk++; + } + + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return 0; +} + +//TODO:multithreading mulmat +static int ggmlop_dsp_mulmat_multithread(remote_handle64 h, const struct dsptensor * src0, const struct dsptensor * src1, dsptensor * dst) { + GGMLHEXAGON_LOG_DEBUG("enter %s", __func__ ); + GGMLHEXAGON_LOG_DEBUG("leave %s", __func__ ); + return 0; +} + +int ggmlop_dsp_mulmat(remote_handle64 h, const struct dsptensor * src0, const struct dsptensor * src1, dsptensor * dst) { + if (ggmlop_get_thread_counts() > 1) { + return ggmlop_dsp_mulmat_multithread(h, src0, src1, dst); + } else { + return ggmlop_dsp_mulmat_singlethread(h, src0, src1, dst); + } +} diff --git a/ggml/src/ggml-hexagon/kernels/skel.c b/ggml/src/ggml-hexagon/kernels/skel.c new file mode 100644 index 0000000000000..26da58273f013 --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/skel.c @@ -0,0 +1,621 @@ +//qidl copyright +//qidl nested=false +#include "skel.h" + +#include +#ifndef _WIN32 +#include "HAP_farf.h" +#endif //_WIN32 for HAP_farf +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H + +#include +#include + +typedef struct _heap _heap; +struct _heap { + _heap* pPrev; + const char* loc; + uint64_t buf; +}; + +typedef struct _allocator { + _heap* pheap; + uint8_t* stack; + uint8_t* stackEnd; + int nSize; +} _allocator; + +_ATTRIBUTE_UNUSED +static __inline int _heap_alloc(_heap** ppa, const char* loc, int size, void** ppbuf) { + _heap* pn = 0; + pn = MALLOC((size_t)size + sizeof(_heap) - sizeof(uint64_t)); + if(pn != 0) { + pn->pPrev = *ppa; + pn->loc = loc; + *ppa = pn; + *ppbuf = (void*)&(pn->buf); + return 0; + } else { + return -1; + } +} +#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1)) + +_ATTRIBUTE_UNUSED +static __inline int _allocator_alloc(_allocator* me, + const char* loc, + int size, + unsigned int al, + void** ppbuf) { + if(size < 0) { + return -1; + } else if (size == 0) { + *ppbuf = 0; + return 0; + } + if((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + (size_t)size) < (uintptr_t)me->stack + (size_t)me->nSize) { + *ppbuf = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al); + me->stackEnd = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size; + return 0; + } else { + return _heap_alloc(&me->pheap, loc, size, ppbuf); + } +} + +_ATTRIBUTE_UNUSED +static __inline void _allocator_deinit(_allocator* me) { + _heap* pa = me->pheap; + while(pa != 0) { + _heap* pn = pa; + const char* loc = pn->loc; + (void)loc; + pa = pn->pPrev; + FREE(pn); + } +} + +_ATTRIBUTE_UNUSED +static __inline void _allocator_init(_allocator* me, uint8_t* stack, int stackSize) { + me->stack = stack; + me->stackEnd = stack + stackSize; + me->nSize = stackSize; + me->pheap = 0; +} + + +#endif // _ALLOCATOR_H + +#ifndef SLIM_H +#define SLIM_H + +#include + +//a C data structure for the idl types that can be used to implement +//static and dynamic language bindings fairly efficiently. +// +//the goal is to have a minimal ROM and RAM footprint and without +//doing too many allocations. A good way to package these things seemed +//like the module boundary, so all the idls within one module can share +//all the type references. + + +#define PARAMETER_IN 0x0 +#define PARAMETER_OUT 0x1 +#define PARAMETER_INOUT 0x2 +#define PARAMETER_ROUT 0x3 +#define PARAMETER_INROUT 0x4 + +//the types that we get from idl +#define TYPE_OBJECT 0x0 +#define TYPE_INTERFACE 0x1 +#define TYPE_PRIMITIVE 0x2 +#define TYPE_ENUM 0x3 +#define TYPE_STRING 0x4 +#define TYPE_WSTRING 0x5 +#define TYPE_STRUCTURE 0x6 +#define TYPE_UNION 0x7 +#define TYPE_ARRAY 0x8 +#define TYPE_SEQUENCE 0x9 + +//these require the pack/unpack to recurse +//so it's a hint to those languages that can optimize in cases where +//recursion isn't necessary. +#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE) +#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION) +#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY) +#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE) + + +typedef struct Type Type; + +#define INHERIT_TYPE\ + int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\ + union {\ + struct {\ + const uintptr_t p1;\ + const uintptr_t p2;\ + } _cast;\ + struct {\ + uint32_t iid;\ + uint32_t bNotNil;\ + } object;\ + struct {\ + const Type *arrayType;\ + int32_t nItems;\ + } array;\ + struct {\ + const Type *seqType;\ + int32_t nMaxLen;\ + } seqSimple; \ + struct {\ + uint32_t bFloating;\ + uint32_t bSigned;\ + } prim; \ + const SequenceType* seqComplex;\ + const UnionType *unionType;\ + const StructType *structType;\ + int32_t stringMaxLen;\ + uint8_t bInterfaceNotNil;\ + } param;\ + uint8_t type;\ + uint8_t nativeAlignment\ + +typedef struct UnionType UnionType; +typedef struct StructType StructType; +typedef struct SequenceType SequenceType; +struct Type { + INHERIT_TYPE; +}; + +struct SequenceType { + const Type * seqType; + uint32_t nMaxLen; + uint32_t inSize; + uint32_t routSizePrimIn; + uint32_t routSizePrimROut; +}; + +//byte offset from the start of the case values for +//this unions case value array. it MUST be aligned +//at the alignment requrements for the descriptor +// +//if negative it means that the unions cases are +//simple enumerators, so the value read from the descriptor +//can be used directly to find the correct case +typedef union CaseValuePtr CaseValuePtr; +union CaseValuePtr { + const uint8_t* value8s; + const uint16_t* value16s; + const uint32_t* value32s; + const uint64_t* value64s; +}; + +//these are only used in complex cases +//so I pulled them out of the type definition as references to make +//the type smaller +struct UnionType { + const Type *descriptor; + uint32_t nCases; + const CaseValuePtr caseValues; + const Type * const *cases; + int32_t inSize; + int32_t routSizePrimIn; + int32_t routSizePrimROut; + uint8_t inAlignment; + uint8_t routAlignmentPrimIn; + uint8_t routAlignmentPrimROut; + uint8_t inCaseAlignment; + uint8_t routCaseAlignmentPrimIn; + uint8_t routCaseAlignmentPrimROut; + uint8_t nativeCaseAlignment; + uint8_t bDefaultCase; +}; + +struct StructType { + uint32_t nMembers; + const Type * const *members; + int32_t inSize; + int32_t routSizePrimIn; + int32_t routSizePrimROut; + uint8_t inAlignment; + uint8_t routAlignmentPrimIn; + uint8_t routAlignmentPrimROut; +}; + +typedef struct Parameter Parameter; +struct Parameter { + INHERIT_TYPE; + uint8_t mode; + uint8_t bNotNil; +}; + +#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64)) +#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff) + +typedef struct Method Method; +struct Method { + uint32_t uScalars; //no method index + int32_t primInSize; + int32_t primROutSize; + int maxArgs; + int numParams; + const Parameter * const *params; + uint8_t primInAlignment; + uint8_t primROutAlignment; +}; + +typedef struct Interface Interface; + +struct Interface { + int nMethods; + const Method * const *methodArray; + int nIIds; + const uint32_t *iids; + const uint16_t* methodStringArray; + const uint16_t* methodStrings; + const char* strings; +}; + + +#endif //SLIM_H + + +#ifndef _GGMLOP_SLIM_H +#define _GGMLOP_SLIM_H +#include + +#ifndef __QAIC_SLIM +#define __QAIC_SLIM(ff) ff +#endif +#ifndef __QAIC_SLIM_EXPORT +#define __QAIC_SLIM_EXPORT +#endif + +static const Type types[5]; +static const Type* const typeArrays[7] = {&(types[0]),&(types[1]),&(types[1]),&(types[0]),&(types[2]),&(types[0]),&(types[3])}; +static const StructType structTypes[1] = {{0x7,&(typeArrays[0]),0x70,0x4,0x6c,0x4,0x4,0x4}}; +static const Type types[5] = {{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4},{0x10,{{(const uintptr_t)&(types[0]),(const uintptr_t)0x4}}, 8,0x4},{0x40,{{(const uintptr_t)&(types[0]),(const uintptr_t)0x10}}, 8,0x4},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[4]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8)},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4}}; +static const Parameter parameters[6] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),3,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x74,0x80),{{(const uintptr_t)&(structTypes[0]),0}}, 22,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x74,0x80),{{(const uintptr_t)&(structTypes[0]),0}}, 22,SLIM_IFPTR32(0x4,0x8),3,0}}; +static const Parameter* const parameterArrays[9] = {(&(parameters[4])),(&(parameters[4])),(&(parameters[5])),(&(parameters[3])),(&(parameters[3])),(&(parameters[3])),(&(parameters[0])),(&(parameters[1])),(&(parameters[2]))}; +static const Method methods[4] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x1),0x4,0x0,2,2,(&(parameterArrays[6])),0x4,0x1},{REMOTE_SCALARS_MAKEX(0,0,0x0,0x0,0x1,0x0),0x0,0x0,1,1,(&(parameterArrays[8])),0x1,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0xc,0x0,3,3,(&(parameterArrays[3])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x3,0x2,0x0,0x0),0xe4,0x6c,3,3,(&(parameterArrays[0])),0x4,0x4}}; +static const Method* const methodArrays[8] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3]),&(methods[3]),&(methods[3]),&(methods[3]),&(methods[3])}; +static const char strings[167] = "dsp_setclocks\0dsp_rmsnorm\0dsp_softmax\0dcvs_enable\0power_level\0dsp_pool2d\0dsp_mulmat\0op_params\0dsp_add\0latency\0flags\0close\0src1\0data\0type\0src0\0open\0dst\0uri\0op\0nb\0ne\0h\0"; +static const uint16_t methodStrings[134] = {62,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,14,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,26,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,73,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,94,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,0,50,102,38,142,151,164,116,164}; +static const uint16_t methodStringsArrays[8] = {129,132,125,100,75,50,25,0}; +__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(ggmlop_slim) = {8,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; +#endif //_GGMLOP_SLIM_H +extern int adsp_mmap_fd_getinfo(int, uint32_t *); +#ifdef __cplusplus +extern "C" { +#endif +_ATTRIBUTE_VISIBILITY uint32_t ggmlop_skel_handle_invoke_qaic_version = 10048; +_ATTRIBUTE_VISIBILITY char ggmlop_skel_handle_invoke_uri[77+1]="file:///libggmlop-skel.so?ggmlop_skel_handle_invoke&_modver=1.0&_idlver=0.0.1"; +static __inline int _skel_pack(_ATTRIBUTE_UNUSED remote_arg* _praROutPost, _ATTRIBUTE_UNUSED remote_arg* _ppraROutPost[1], _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _rout0[1], _ATTRIBUTE_UNUSED uint32_t _rout1[4], _ATTRIBUTE_UNUSED uint32_t _rout2[4], _ATTRIBUTE_UNUSED uint32_t _rout3[1], _ATTRIBUTE_UNUSED uint32_t _rout4[16], _ATTRIBUTE_UNUSED uint32_t _rout5[1], _ATTRIBUTE_UNUSED char* _rout6[1], _ATTRIBUTE_UNUSED uint32_t _rout6Len[1]) { + int _nErr = 0; + remote_arg* _praROutPostStart = _praROutPost; + remote_arg** _ppraROutPostStart = _ppraROutPost; + _ppraROutPost = &_praROutPost; + _COPY(_primROut, 0, _rout0, 0, 4); + _COPY(_primROut, 4, _rout1, 0, 16); + _COPY(_primROut, 20, _rout2, 0, 16); + _COPY(_primROut, 36, _rout3, 0, 4); + _COPY(_primROut, 40, _rout4, 0, 64); + _COPY(_primROut, 104, _rout5, 0, 4); + _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) +1; + return _nErr; +} +static __inline int _skel_unpack(_ATTRIBUTE_UNUSED _allocator* _al, _ATTRIBUTE_UNUSED remote_arg* _praIn, _ATTRIBUTE_UNUSED remote_arg* _ppraIn[1], _ATTRIBUTE_UNUSED remote_arg* _praROut, _ATTRIBUTE_UNUSED remote_arg* _ppraROut[1], _ATTRIBUTE_UNUSED remote_arg* _praHIn, _ATTRIBUTE_UNUSED remote_arg* _ppraHIn[1], _ATTRIBUTE_UNUSED remote_arg* _praHROut, _ATTRIBUTE_UNUSED remote_arg* _ppraHROut[1], _ATTRIBUTE_UNUSED void* _primIn, _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _rout0[1], _ATTRIBUTE_UNUSED uint32_t _rout1[4], _ATTRIBUTE_UNUSED uint32_t _rout2[4], _ATTRIBUTE_UNUSED uint32_t _rout3[1], _ATTRIBUTE_UNUSED uint32_t _rout4[16], _ATTRIBUTE_UNUSED uint32_t _rout5[1], _ATTRIBUTE_UNUSED char* _rout6[1], _ATTRIBUTE_UNUSED uint32_t _rout6Len[1]) { + int _nErr = 0; + remote_arg* _praInStart = _praIn; + remote_arg** _ppraInStart = _ppraIn; + remote_arg* _praROutStart = _praROut; + remote_arg** _ppraROutStart = _ppraROut; + _ppraIn = &_praIn; + _ppraROut = &_praROut; + _COPY(_rout6Len, 0, _primIn, 0, 4); + _QAIC_ASSERT(_nErr, ((_praROut[0].buf.nLen / 4)) >= (size_t)(_rout6Len[0])); + _rout6[0] = _praROut[0].buf.pv; + _ppraInStart[0] += (_praIn - _praInStart) + 0; + _ppraROutStart[0] += (_praROut - _praROutStart) +1; + _QAIC_CATCH(_nErr) {} + return _nErr; +} +static __inline int _skel_unpack_1(_ATTRIBUTE_UNUSED _allocator* _al, _ATTRIBUTE_UNUSED remote_arg* _praIn, _ATTRIBUTE_UNUSED remote_arg* _ppraIn[1], _ATTRIBUTE_UNUSED remote_arg* _praROut, _ATTRIBUTE_UNUSED remote_arg* _ppraROut[1], _ATTRIBUTE_UNUSED remote_arg* _praHIn, _ATTRIBUTE_UNUSED remote_arg* _ppraHIn[1], _ATTRIBUTE_UNUSED remote_arg* _praHROut, _ATTRIBUTE_UNUSED remote_arg* _ppraHROut[1], _ATTRIBUTE_UNUSED void* _primIn, _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _in0[1], _ATTRIBUTE_UNUSED uint32_t _in1[4], _ATTRIBUTE_UNUSED uint32_t _in2[4], _ATTRIBUTE_UNUSED uint32_t _in3[1], _ATTRIBUTE_UNUSED uint32_t _in4[16], _ATTRIBUTE_UNUSED uint32_t _in5[1], _ATTRIBUTE_UNUSED char* _in6[1], _ATTRIBUTE_UNUSED uint32_t _in6Len[1]) { + int _nErr = 0; + remote_arg* _praInStart = _praIn; + remote_arg** _ppraInStart = _ppraIn; + remote_arg* _praROutStart = _praROut; + remote_arg** _ppraROutStart = _ppraROut; + _ppraIn = &_praIn; + _ppraROut = &_praROut; + _COPY(_in0, 0, _primIn, 0, 4); + _COPY(_in1, 0, _primIn, 4, 16); + _COPY(_in2, 0, _primIn, 20, 16); + _COPY(_in3, 0, _primIn, 36, 4); + _COPY(_in4, 0, _primIn, 40, 64); + _COPY(_in5, 0, _primIn, 104, 4); + _COPY(_in6Len, 0, _primIn, 108, 4); + _QAIC_ASSERT(_nErr, ((_praIn[0].buf.nLen / 4)) >= (size_t)(_in6Len[0])); + _in6[0] = _praIn[0].buf.pv; + _ppraInStart[0] += (_praIn - _praInStart) + 1; + _ppraROutStart[0] += (_praROut - _praROutStart) +0; + _QAIC_CATCH(_nErr) {} + return _nErr; +} +static __inline int _skel_method(int (*_pfn)(remote_handle64, const dsptensor*, const dsptensor*, dsptensor*), remote_handle64 _h, uint32_t _sc, remote_arg* _pra) { + remote_arg* _praEnd = 0; + uintptr_t _in0[SLIM_IFPTR32(29, 16)] = {0}; + uintptr_t _in1[SLIM_IFPTR32(29, 16)] = {0}; + uintptr_t _rout2[SLIM_IFPTR32(29, 16)] = {0}; + uint32_t* _primIn= 0; + int _numIn[1] = {0}; + uint32_t* _primROut= 0; + int _numInH[1] = {0}; + int _numROut[1] = {0}; + remote_arg* _praIn = 0; + remote_arg* _praROut = 0; + remote_arg* _praROutPost = 0; + remote_arg** _ppraROutPost = &_praROutPost; + _allocator _al[1] = {{0}}; + remote_arg** _ppraIn = &_praIn; + remote_arg** _ppraROut = &_praROut; + remote_arg* _praHIn = 0; + remote_arg** _ppraHIn = &_praHIn; + remote_arg* _praHROut = 0; + remote_arg** _ppraHROut = &_praHROut; + int _nErr = 0; + _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INBUFS(_sc)>=1); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTBUFS(_sc)>=1); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, (_pra + ((1 + 1) + (((0 + 0) + 0) + 0))) <= _praEnd); + _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1); + _QAIC_ASSERT(_nErr, _pra[0].buf.nLen >= 228); + _primIn = _pra[0].buf.pv; + _QAIC_ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 108); + _primROut = _pra[(_numIn[0] + 1)].buf.pv; + _numInH[0] = REMOTE_SCALARS_INHANDLES(_sc); + _numROut[0] = REMOTE_SCALARS_OUTBUFS(_sc); + _praIn = (_pra + 1); + _praROut = (_praIn + _numIn[0] + 1); + _praROutPost = _praROut; + _allocator_init(_al, 0, 0); + if(_praHIn == 0) + { + _praHIn = ((_praROut + _numROut[0]) + 1); + } + if(_praHROut == 0) + (_praHROut = _praHIn + _numInH[0] + 0); + _TRY(_nErr, _skel_unpack_1(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 0), 0, (uint32_t*)&(((uint32_t*)_in0)[0]), (uint32_t*)&(((uint32_t*)_in0)[1]), (uint32_t*)&(((uint32_t*)_in0)[5]), (uint32_t*)&(((uint32_t*)_in0)[9]), (uint32_t*)&(((uint32_t*)_in0)[10]), (uint32_t*)&(((uint32_t*)_in0)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in0)[27]), (char**)&(((uint64_t*)_in0)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in0)[28]), (uint32_t*)&(((uint32_t*)_in0)[30])))); + _TRY(_nErr, _skel_unpack_1(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 112), 0, (uint32_t*)&(((uint32_t*)_in1)[0]), (uint32_t*)&(((uint32_t*)_in1)[1]), (uint32_t*)&(((uint32_t*)_in1)[5]), (uint32_t*)&(((uint32_t*)_in1)[9]), (uint32_t*)&(((uint32_t*)_in1)[10]), (uint32_t*)&(((uint32_t*)_in1)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in1)[27]), (char**)&(((uint64_t*)_in1)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in1)[28]), (uint32_t*)&(((uint32_t*)_in1)[30])))); + _TRY(_nErr, _skel_unpack(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 224), ((char*)_primROut + 0), (uint32_t*)&(((uint32_t*)_rout2)[0]), (uint32_t*)&(((uint32_t*)_rout2)[1]), (uint32_t*)&(((uint32_t*)_rout2)[5]), (uint32_t*)&(((uint32_t*)_rout2)[9]), (uint32_t*)&(((uint32_t*)_rout2)[10]), (uint32_t*)&(((uint32_t*)_rout2)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_rout2)[27]), (char**)&(((uint64_t*)_rout2)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_rout2)[28]), (uint32_t*)&(((uint32_t*)_rout2)[30])))); + _TRY(_nErr, _pfn(_h, (const dsptensor*)_in0, (const dsptensor*)_in1, (dsptensor*)_rout2)); + _TRY(_nErr, _skel_pack((_praROutPost + 0), _ppraROutPost, ((char*)_primROut + 0), (uint32_t*)&(((uint32_t*)_rout2)[0]), (uint32_t*)&(((uint32_t*)_rout2)[1]), (uint32_t*)&(((uint32_t*)_rout2)[5]), (uint32_t*)&(((uint32_t*)_rout2)[9]), (uint32_t*)&(((uint32_t*)_rout2)[10]), (uint32_t*)&(((uint32_t*)_rout2)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_rout2)[27]), (char**)&(((uint64_t*)_rout2)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_rout2)[28]), (uint32_t*)&(((uint32_t*)_rout2)[30])))); + _QAIC_CATCH(_nErr) {} + _allocator_deinit(_al); + return _nErr; +} +static __inline int _skel_method_1(int (*_pfn)(remote_handle64, int32, int32, int32, int32), remote_handle64 _h, uint32_t _sc, remote_arg* _pra) { + remote_arg* _praEnd = 0; + uint32_t _in0[1] = {0}; + uint32_t _in1[1] = {0}; + uint32_t _in2[1] = {0}; + uint32_t _in3[1] = {0}; + uint32_t* _primIn= 0; + int _nErr = 0; + _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INBUFS(_sc)==1); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTBUFS(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, (_pra + ((1 + 0) + (((0 + 0) + 0) + 0))) <= _praEnd); + _QAIC_ASSERT(_nErr, _pra[0].buf.nLen >= 12); + _primIn = _pra[0].buf.pv; + _COPY(_in0, 0, _primIn, 0, 4); + _COPY(_in1, 0, _primIn, 4, 4); + _COPY(_in2, 0, _primIn, 8, 4); + _COPY(_in3, 0, _primIn, 12, 4); + _TRY(_nErr, _pfn(_h, (int32)*_in0, (int32)*_in1, (int32)*_in2, (int32)*_in3)); + _QAIC_CATCH(_nErr) {} + return _nErr; +} +static __inline int _skel_method_2(int (*_pfn)(remote_handle64), uint32_t _sc, remote_arg* _pra) { + remote_arg* _praEnd = 0; + remote_handle64 _in0[1] = {0}; + remote_arg* _praRHandleIn = _pra + REMOTE_SCALARS_INBUFS(_sc) + REMOTE_SCALARS_OUTBUFS(_sc); + int _nErr = 0; + _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INBUFS(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTBUFS(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INHANDLES(_sc)==1); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, (_pra + ((0 + 0) + (((1 + 0) + 0) + 0))) <= _praEnd); + _COPY(_in0, 0, &(_praRHandleIn[0].h64), 0, sizeof(remote_handle64)); + _TRY(_nErr, _pfn((remote_handle64)*_in0)); + _QAIC_CATCH(_nErr) {} + return _nErr; +} +static __inline int _compare_versions(char* stub_ver, char* skel_ver, int* result) { + unsigned long int major_stub = 0, minor_stub = 0, patch_stub = 0; + unsigned long int major_skel = 0, minor_skel = 0, patch_skel = 0; + char *saveptr1 = NULL; + char *token1 = NULL; + char *saveptr2 = NULL; + char *token2 = NULL; + int i=0; + for (i=0, token1 = strtok_r(stub_ver, ".", &saveptr1); i<3 && token1 != NULL; i++, token1 = strtok_r(NULL, ".", &saveptr1)) + { + unsigned long int tn = strtoul(token1, NULL,10); + if( tn > 999) + { + *result=-1; + return 0; + } + else + { + if(i==0) major_stub=tn; + if(i==1) minor_stub=tn; + if(i==2) patch_stub=tn; + } + } + for (i=0, token2 = strtok_r(skel_ver, ".", &saveptr2); i<3 && token2 != NULL; i++, token2 = strtok_r(NULL, ".", &saveptr2)) + { + unsigned long int tn = strtoul(token2, NULL,10); + if( tn > 999) + { + *result=-1; + return 0; + } + else + { + if(i==0) major_skel=tn; + if(i==1) minor_skel=tn; + if(i==2) patch_skel=tn; + } + } + if(major_stub=patch_stub)) + { + *result=1; + return 0; + } + } + *result=-1; + return 0; +} +static __inline int _stub_skel_version_check(char*_in0, int* resVal) { + int _nErr = 0; + char* p = strstr(_in0, "_idlver="); + if(!p) + { + *resVal = -1; + return 0; + } + p+=8; + int i=0,len=0, comVer=0,num_delimit=0, updtInxStub=0, updtInxSkel=0; + for(i=0;i2) + { + *resVal = -1; + return 0; + } + if ((p[i]>='0' && p[i]<='9') || (p[i]=='.')) + { + len++; + if(p[i]=='.') + { + num_delimit++; + } + } + else if(p[i]=='&') + { + break; + } + else + { + *resVal = -1; + return 0; + } + } + char* stubVer=(char*)MALLOC(len+1); + _QAIC_ASSERT(_nErr, stubVer!=NULL); + for(i=0;i='0' && p[i]<='9') || (p[i]=='.')) + { + stubVer[updtInxStub]=p[i]; + updtInxStub++; + } + else if(p[i]=='&') + { + break; + } + } + stubVer[len]='\0'; + char* skelVer=(char*)MALLOC(strlen(IDL_VERSION)+1); + _QAIC_ASSERT(_nErr, skelVer!=NULL); + for(i=0;i< strlen(IDL_VERSION);i++) + { + skelVer[updtInxSkel]=IDL_VERSION[i]; + updtInxSkel++; + } + skelVer[strlen(IDL_VERSION)]='\0'; + _TRY(_nErr, _compare_versions(stubVer, skelVer, &comVer)); + *resVal = 0; + if (comVer==-1) + { + *resVal = -1; + } + FREE(stubVer); + FREE(skelVer); + _QAIC_CATCH(_nErr) {} + return 0; +} +static __inline int _skel_method_3(int (*_pfn)(const char*, remote_handle64*), uint32_t _sc, remote_arg* _pra) { + remote_arg* _praEnd = 0; + char* _in0[1] = {0}; + uint32_t _in0Len[1] = {0}; + remote_handle64 _rout1[1] = {0}; + uint32_t* _primIn= 0; + remote_arg* _praRHandleROut = _pra + REMOTE_SCALARS_INBUFS(_sc) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) ; + remote_arg* _praIn = 0; + int _nErr = 0; + _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INBUFS(_sc)==2); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTBUFS(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_INHANDLES(_sc)==0); + _QAIC_ASSERT(_nErr, REMOTE_SCALARS_OUTHANDLES(_sc)==1); + _QAIC_ASSERT(_nErr, (_pra + ((2 + 0) + (((0 + 1) + 0) + 0))) <= _praEnd); + _QAIC_ASSERT(_nErr, _pra[0].buf.nLen >= 4); + _primIn = _pra[0].buf.pv; + _COPY(_in0Len, 0, _primIn, 0, 4); + _praIn = (_pra + 1); + _QAIC_ASSERT(_nErr, ((_praIn[0].buf.nLen / 1)) >= (size_t)(_in0Len[0])); + _in0[0] = _praIn[0].buf.pv; + _QAIC_ASSERT(_nErr, (_in0Len[0] > 0) && (_in0[0][(_in0Len[0] - 1)] == 0)); + int resVal; + _TRY(_nErr, _stub_skel_version_check(*_in0, &resVal)); + if(resVal==-1) + { + return AEE_ESTUBSKELVERMISMATCH; + } + _TRY(_nErr, _pfn((const char*)*_in0, (remote_handle64*)_rout1)); + _COPY(&(_praRHandleROut[0].h64), 0, _rout1, 0, sizeof(remote_handle64)); + _QAIC_CATCH(_nErr) {} + return _nErr; +} +__QAIC_SKEL_EXPORT int __QAIC_SKEL(ggmlop_skel_handle_invoke)(remote_handle64 _h, uint32_t _sc, remote_arg* _pra) __QAIC_SKEL_ATTRIBUTE { + switch(REMOTE_SCALARS_METHOD(_sc)){ + case 0: + return _skel_method_3(__QAIC_IMPL(ggmlop_dsp_open), _sc, _pra); + case 1: + return _skel_method_2(__QAIC_IMPL(ggmlop_dsp_close), _sc, _pra); + case 2: + return _skel_method_1(__QAIC_IMPL(ggmlop_dsp_setclocks), _h, _sc, _pra); + case 3: + return _skel_method(__QAIC_IMPL(ggmlop_dsp_add), _h, _sc, _pra); + case 4: + return _skel_method(__QAIC_IMPL(ggmlop_dsp_mulmat), _h, _sc, _pra); + case 5: + return _skel_method(__QAIC_IMPL(ggmlop_dsp_softmax), _h, _sc, _pra); + case 6: + return _skel_method(__QAIC_IMPL(ggmlop_dsp_rmsnorm), _h, _sc, _pra); + case 7: + return _skel_method(__QAIC_IMPL(ggmlop_dsp_pool2d), _h, _sc, _pra); + } + return AEE_EUNSUPPORTED; +} diff --git a/ggml/src/ggml-hexagon/kernels/skel.h b/ggml/src/ggml-hexagon/kernels/skel.h new file mode 100644 index 0000000000000..194c71e6ecb2a --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/skel.h @@ -0,0 +1,287 @@ +#ifndef _SKEL_H +#define _SKEL_H +//qidl copyright +//qidl nested=false +#include +#include +#include +#include + + +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifndef _QAIC_ENV_H +#define _QAIC_ENV_H + +#include +#ifdef _WIN32 +#include "qtest_stdlib.h" +#else +#define MALLOC malloc +#define FREE free +#endif + +#ifdef __GNUC__ +#ifdef __clang__ +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#else +#pragma GCC diagnostic ignored "-Wpragmas" +#endif +#pragma GCC diagnostic ignored "-Wuninitialized" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#ifndef _ATTRIBUTE_UNUSED + +#ifdef _WIN32 +#define _ATTRIBUTE_UNUSED +#else +#define _ATTRIBUTE_UNUSED __attribute__ ((unused)) +#endif + +#endif // _ATTRIBUTE_UNUSED + +#ifndef _ATTRIBUTE_VISIBILITY + +#ifdef _WIN32 +#define _ATTRIBUTE_VISIBILITY +#else +#define _ATTRIBUTE_VISIBILITY __attribute__ ((visibility("default"))) +#endif + +#endif // _ATTRIBUTE_VISIBILITY + +#ifndef __QAIC_REMOTE +#define __QAIC_REMOTE(ff) ff +#endif //__QAIC_REMOTE + +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE + +#ifndef __QAIC_STUB +#define __QAIC_STUB(ff) ff +#endif //__QAIC_STUB + +#ifndef __QAIC_STUB_EXPORT +#define __QAIC_STUB_EXPORT +#endif // __QAIC_STUB_EXPORT + +#ifndef __QAIC_STUB_ATTRIBUTE +#define __QAIC_STUB_ATTRIBUTE +#endif // __QAIC_STUB_ATTRIBUTE + +#ifndef __QAIC_SKEL +#define __QAIC_SKEL(ff) ff +#endif //__QAIC_SKEL__ + +#ifndef __QAIC_SKEL_EXPORT +#define __QAIC_SKEL_EXPORT +#endif // __QAIC_SKEL_EXPORT + +#ifndef __QAIC_SKEL_ATTRIBUTE +#define __QAIC_SKEL_ATTRIBUTE +#endif // __QAIC_SKEL_ATTRIBUTE + +#ifdef __QAIC_DEBUG__ + #ifndef __QAIC_DBG_PRINTF__ + #include + #define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0) + #endif +#else + #define __QAIC_DBG_PRINTF__( ee ) (void)0 +#endif + + +#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof))) + +#define _COPY(dst, dof, src, sof, sz) \ + do {\ + struct __copy { \ + char ar[sz]; \ + };\ + *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\ + } while (0) + +#define _COPYIF(dst, dof, src, sof, sz) \ + do {\ + if(_OFFSET(dst, dof) != _OFFSET(src, sof)) {\ + _COPY(dst, dof, src, sof, sz); \ + } \ + } while (0) + +_ATTRIBUTE_UNUSED +static __inline void _qaic_memmove(void* dst, void* src, int size) { + int i = 0; + for(i = 0; i < size; ++i) { + ((char*)dst)[i] = ((char*)src)[i]; + } +} + +#define _MEMMOVEIF(dst, src, sz) \ + do {\ + if(dst != src) {\ + _qaic_memmove(dst, src, sz);\ + } \ + } while (0) + + +#define _ASSIGN(dst, src, sof) \ + do {\ + dst = OFFSET(src, sof); \ + } while (0) + +#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str)) + +#include "AEEStdErr.h" + +#ifdef _WIN32 +#define _QAIC_FARF(level, msg, ...) (void)0 +#else +#define _QAIC_FARF(level, msg, ...) (void)0 +#endif //_WIN32 for _QAIC_FARF + +#define _TRY(ee, func) \ + do { \ + if (AEE_SUCCESS != ((ee) = func)) {\ + __QAIC_DBG_PRINTF__((__FILE__ ":%d:error:%d:%s\n", __LINE__, (int)(ee),#func));\ + goto ee##bail;\ + } \ + } while (0) + +#define _TRY_FARF(ee, func) \ + do { \ + if (AEE_SUCCESS != ((ee) = func)) {\ + goto ee##farf##bail;\ + } \ + } while (0) + +#define _QAIC_CATCH(exception) exception##bail: if (exception != AEE_SUCCESS) + +#define _CATCH_FARF(exception) exception##farf##bail: if (exception != AEE_SUCCESS) + +#define _QAIC_ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS) + +#ifdef __QAIC_DEBUG__ +#define _QAIC_ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv));\ + _QAIC_ASSERT(nErr,pv || !(size)) +#else +#define _QAIC_ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, 0, size, alignment, (void**)&pv));\ + _QAIC_ASSERT(nErr,pv || !(size)) +#endif + + +#endif // _QAIC_ENV_H + +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__) +#define __QAIC_STRING1_OBJECT_DEFINED__ +#define __STRING1_OBJECT__ +typedef struct _cstring1_s { + char* data; + int dataLen; +} _cstring1_t; + +#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */ +/// Enabling stub-skel mismatch check feature in the auto-gen files. +/// Please refer to the IDL documentation for more details on the feature. +/// It is fully supported only on Kailua and later targets. +#define IDL_VERSION "0.0.1" +typedef struct dsptensor dsptensor; +struct dsptensor { + int32_t type; + int32_t ne[4]; + int32_t nb[4]; + int32_t op; + int32_t op_params[16]; + int32_t flags; + void * data; + int data_len; +}; +/** + * Opens the handle in the specified domain. If this is the first + * handle, this creates the session. Typically this means opening + * the device, aka open("/dev/adsprpc-smd"), then calling ioctl + * device APIs to create a PD on the DSP to execute our code in, + * then asking that PD to dlopen the .so and dlsym the skel function. + * + * @param uri, _URI"&_dom=aDSP" + * _URI is a QAIC generated uri, or + * "file:///?_skel_handle_invoke&_modver=1.0" + * If the _dom parameter is not present, _dom=DEFAULT is assumed + * but not forwarded. + * Reserved uri keys: + * [0]: first unamed argument is the skel invoke function + * _dom: execution domain name, _dom=mDSP/aDSP/DEFAULT + * _modver: module version, _modver=1.0 + * _*: any other key name starting with an _ is reserved + * Unknown uri keys/values are forwarded as is. + * @param h, resulting handle + * @retval, 0 on success + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_open)(const char* uri, remote_handle64* h) __QAIC_HEADER_ATTRIBUTE; +/** + * Closes a handle. If this is the last handle to close, the session + * is closed as well, releasing all the allocated resources. + + * @param h, the handle to close + * @retval, 0 on success, should always succeed + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_close)(remote_handle64 h) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT AEEResult __QAIC_HEADER(ggmlop_dsp_setclocks)(remote_handle64 _h, int32 power_level, int32 latency, int32 dcvs_enable, int32 threads) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_add)(remote_handle64 _h, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_mulmat)(remote_handle64 _h, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_softmax)(remote_handle64 _h, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_rmsnorm)(remote_handle64 _h, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(ggmlop_dsp_pool2d)(remote_handle64 _h, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_HEADER_ATTRIBUTE; +#ifndef ggmlop_URI +#define ggmlop_URI "file:///libggmlop-skel.so?ggmlop_skel_handle_invoke&_modver=1.0&_idlver=0.0.1" +#endif /*ggmlop_URI*/ +#ifdef __cplusplus +} +#endif +#endif //_SKEL_H diff --git a/ggml/src/ggml-hexagon/kernels/stub.c b/ggml/src/ggml-hexagon/kernels/stub.c new file mode 100644 index 0000000000000..6074d243610df --- /dev/null +++ b/ggml/src/ggml-hexagon/kernels/stub.c @@ -0,0 +1,463 @@ +//qidl copyright +//qidl nested=false +#include "skel.h" +#include +#ifndef _WIN32 +#include "HAP_farf.h" +#include +#endif //_WIN32 for HAP_farf +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H + +#include +#include + +typedef struct _heap _heap; +struct _heap { + _heap* pPrev; + const char* loc; + uint64_t buf; +}; + +typedef struct _allocator { + _heap* pheap; + uint8_t* stack; + uint8_t* stackEnd; + int nSize; +} _allocator; + +_ATTRIBUTE_UNUSED +static __inline int _heap_alloc(_heap** ppa, const char* loc, int size, void** ppbuf) { + _heap* pn = 0; + pn = MALLOC((size_t)size + sizeof(_heap) - sizeof(uint64_t)); + if(pn != 0) { + pn->pPrev = *ppa; + pn->loc = loc; + *ppa = pn; + *ppbuf = (void*)&(pn->buf); + return 0; + } else { + return -1; + } +} +#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1)) + +_ATTRIBUTE_UNUSED +static __inline int _allocator_alloc(_allocator* me, + const char* loc, + int size, + unsigned int al, + void** ppbuf) { + if(size < 0) { + return -1; + } else if (size == 0) { + *ppbuf = 0; + return 0; + } + if((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + (size_t)size) < (uintptr_t)me->stack + (size_t)me->nSize) { + *ppbuf = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al); + me->stackEnd = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size; + return 0; + } else { + return _heap_alloc(&me->pheap, loc, size, ppbuf); + } +} + +_ATTRIBUTE_UNUSED +static __inline void _allocator_deinit(_allocator* me) { + _heap* pa = me->pheap; + while(pa != 0) { + _heap* pn = pa; + const char* loc = pn->loc; + (void)loc; + pa = pn->pPrev; + FREE(pn); + } +} + +_ATTRIBUTE_UNUSED +static __inline void _allocator_init(_allocator* me, uint8_t* stack, int stackSize) { + me->stack = stack; + me->stackEnd = stack + stackSize; + me->nSize = stackSize; + me->pheap = 0; +} + + +#endif // _ALLOCATOR_H + +#ifndef SLIM_H +#define SLIM_H + +#include + +//a C data structure for the idl types that can be used to implement +//static and dynamic language bindings fairly efficiently. +// +//the goal is to have a minimal ROM and RAM footprint and without +//doing too many allocations. A good way to package these things seemed +//like the module boundary, so all the idls within one module can share +//all the type references. + + +#define PARAMETER_IN 0x0 +#define PARAMETER_OUT 0x1 +#define PARAMETER_INOUT 0x2 +#define PARAMETER_ROUT 0x3 +#define PARAMETER_INROUT 0x4 + +//the types that we get from idl +#define TYPE_OBJECT 0x0 +#define TYPE_INTERFACE 0x1 +#define TYPE_PRIMITIVE 0x2 +#define TYPE_ENUM 0x3 +#define TYPE_STRING 0x4 +#define TYPE_WSTRING 0x5 +#define TYPE_STRUCTURE 0x6 +#define TYPE_UNION 0x7 +#define TYPE_ARRAY 0x8 +#define TYPE_SEQUENCE 0x9 + +//these require the pack/unpack to recurse +//so it's a hint to those languages that can optimize in cases where +//recursion isn't necessary. +#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE) +#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION) +#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY) +#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE) + + +typedef struct Type Type; + +#define INHERIT_TYPE\ + int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\ + union {\ + struct {\ + const uintptr_t p1;\ + const uintptr_t p2;\ + } _cast;\ + struct {\ + uint32_t iid;\ + uint32_t bNotNil;\ + } object;\ + struct {\ + const Type *arrayType;\ + int32_t nItems;\ + } array;\ + struct {\ + const Type *seqType;\ + int32_t nMaxLen;\ + } seqSimple; \ + struct {\ + uint32_t bFloating;\ + uint32_t bSigned;\ + } prim; \ + const SequenceType* seqComplex;\ + const UnionType *unionType;\ + const StructType *structType;\ + int32_t stringMaxLen;\ + uint8_t bInterfaceNotNil;\ + } param;\ + uint8_t type;\ + uint8_t nativeAlignment\ + +typedef struct UnionType UnionType; +typedef struct StructType StructType; +typedef struct SequenceType SequenceType; +struct Type { + INHERIT_TYPE; +}; + +struct SequenceType { + const Type * seqType; + uint32_t nMaxLen; + uint32_t inSize; + uint32_t routSizePrimIn; + uint32_t routSizePrimROut; +}; + +//byte offset from the start of the case values for +//this unions case value array. it MUST be aligned +//at the alignment requrements for the descriptor +// +//if negative it means that the unions cases are +//simple enumerators, so the value read from the descriptor +//can be used directly to find the correct case +typedef union CaseValuePtr CaseValuePtr; +union CaseValuePtr { + const uint8_t* value8s; + const uint16_t* value16s; + const uint32_t* value32s; + const uint64_t* value64s; +}; + +//these are only used in complex cases +//so I pulled them out of the type definition as references to make +//the type smaller +struct UnionType { + const Type *descriptor; + uint32_t nCases; + const CaseValuePtr caseValues; + const Type * const *cases; + int32_t inSize; + int32_t routSizePrimIn; + int32_t routSizePrimROut; + uint8_t inAlignment; + uint8_t routAlignmentPrimIn; + uint8_t routAlignmentPrimROut; + uint8_t inCaseAlignment; + uint8_t routCaseAlignmentPrimIn; + uint8_t routCaseAlignmentPrimROut; + uint8_t nativeCaseAlignment; + uint8_t bDefaultCase; +}; + +struct StructType { + uint32_t nMembers; + const Type * const *members; + int32_t inSize; + int32_t routSizePrimIn; + int32_t routSizePrimROut; + uint8_t inAlignment; + uint8_t routAlignmentPrimIn; + uint8_t routAlignmentPrimROut; +}; + +typedef struct Parameter Parameter; +struct Parameter { + INHERIT_TYPE; + uint8_t mode; + uint8_t bNotNil; +}; + +#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64)) +#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff) + +typedef struct Method Method; +struct Method { + uint32_t uScalars; //no method index + int32_t primInSize; + int32_t primROutSize; + int maxArgs; + int numParams; + const Parameter * const *params; + uint8_t primInAlignment; + uint8_t primROutAlignment; +}; + +typedef struct Interface Interface; + +struct Interface { + int nMethods; + const Method * const *methodArray; + int nIIds; + const uint32_t *iids; + const uint16_t* methodStringArray; + const uint16_t* methodStrings; + const char* strings; +}; + + +#endif //SLIM_H + + +#ifndef _GGMLOP_SLIM_H +#define _GGMLOP_SLIM_H +#include + +#ifndef __QAIC_SLIM +#define __QAIC_SLIM(ff) ff +#endif +#ifndef __QAIC_SLIM_EXPORT +#define __QAIC_SLIM_EXPORT +#endif + +static const Type types[5]; +static const Type* const typeArrays[7] = {&(types[0]),&(types[1]),&(types[1]),&(types[0]),&(types[2]),&(types[0]),&(types[3])}; +static const StructType structTypes[1] = {{0x7,&(typeArrays[0]),0x70,0x4,0x6c,0x4,0x4,0x4}}; +static const Type types[5] = {{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4},{0x10,{{(const uintptr_t)&(types[0]),(const uintptr_t)0x4}}, 8,0x4},{0x40,{{(const uintptr_t)&(types[0]),(const uintptr_t)0x10}}, 8,0x4},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[4]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8)},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4}}; +static const Parameter parameters[6] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),3,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x74,0x80),{{(const uintptr_t)&(structTypes[0]),0}}, 22,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x74,0x80),{{(const uintptr_t)&(structTypes[0]),0}}, 22,SLIM_IFPTR32(0x4,0x8),3,0}}; +static const Parameter* const parameterArrays[9] = {(&(parameters[4])),(&(parameters[4])),(&(parameters[5])),(&(parameters[3])),(&(parameters[3])),(&(parameters[3])),(&(parameters[0])),(&(parameters[1])),(&(parameters[2]))}; +static const Method methods[4] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x1),0x4,0x0,2,2,(&(parameterArrays[6])),0x4,0x1},{REMOTE_SCALARS_MAKEX(0,0,0x0,0x0,0x1,0x0),0x0,0x0,1,1,(&(parameterArrays[8])),0x1,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0xc,0x0,3,3,(&(parameterArrays[3])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x3,0x2,0x0,0x0),0xe4,0x6c,3,3,(&(parameterArrays[0])),0x4,0x4}}; +static const Method* const methodArrays[8] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3]),&(methods[3]),&(methods[3]),&(methods[3]),&(methods[3])}; +static const char strings[167] = "dsp_setclocks\0dsp_rmsnorm\0dsp_softmax\0dcvs_enable\0power_level\0dsp_pool2d\0dsp_mulmat\0op_params\0dsp_add\0latency\0flags\0close\0src1\0data\0type\0src0\0open\0dst\0uri\0op\0nb\0ne\0h\0"; +static const uint16_t methodStrings[134] = {62,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,14,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,26,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,73,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,94,137,132,161,158,155,84,110,127,122,132,161,158,155,84,110,127,147,132,161,158,155,84,110,127,0,50,102,38,142,151,164,116,164}; +static const uint16_t methodStringsArrays[8] = {129,132,125,100,75,50,25,0}; +__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(ggmlop_slim) = {8,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; +#endif //_GGMLOP_SLIM_H + + +#ifdef __cplusplus +extern "C" { +#endif +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_open)(const char* uri, remote_handle64* h) __QAIC_STUB_ATTRIBUTE { + return __QAIC_REMOTE(remote_handle64_open)(uri, h); +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_close)(remote_handle64 h) __QAIC_STUB_ATTRIBUTE { + return __QAIC_REMOTE(remote_handle64_close)(h); +} +static __inline int _stub_method(remote_handle64 _handle, uint32_t _mid, uint32_t _in0[1], uint32_t _in1[1], uint32_t _in2[1], uint32_t _in3[1]) { + remote_arg _pra[1] = {0}; + uint32_t _primIn[4]= {0}; + int _nErr = 0; + _pra[0].buf.pv = (void*)_primIn; + _pra[0].buf.nLen = sizeof(_primIn); + _COPY(_primIn, 0, _in0, 0, 4); + _COPY(_primIn, 4, _in1, 0, 4); + _COPY(_primIn, 8, _in2, 0, 4); + _COPY(_primIn, 12,_in3, 0, 4); + _TRY_FARF(_nErr, __QAIC_REMOTE(remote_handle64_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 1, 0, 0, 0), _pra)); + _CATCH_FARF(_nErr) { + _QAIC_FARF(RUNTIME_ERROR, "ERROR 0x%x: handle=0x%"PRIx64", scalar=0x%x, method ID=%d: %s failed\n", _nErr , _handle, REMOTE_SCALARS_MAKEX(0, _mid, 1, 0, 0, 0), _mid, __func__); + } + return _nErr; +} +__QAIC_STUB_EXPORT AEEResult __QAIC_STUB(ggmlop_dsp_setclocks)(remote_handle64 _handle, int32 power_level, int32 latency, int32 dcvs_enable, int32 threads) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 2; + return _stub_method(_handle, _mid, (uint32_t*)&power_level, (uint32_t*)&latency, (uint32_t*)&dcvs_enable, (uint32_t*)&threads); +} +static __inline int _stub_unpack(_ATTRIBUTE_UNUSED remote_arg* _praROutPost, _ATTRIBUTE_UNUSED remote_arg* _ppraROutPost[1], _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _rout0[1], _ATTRIBUTE_UNUSED uint32_t _rout1[4], _ATTRIBUTE_UNUSED uint32_t _rout2[4], _ATTRIBUTE_UNUSED uint32_t _rout3[1], _ATTRIBUTE_UNUSED uint32_t _rout4[16], _ATTRIBUTE_UNUSED uint32_t _rout5[1], _ATTRIBUTE_UNUSED char* _rout6[1], _ATTRIBUTE_UNUSED uint32_t _rout6Len[1]) { + int _nErr = 0; + remote_arg* _praROutPostStart = _praROutPost; + remote_arg** _ppraROutPostStart = _ppraROutPost; + _ppraROutPost = &_praROutPost; + _COPY(_rout0, 0, _primROut, 0, 4); + _COPY(_rout1, 0, _primROut, 4, 16); + _COPY(_rout2, 0, _primROut, 20, 16); + _COPY(_rout3, 0, _primROut, 36, 4); + _COPY(_rout4, 0, _primROut, 40, 64); + _COPY(_rout5, 0, _primROut, 104, 4); + _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) +1; + return _nErr; +} +static __inline int _stub_pack(_ATTRIBUTE_UNUSED _allocator* _al, _ATTRIBUTE_UNUSED remote_arg* _praIn, _ATTRIBUTE_UNUSED remote_arg* _ppraIn[1], _ATTRIBUTE_UNUSED remote_arg* _praROut, _ATTRIBUTE_UNUSED remote_arg* _ppraROut[1], _ATTRIBUTE_UNUSED remote_arg* _praHIn, _ATTRIBUTE_UNUSED remote_arg* _ppraHIn[1], _ATTRIBUTE_UNUSED remote_arg* _praHROut, _ATTRIBUTE_UNUSED remote_arg* _ppraHROut[1], _ATTRIBUTE_UNUSED void* _primIn, _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _rout0[1], _ATTRIBUTE_UNUSED uint32_t _rout1[4], _ATTRIBUTE_UNUSED uint32_t _rout2[4], _ATTRIBUTE_UNUSED uint32_t _rout3[1], _ATTRIBUTE_UNUSED uint32_t _rout4[16], _ATTRIBUTE_UNUSED uint32_t _rout5[1], _ATTRIBUTE_UNUSED char* _rout6[1], _ATTRIBUTE_UNUSED uint32_t _rout6Len[1]) { + int _nErr = 0; + remote_arg* _praInStart = _praIn; + remote_arg** _ppraInStart = _ppraIn; + remote_arg* _praROutStart = _praROut; + remote_arg** _ppraROutStart = _ppraROut; + _ppraIn = &_praIn; + _ppraROut = &_praROut; + _COPY(_primIn, 0, _rout6Len, 0, 4); + _praROut[0].buf.pv = _rout6[0]; + _praROut[0].buf.nLen = (4 * _rout6Len[0]); + _ppraInStart[0] += (_praIn - _praInStart) + 0; + _ppraROutStart[0] += (_praROut - _praROutStart) +1; + return _nErr; +} +static __inline int _stub_pack_1(_ATTRIBUTE_UNUSED _allocator* _al, _ATTRIBUTE_UNUSED remote_arg* _praIn, _ATTRIBUTE_UNUSED remote_arg* _ppraIn[1], _ATTRIBUTE_UNUSED remote_arg* _praROut, _ATTRIBUTE_UNUSED remote_arg* _ppraROut[1], _ATTRIBUTE_UNUSED remote_arg* _praHIn, _ATTRIBUTE_UNUSED remote_arg* _ppraHIn[1], _ATTRIBUTE_UNUSED remote_arg* _praHROut, _ATTRIBUTE_UNUSED remote_arg* _ppraHROut[1], _ATTRIBUTE_UNUSED void* _primIn, _ATTRIBUTE_UNUSED void* _primROut, _ATTRIBUTE_UNUSED uint32_t _in0[1], _ATTRIBUTE_UNUSED uint32_t _in1[4], _ATTRIBUTE_UNUSED uint32_t _in2[4], _ATTRIBUTE_UNUSED uint32_t _in3[1], _ATTRIBUTE_UNUSED uint32_t _in4[16], _ATTRIBUTE_UNUSED uint32_t _in5[1], _ATTRIBUTE_UNUSED char* _in6[1], _ATTRIBUTE_UNUSED uint32_t _in6Len[1]) { + int _nErr = 0; + remote_arg* _praInStart = _praIn; + remote_arg** _ppraInStart = _ppraIn; + remote_arg* _praROutStart = _praROut; + remote_arg** _ppraROutStart = _ppraROut; + _ppraIn = &_praIn; + _ppraROut = &_praROut; + _COPY(_primIn, 0, _in0, 0, 4); + _COPY(_primIn, 4, _in1, 0, 16); + _COPY(_primIn, 20, _in2, 0, 16); + _COPY(_primIn, 36, _in3, 0, 4); + _COPY(_primIn, 40, _in4, 0, 64); + _COPY(_primIn, 104, _in5, 0, 4); + _COPY(_primIn, 108, _in6Len, 0, 4); + _praIn[0].buf.pv = (void*) _in6[0]; + _praIn[0].buf.nLen = (4 * _in6Len[0]); + _ppraInStart[0] += (_praIn - _praInStart) + 1; + _ppraROutStart[0] += (_praROut - _praROutStart) +0; + return _nErr; +} +static __inline void _count(int _numIn[1], int _numROut[1], int _numInH[1], int _numROutH[1], _ATTRIBUTE_UNUSED uint32_t _rout0[1], _ATTRIBUTE_UNUSED uint32_t _rout1[4], _ATTRIBUTE_UNUSED uint32_t _rout2[4], _ATTRIBUTE_UNUSED uint32_t _rout3[1], _ATTRIBUTE_UNUSED uint32_t _rout4[16], _ATTRIBUTE_UNUSED uint32_t _rout5[1], _ATTRIBUTE_UNUSED char* _rout6[1], _ATTRIBUTE_UNUSED uint32_t _rout6Len[1]) { + _numIn[0] += 0; + _numROut[0] += 1; + _numInH[0] += 0; + _numROutH[0] += 0; +} +static __inline void _count_1(int _numIn[1], int _numROut[1], int _numInH[1], int _numROutH[1], _ATTRIBUTE_UNUSED uint32_t _in0[1], _ATTRIBUTE_UNUSED uint32_t _in1[4], _ATTRIBUTE_UNUSED uint32_t _in2[4], _ATTRIBUTE_UNUSED uint32_t _in3[1], _ATTRIBUTE_UNUSED uint32_t _in4[16], _ATTRIBUTE_UNUSED uint32_t _in5[1], _ATTRIBUTE_UNUSED char* _in6[1], _ATTRIBUTE_UNUSED uint32_t _in6Len[1]) { + _numIn[0] += 1; + _numROut[0] += 0; + _numInH[0] += 0; + _numROutH[0] += 0; +} +static __inline int _stub_method_1(remote_handle64 _handle, uint32_t _mid, uintptr_t _in0[SLIM_IFPTR32(29, 16)], uintptr_t _in1[SLIM_IFPTR32(29, 16)], uintptr_t _rout2[SLIM_IFPTR32(29, 16)]) { + remote_arg* _pra = 0; + int _numIn[1] = {0}; + int _numROut[1] = {0}; + int _numInH[1] = {0}; + int _numROutH[1] = {0}; + _allocator _al[1] = {{0}}; + uint32_t _primIn[57]= {0}; + uint32_t _primROut[27]= {0}; + remote_arg* _praIn = 0; + remote_arg* _praROut = 0; + remote_arg* _praROutPost = 0; + remote_arg** _ppraROutPost = &_praROutPost; + remote_arg** _ppraIn = &_praIn; + remote_arg** _ppraROut = &_praROut; + remote_arg* _praHIn = 0; + remote_arg** _ppraHIn = &_praHIn; + remote_arg* _praHROut = 0; + remote_arg** _ppraHROut = &_praHROut; + int _nErr = 0; + _numIn[0] = 0; + _numROut[0] = 0; + _numInH[0] = 0; + _numROutH[0] = 0; + _count_1(_numIn, _numROut, _numInH, _numROutH, (uint32_t*)&(((uint32_t*)_in0)[0]), (uint32_t*)&(((uint32_t*)_in0)[1]), (uint32_t*)&(((uint32_t*)_in0)[5]), (uint32_t*)&(((uint32_t*)_in0)[9]), (uint32_t*)&(((uint32_t*)_in0)[10]), (uint32_t*)&(((uint32_t*)_in0)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in0)[27]), (char**)&(((uint64_t*)_in0)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in0)[28]), (uint32_t*)&(((uint32_t*)_in0)[30]))); + _count_1(_numIn, _numROut, _numInH, _numROutH, (uint32_t*)&(((uint32_t*)_in1)[0]), (uint32_t*)&(((uint32_t*)_in1)[1]), (uint32_t*)&(((uint32_t*)_in1)[5]), (uint32_t*)&(((uint32_t*)_in1)[9]), (uint32_t*)&(((uint32_t*)_in1)[10]), (uint32_t*)&(((uint32_t*)_in1)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in1)[27]), (char**)&(((uint64_t*)_in1)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in1)[28]), (uint32_t*)&(((uint32_t*)_in1)[30]))); + _count(_numIn, _numROut, _numInH, _numROutH, (uint32_t*)&(((uint32_t*)_rout2)[0]), (uint32_t*)&(((uint32_t*)_rout2)[1]), (uint32_t*)&(((uint32_t*)_rout2)[5]), (uint32_t*)&(((uint32_t*)_rout2)[9]), (uint32_t*)&(((uint32_t*)_rout2)[10]), (uint32_t*)&(((uint32_t*)_rout2)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_rout2)[27]), (char**)&(((uint64_t*)_rout2)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_rout2)[28]), (uint32_t*)&(((uint32_t*)_rout2)[30]))); + if(_numIn[0]>=255){ + return AEE_EUNSUPPORTED; + } + if(_numROut[0]>=255){ + return AEE_EUNSUPPORTED; + } + _allocator_init(_al, 0, 0); + _QAIC_ALLOCATE(_nErr, _al, ((((((((_numIn[0] + _numROut[0]) + _numInH[0]) + _numROutH[0]) + 1) + 1) + 0) + 0) * sizeof(_pra[0])), 4, _pra); + _QAIC_ASSERT(_nErr, _pra); + _pra[0].buf.pv = (void*)_primIn; + _pra[0].buf.nLen = sizeof(_primIn); + _pra[(_numIn[0] + 1)].buf.pv = (void*)_primROut; + _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut); + _praIn = (_pra + 1); + _praROut = (_praIn + _numIn[0] + 1); + _praROutPost = _praROut; + if(_praHIn == 0) + { + _praHIn = ((_praROut + _numROut[0]) + 1); + } + if(_praHROut == 0) + (_praHROut = _praHIn + _numInH[0] + 0); + _TRY(_nErr, _stub_pack_1(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 0), 0, (uint32_t*)&(((uint32_t*)_in0)[0]), (uint32_t*)&(((uint32_t*)_in0)[1]), (uint32_t*)&(((uint32_t*)_in0)[5]), (uint32_t*)&(((uint32_t*)_in0)[9]), (uint32_t*)&(((uint32_t*)_in0)[10]), (uint32_t*)&(((uint32_t*)_in0)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in0)[27]), (char**)&(((uint64_t*)_in0)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in0)[28]), (uint32_t*)&(((uint32_t*)_in0)[30])))); + _TRY(_nErr, _stub_pack_1(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 112), 0, (uint32_t*)&(((uint32_t*)_in1)[0]), (uint32_t*)&(((uint32_t*)_in1)[1]), (uint32_t*)&(((uint32_t*)_in1)[5]), (uint32_t*)&(((uint32_t*)_in1)[9]), (uint32_t*)&(((uint32_t*)_in1)[10]), (uint32_t*)&(((uint32_t*)_in1)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_in1)[27]), (char**)&(((uint64_t*)_in1)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_in1)[28]), (uint32_t*)&(((uint32_t*)_in1)[30])))); + _TRY(_nErr, _stub_pack(_al, (_praIn + 0), _ppraIn, (_praROut + 0), _ppraROut, _praHIn, _ppraHIn, _praHROut, _ppraHROut, ((char*)_primIn + 224), ((char*)_primROut + 0), (uint32_t*)&(((uint32_t*)_rout2)[0]), (uint32_t*)&(((uint32_t*)_rout2)[1]), (uint32_t*)&(((uint32_t*)_rout2)[5]), (uint32_t*)&(((uint32_t*)_rout2)[9]), (uint32_t*)&(((uint32_t*)_rout2)[10]), (uint32_t*)&(((uint32_t*)_rout2)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_rout2)[27]), (char**)&(((uint64_t*)_rout2)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_rout2)[28]), (uint32_t*)&(((uint32_t*)_rout2)[30])))); + _QAIC_ASSERT(_nErr, (_numInH[0] + 0) <= 15); + _QAIC_ASSERT(_nErr, (_numROutH[0] + 0) <= 15); + _TRY_FARF(_nErr, __QAIC_REMOTE(remote_handle64_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, (_numIn[0] + 1), (_numROut[0] + 1), (_numInH[0] + 0), (_numROutH[0] + 0)), _pra)); + _TRY(_nErr, _stub_unpack((_praROutPost + 0), _ppraROutPost, ((char*)_primROut + 0), (uint32_t*)&(((uint32_t*)_rout2)[0]), (uint32_t*)&(((uint32_t*)_rout2)[1]), (uint32_t*)&(((uint32_t*)_rout2)[5]), (uint32_t*)&(((uint32_t*)_rout2)[9]), (uint32_t*)&(((uint32_t*)_rout2)[10]), (uint32_t*)&(((uint32_t*)_rout2)[26]), SLIM_IFPTR32((char**)&(((uint32_t*)_rout2)[27]), (char**)&(((uint64_t*)_rout2)[14])), SLIM_IFPTR32((uint32_t*)&(((uint32_t*)_rout2)[28]), (uint32_t*)&(((uint32_t*)_rout2)[30])))); + _QAIC_CATCH(_nErr) {} + _CATCH_FARF(_nErr) { + _QAIC_FARF(RUNTIME_ERROR, "ERROR 0x%x: handle=0x%"PRIx64", scalar=0x%x, method ID=%d: %s failed\n", _nErr , _handle, REMOTE_SCALARS_MAKEX(0, _mid, (_numIn[0] + 1), (_numROut[0] + 1), (_numInH[0] + 0), (_numROutH[0] + 0)), _mid, __func__); + } + _allocator_deinit(_al); + return _nErr; +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_add)(remote_handle64 _handle, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 3; + return _stub_method_1(_handle, _mid, (uintptr_t*)src0, (uintptr_t*)src1, (uintptr_t*)dst); +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_mulmat)(remote_handle64 _handle, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 4; + return _stub_method_1(_handle, _mid, (uintptr_t*)src0, (uintptr_t*)src1, (uintptr_t*)dst); +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_softmax)(remote_handle64 _handle, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 5; + return _stub_method_1(_handle, _mid, (uintptr_t*)src0, (uintptr_t*)src1, (uintptr_t*)dst); +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_rmsnorm)(remote_handle64 _handle, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 6; + return _stub_method_1(_handle, _mid, (uintptr_t*)src0, (uintptr_t*)src1, (uintptr_t*)dst); +} +__QAIC_STUB_EXPORT int __QAIC_STUB(ggmlop_dsp_pool2d)(remote_handle64 _handle, const dsptensor* src0, const dsptensor* src1, dsptensor* dst) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 7; + return _stub_method_1(_handle, _mid, (uintptr_t*)src0, (uintptr_t*)src1, (uintptr_t*)dst); +} diff --git a/ggml/src/ggml-impl.h b/ggml/src/ggml-impl.h index a19cfb14e0f9f..89b59d9aadc7e 100644 --- a/ggml/src/ggml-impl.h +++ b/ggml/src/ggml-impl.h @@ -386,7 +386,7 @@ GGML_API void ggml_aligned_free(void * ptr, size_t size); return r; } -#elif defined(__riscv) && defined(GGML_RV_ZFH) +#elif defined(__riscv) && defined(__riscv_zfhmin) static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) { float f; diff --git a/ggml/src/ggml-metal/ggml-metal.m b/ggml/src/ggml-metal/ggml-metal.m index 85dbbcd5d7f99..f78e7eee553b6 100644 --- a/ggml/src/ggml-metal/ggml-metal.m +++ b/ggml/src/ggml-metal/ggml-metal.m @@ -149,6 +149,8 @@ static void ggml_backend_metal_device_rel(struct ggml_backend_metal_device_conte GGML_METAL_KERNEL_TYPE_SIGMOID, GGML_METAL_KERNEL_TYPE_GELU, GGML_METAL_KERNEL_TYPE_GELU_4, + GGML_METAL_KERNEL_TYPE_GELU_ERF, + GGML_METAL_KERNEL_TYPE_GELU_ERF_4, GGML_METAL_KERNEL_TYPE_GELU_QUICK, GGML_METAL_KERNEL_TYPE_GELU_QUICK_4, GGML_METAL_KERNEL_TYPE_SILU, @@ -1103,6 +1105,8 @@ @implementation GGMLMetalClass GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_SIGMOID, sigmoid, true); GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU, gelu, true); GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU_4, gelu_4, true); + GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU_ERF, gelu_erf, true); + GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU_ERF_4, gelu_erf_4, true); GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU_QUICK, gelu_quick, true); GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_GELU_QUICK_4, gelu_quick_4, true); GGML_METAL_ADD_KERNEL(GGML_METAL_KERNEL_TYPE_SILU, silu, true); @@ -1613,6 +1617,7 @@ static bool ggml_metal_supports_op(const struct ggml_backend_metal_device_contex case GGML_UNARY_OP_RELU: case GGML_UNARY_OP_SIGMOID: case GGML_UNARY_OP_GELU: + case GGML_UNARY_OP_GELU_ERF: case GGML_UNARY_OP_GELU_QUICK: case GGML_UNARY_OP_SILU: case GGML_UNARY_OP_ELU: @@ -2251,6 +2256,25 @@ static bool ggml_metal_encode_node( [encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)]; } break; + case GGML_UNARY_OP_GELU_ERF: + { + int64_t n = ggml_nelements(dst); + + id pipeline = nil; + + if (n % 4 == 0) { + pipeline = ctx->kernels[GGML_METAL_KERNEL_TYPE_GELU_ERF_4].pipeline; + n /= 4; + } else { + pipeline = ctx->kernels[GGML_METAL_KERNEL_TYPE_GELU_ERF].pipeline; + } + + [encoder setComputePipelineState:pipeline]; + [encoder setBuffer:id_src0 offset:offs_src0 atIndex:0]; + [encoder setBuffer:id_dst offset:offs_dst atIndex:1]; + + [encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)]; + } break; case GGML_UNARY_OP_GELU_QUICK: { int64_t n = ggml_nelements(dst); diff --git a/ggml/src/ggml-metal/ggml-metal.metal b/ggml/src/ggml-metal/ggml-metal.metal index e94b6cd756441..59899550ed38c 100644 --- a/ggml/src/ggml-metal/ggml-metal.metal +++ b/ggml/src/ggml-metal/ggml-metal.metal @@ -856,6 +856,7 @@ kernel void kernel_tanh( constant float GELU_COEF_A = 0.044715f; constant float GELU_QUICK_COEF = -1.702f; constant float SQRT_2_OVER_PI = 0.79788456080286535587989211986876f; +constant float SQRT_2_INV = 0.70710678118654752440084436210484f; kernel void kernel_gelu( device const float * src0, @@ -897,6 +898,42 @@ kernel void kernel_gelu_quick_4( dst[tpig] = x*(1.0f/(1.0f+exp(GELU_QUICK_COEF*x))); } +// based on Abramowitz and Stegun formula 7.1.26 or similar Hastings' approximation +// ref: https://www.johndcook.com/blog/python_erf/ +constant float p_erf = 0.3275911f; +constant float a1_erf = 0.254829592f; +constant float a2_erf = -0.284496736f; +constant float a3_erf = 1.421413741f; +constant float a4_erf = -1.453152027f; +constant float a5_erf = 1.061405429f; + +template +T erf_approx(T x) { + T sign_x = sign(x); + x = fabs(x); + T t = 1.0f / (1.0f + p_erf * x); + T y = 1.0f - (((((a5_erf * t + a4_erf) * t) + a3_erf) * t + a2_erf) * t + a1_erf) * t * exp(-x * x); + return sign_x * y; +} + +kernel void kernel_gelu_erf( + device const float * src0, + device float * dst, + uint tpig[[thread_position_in_grid]]) { + device const float & x = src0[tpig]; + + dst[tpig] = 0.5f*x*(1.0f+erf_approx(x*SQRT_2_INV)); +} + +kernel void kernel_gelu_erf_4( + device const float4 * src0, + device float4 * dst, + uint tpig[[thread_position_in_grid]]) { + device const float4 & x = src0[tpig]; + + dst[tpig] = 0.5f*x*(1.0f+erf_approx(x*SQRT_2_INV)); +} + kernel void kernel_silu( device const float * src0, device float * dst, @@ -3255,7 +3292,7 @@ template< typename kd4x4_t, // key type in device memory short nl_k, void (*deq_k)(device const kd4x4_t *, short, thread k4x4_t &), - typename vd4x4_t, // key type in device memory + typename vd4x4_t, // value type in device memory short nl_v, void (*deq_v)(device const vd4x4_t *, short, thread v4x4_t &), short DK, // K head size @@ -3776,7 +3813,7 @@ template< typename kd4_t, // key type in device memory short nl_k, void (*deq_k_t4)(device const kd4_t *, short, thread k4_t &), - typename vd4_t, // key type in device memory + typename vd4_t, // value type in device memory short nl_v, void (*deq_v_t4)(device const vd4_t *, short, thread v4_t &), short DK, // K head size diff --git a/ggml/src/ggml-musa/CMakeLists.txt b/ggml/src/ggml-musa/CMakeLists.txt index 92f05d5558c80..971314debc714 100644 --- a/ggml/src/ggml-musa/CMakeLists.txt +++ b/ggml/src/ggml-musa/CMakeLists.txt @@ -27,12 +27,15 @@ if (MUSAToolkit_FOUND) file(GLOB GGML_HEADERS_MUSA "../ggml-cuda/*.cuh") list(APPEND GGML_HEADERS_MUSA "../../include/ggml-cuda.h") + list(APPEND GGML_HEADERS_MUSA "../ggml-musa/mudnn.cuh") file(GLOB GGML_SOURCES_MUSA "../ggml-cuda/*.cu") file(GLOB SRCS "../ggml-cuda/template-instances/fattn-mma*.cu") list(APPEND GGML_SOURCES_MUSA ${SRCS}) file(GLOB SRCS "../ggml-cuda/template-instances/mmq*.cu") list(APPEND GGML_SOURCES_MUSA ${SRCS}) + file(GLOB SRCS "../ggml-musa/*.cu") + list(APPEND GGML_SOURCES_MUSA ${SRCS}) if (GGML_CUDA_FA_ALL_QUANTS) file(GLOB SRCS "../ggml-cuda/template-instances/fattn-vec*.cu") @@ -62,7 +65,9 @@ if (MUSAToolkit_FOUND) ) # TODO: do not use CUDA definitions for MUSA - target_compile_definitions(ggml PUBLIC GGML_USE_CUDA) + if (NOT GGML_BACKEND_DL) + target_compile_definitions(ggml PUBLIC GGML_USE_CUDA) + endif() add_compile_definitions(GGML_USE_MUSA) add_compile_definitions(GGML_CUDA_PEER_MAX_BATCH_SIZE=${GGML_CUDA_PEER_MAX_BATCH_SIZE}) @@ -92,9 +97,10 @@ if (MUSAToolkit_FOUND) endif() if (GGML_STATIC) + # TODO: mudnn has not provided static libraries yet target_link_libraries(ggml-musa PRIVATE MUSA::musart_static MUSA::mublas_static) else() - target_link_libraries(ggml-musa PRIVATE MUSA::musart MUSA::mublas) + target_link_libraries(ggml-musa PRIVATE MUSA::musart MUSA::mublas mudnn) endif() if (GGML_CUDA_NO_VMM) diff --git a/ggml/src/ggml-musa/mudnn.cu b/ggml/src/ggml-musa/mudnn.cu new file mode 100644 index 0000000000000..020c1702c45c0 --- /dev/null +++ b/ggml/src/ggml-musa/mudnn.cu @@ -0,0 +1,112 @@ +#include +#include + +#include "mudnn.cuh" + +namespace mudnn = musa::dnn; + +// Returns a human-readable error string for mudnn::Status +const char* mudnnGetErrorString(mudnn::Status err) { + switch (err) { + case mudnn::Status::SUCCESS: + return "Success"; + case mudnn::Status::INVALID_PARAMETER: + return "Invalid parameter"; + case mudnn::Status::NOT_INITIALIZED: + return "Not initialized"; + case mudnn::Status::ALLOC_FAILED: + return "Allocation failed"; + case mudnn::Status::NOT_SUPPORTED: + return "Not supported"; + case mudnn::Status::INTERNAL_ERROR: + return "Internal error"; + case mudnn::Status::ARCH_MISMATCH: + return "Architecture mismatch"; + case mudnn::Status::EXECUTION_FAILED: + return "Execution failed"; + default: + return "Unknown mudnn status"; + } +} + +// Error checking macro for MUDNN calls +#define MUDNN_CHECK(err) CUDA_CHECK_GEN(err, mudnn::Status::SUCCESS, mudnnGetErrorString) + +namespace { + // Thread-safe cache for mudnn::Handle objects per device + std::unordered_map> handle_cache; + std::mutex handle_cache_mutex; + + mudnn::Handle* get_cached_handle(int device_id) { + std::lock_guard lock(handle_cache_mutex); + auto it = handle_cache.find(device_id); + if (it != handle_cache.end()) { + return it->second.get(); + } + auto handle = std::make_unique(device_id); + mudnn::Handle* handle_ptr = handle.get(); + handle_cache[device_id] = std::move(handle); + return handle_ptr; + } +} + +// Extracts dimensions and strides from a ggml_tensor +int get_ggml_dims_and_strides(const ggml_tensor* tensor, + std::vector& dims, + std::vector& strides) { + const int ndims = ggml_n_dims(tensor); + const size_t element_size = ggml_element_size(tensor); + + dims.resize(ndims); + strides.resize(ndims); + + for (int i = 0; i < ndims; ++i) { + dims[i] = tensor->ne[i]; + strides[i] = tensor->nb[i] / static_cast(element_size); + } + return ndims; +} + +// Converts ggml_type to mudnn::Tensor::Type +mudnn::Tensor::Type ggml_type_to_mudnn_type(ggml_type type) { + switch (type) { + case GGML_TYPE_F32: + return mudnn::Tensor::Type::FLOAT; + case GGML_TYPE_F16: + return mudnn::Tensor::Type::HALF; + + // TODO: Add support for other types + + default: + MUDNN_CHECK(mudnn::Status::NOT_SUPPORTED); + } + + return mudnn::Tensor::Type::FLOAT; // Default fallback +} + +// Asynchronous memory copy using mudnn::Unary::IDENTITY +musaError_t mudnnMemcpyAsync(ggml_backend_cuda_context& ctx, const ggml_tensor* dst, const ggml_tensor* src) { + mudnn::Tensor tensor_dst, tensor_src; + + MUDNN_CHECK(tensor_dst.SetType(ggml_type_to_mudnn_type(dst->type))); + MUDNN_CHECK(tensor_src.SetType(ggml_type_to_mudnn_type(src->type))); + + std::vector dims, strides; + const int ndims = get_ggml_dims_and_strides(src, dims, strides); + + MUDNN_CHECK(tensor_dst.SetNdInfo(ndims, dims.data(), strides.data())); + MUDNN_CHECK(tensor_src.SetNdInfo(ndims, dims.data(), strides.data())); + MUDNN_CHECK(tensor_dst.SetAddr(dst->data)); + MUDNN_CHECK(tensor_src.SetAddr(src->data)); + + mudnn::Unary op; + MUDNN_CHECK(op.SetMode(mudnn::Unary::Mode::IDENTITY)); + MUDNN_CHECK(op.SetAlpha(0.0f)); + MUDNN_CHECK(op.SetBeta(0.0f)); + + mudnn::Handle* handle = get_cached_handle(ctx.device); + MUDNN_CHECK(handle->SetStream(ctx.stream())); + MUDNN_CHECK(op.Run(*handle, tensor_dst, tensor_src)); + + return musaSuccess; +} diff --git a/ggml/src/ggml-musa/mudnn.cuh b/ggml/src/ggml-musa/mudnn.cuh new file mode 100644 index 0000000000000..a63be5755c79c --- /dev/null +++ b/ggml/src/ggml-musa/mudnn.cuh @@ -0,0 +1,12 @@ +#pragma once + +#include "../include/ggml.h" +#include "../ggml-cuda/common.cuh" + +// Asynchronously copies data from src tensor to dst tensor using the provided context. +// Returns a musaError_t indicating success or failure. +musaError_t mudnnMemcpyAsync( + ggml_backend_cuda_context &ctx, + const ggml_tensor *dst, + const ggml_tensor *src +); diff --git a/ggml/src/ggml-opencl/CMakeLists.txt b/ggml/src/ggml-opencl/CMakeLists.txt index 352deb321ec5c..9f930c70b7bb4 100644 --- a/ggml/src/ggml-opencl/CMakeLists.txt +++ b/ggml/src/ggml-opencl/CMakeLists.txt @@ -55,14 +55,17 @@ endfunction() set(GGML_OPENCL_KERNELS add + argsort clamp cpy cvt diag_mask_inf + div gelu gemv_noshuffle_general gemv_noshuffle get_rows + group_norm im2col_f32 im2col_f16 mul_mat_Ab_Bi_8x4 @@ -83,11 +86,14 @@ set(GGML_OPENCL_KERNELS rms_norm rope scale + sigmoid silu softmax_4_f32 softmax_4_f16 softmax_f32 softmax_f16 + sub + sum_rows transpose ) diff --git a/ggml/src/ggml-opencl/ggml-opencl.cpp b/ggml/src/ggml-opencl/ggml-opencl.cpp index 586946048380b..5dbe97ab2477d 100644 --- a/ggml/src/ggml-opencl/ggml-opencl.cpp +++ b/ggml/src/ggml-opencl/ggml-opencl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #undef MIN #undef MAX @@ -74,6 +75,7 @@ struct ggml_cl_version { cl_uint minor = 0; }; + struct ggml_cl_compiler_version { ADRENO_CL_COMPILER_TYPE type; int major = -1; @@ -91,6 +93,14 @@ struct ggml_cl_compiler_version { } }; +static size_t align_to(size_t value, size_t to_alignment) { + GGML_ASSERT(to_alignment && "Invalid alignment (must be non-zero)"); + GGML_ASSERT((to_alignment & (to_alignment - 1)) == 0 && "to_alignment must be power-of-two"); + + return ((value + to_alignment - 1) / to_alignment) * to_alignment; +} + + // Parses a version string of form "XX.YY ". On an error returns ggml_cl_version with all zeroes. static ggml_cl_version parse_cl_version(std::string_view str) { size_t major_str_begin = 0; @@ -221,13 +231,25 @@ static ggml_cl_compiler_version get_adreno_cl_compiler_version(const char *drive return { type, major, minor, patch }; } +struct ggml_backend_opencl_context; + // backend device context struct ggml_backend_opencl_device_context { cl_platform_id platform; std::string platform_name; - cl_device_id device; - std::string device_name; + cl_device_id device; + std::string device_name; + cl_device_type device_type; + std::string device_version; + + // Initialized by ggml_cl2_init(). + ggml_backend_opencl_context * backend_ctx = nullptr; + + // Initialized by ggml_backend_opencl_device_get_buffer_type() + ggml_backend_buffer_type buffer_type; + + cl_context context = nullptr; }; // backend context @@ -248,6 +270,8 @@ struct ggml_backend_opencl_context { int adreno_wave_size; + cl_bool non_uniform_workgroups; + cl_context context; cl_command_queue queue; @@ -275,27 +299,37 @@ struct ggml_backend_opencl_context { cl_program program_mul_mv_f16_f32; cl_program program_mul_mv_f32_f32; cl_program program_mul; + cl_program program_div; + cl_program program_sub; cl_program program_norm; cl_program program_relu; cl_program program_rms_norm; + cl_program program_group_norm; cl_program program_rope; cl_program program_scale; cl_program program_silu; + cl_program program_sigmoid; cl_program program_softmax_f32; cl_program program_softmax_f16; cl_program program_softmax_4_f32; cl_program program_softmax_4_f16; + cl_program program_argsort_f32_i32; + cl_program program_sum_rows_f32; cl_kernel kernel_add, kernel_add_row; cl_kernel kernel_mul, kernel_mul_row; + cl_kernel kernel_div, kernel_div_row; + cl_kernel kernel_sub, kernel_sub_row; cl_kernel kernel_scale; cl_kernel kernel_silu, kernel_silu_4; cl_kernel kernel_gelu, kernel_gelu_4; cl_kernel kernel_gelu_quick, kernel_gelu_quick_4; cl_kernel kernel_relu; + cl_kernel kernel_sigmoid_f32, kernel_sigmoid_f16; cl_kernel kernel_clamp; cl_kernel kernel_norm; cl_kernel kernel_rms_norm; + cl_kernel kernel_group_norm; cl_kernel kernel_diag_mask_inf, kernel_diag_mask_inf_8; cl_kernel kernel_soft_max, kernel_soft_max_4; cl_kernel kernel_soft_max_f16, kernel_soft_max_4_f16; @@ -315,6 +349,8 @@ struct ggml_backend_opencl_context { cl_kernel kernel_mul_mat_q4_0_f32_1d_8x_flat, kernel_mul_mat_q4_0_f32_1d_16x_flat; cl_kernel kernel_mul_mv_q6_K_f32; cl_kernel kernel_im2col_f32, kernel_im2col_f16; + cl_kernel kernel_argsort_f32_i32; + cl_kernel kernel_sum_rows_f32; #ifdef GGML_OPENCL_USE_ADRENO_KERNELS // Transpose kernels @@ -344,15 +380,8 @@ struct ggml_backend_opencl_context { #endif // GGML_OPENCL_USE_ADRENO_KERNELS }; -static ggml_backend_device g_ggml_backend_opencl_device; -static ggml_backend_opencl_device_context g_ggml_ctx_dev_main { - /*.platform =*/ nullptr, - /*.platform_nane =*/ "", - /*.device =*/ nullptr, - /*.device_name =*/ "", -}; - -static int ggml_backend_opencl_n_devices = 0; +// All registered devices with a default device in the front. +static std::vector g_ggml_backend_opencl_devices; // Profiling #ifdef GGML_OPENCL_PROFILING @@ -969,6 +998,105 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx, ggml_cl_ve GGML_LOG_CONT("."); } + // argsort + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "argsort.cl.h" + }; +#else + const std::string kernel_src = read_file("argsort.cl"); +#endif + backend_ctx->program_argsort_f32_i32 = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_argsort_f32_i32 = clCreateKernel(backend_ctx->program_argsort_f32_i32, "kernel_argsort_f32_i32", &err), err)); + GGML_LOG_CONT("."); + } + + // div + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "div.cl.h" + }; +#else + const std::string kernel_src = read_file("div.cl"); +#endif + backend_ctx->program_div = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_div = clCreateKernel(backend_ctx->program_div, "kernel_div", &err), err)); + CL_CHECK((backend_ctx->kernel_div_row = clCreateKernel(backend_ctx->program_div, "kernel_div_row", &err), err)); + GGML_LOG_CONT("."); + } + + // sub + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "sub.cl.h" + }; +#else + const std::string kernel_src = read_file("sub.cl"); +#endif + backend_ctx->program_sub = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_sub = clCreateKernel(backend_ctx->program_sub, "kernel_sub", &err), err)); + CL_CHECK((backend_ctx->kernel_sub_row = clCreateKernel(backend_ctx->program_sub, "kernel_sub_row", &err), err)); + GGML_LOG_CONT("."); + } + + // sum_rows + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "sum_rows.cl.h" + }; +#else + const std::string kernel_src = read_file("sum_rows.cl"); +#endif + backend_ctx->program_sum_rows_f32 = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_sum_rows_f32 = clCreateKernel(backend_ctx->program_sum_rows_f32, "kernel_sum_rows_f32", &err), err)); + GGML_LOG_CONT("."); + } + + // sigmoid + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "sigmoid.cl.h" + }; +#else + const std::string kernel_src = read_file("sigmoid.cl"); +#endif + backend_ctx->program_sigmoid = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_sigmoid_f32 = clCreateKernel(backend_ctx->program_sigmoid, "kernel_sigmoid_f32", &err), err)); + CL_CHECK((backend_ctx->kernel_sigmoid_f16 = clCreateKernel(backend_ctx->program_sigmoid, "kernel_sigmoid_f16", &err), err)); + GGML_LOG_CONT("."); + } + + // group_norm + { +#ifdef GGML_OPENCL_EMBED_KERNELS + const std::string kernel_src { + #include "group_norm.cl.h" + }; +#else + const std::string kernel_src = read_file("group_norm.cl"); +#endif + backend_ctx->program_group_norm = + build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts); + + CL_CHECK((backend_ctx->kernel_group_norm = clCreateKernel(backend_ctx->program_group_norm, "kernel_group_norm", &err), err)); + GGML_LOG_CONT("."); + } + // Adreno kernels #ifdef GGML_OPENCL_USE_ADRENO_KERNELS // transpose @@ -1107,25 +1235,19 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx, ggml_cl_ve GGML_LOG_CONT("\n"); } -static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { - static bool initialized = false; - static ggml_backend_opencl_context *backend_ctx = nullptr; - - if (initialized) { - return backend_ctx; - } +// XXX static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { +// XXX static bool initialized = false; +// XXX static ggml_backend_opencl_context *backend_ctx = nullptr; - ggml_backend_opencl_device_context *dev_ctx = (ggml_backend_opencl_device_context *)dev->context; - GGML_ASSERT(dev_ctx); - GGML_ASSERT(dev_ctx->platform == nullptr); - GGML_ASSERT(dev_ctx->device == nullptr); - GGML_ASSERT(backend_ctx == nullptr); +static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev); - initialized = true; - backend_ctx = new ggml_backend_opencl_context(); - backend_ctx->gpu_family = GPU_FAMILY::UNKNOWN; +namespace /* anonymous */ { +extern struct ggml_backend_device_i ggml_backend_opencl_device_i; +} - cl_int err; +// Look for available and suitable devices. +static std::vector ggml_opencl_probe_devices(ggml_backend_reg * reg) { + std::vector found_devices; #ifdef GGML_OPENCL_PROFILING GGML_LOG_INFO("ggml_opencl: OpenCL profiling enabled\n"); @@ -1158,11 +1280,12 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { struct cl_device devices[NDEV]; unsigned n_devices = 0; struct cl_device * default_device = NULL; + unsigned default_platform_number = 0; cl_platform_id platform_ids[NPLAT]; if (clGetPlatformIDs(NPLAT, platform_ids, &n_platforms) != CL_SUCCESS) { GGML_LOG_ERROR("ggml_opencl: plaform IDs not available.\n"); - return backend_ctx; + return found_devices; } for (unsigned i = 0; i < n_platforms; i++) { @@ -1197,19 +1320,22 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { } if (default_device == NULL && p->default_device != NULL) { - default_device = p->default_device; + default_device = p->default_device; + default_platform_number = i; } } if (n_devices == 0) { GGML_LOG_ERROR("ggml_opencl: could find any OpenCL devices.\n"); - return backend_ctx; + return found_devices; } - char * user_platform_string = getenv("GGML_OPENCL_PLATFORM"); - char * user_device_string = getenv("GGML_OPENCL_DEVICE"); - int user_platform_number = -1; - int user_device_number = -1; + char * user_platform_string = getenv("GGML_OPENCL_PLATFORM"); + char * user_device_string = getenv("GGML_OPENCL_DEVICE"); + int user_platform_number = -1; + int user_device_number = -1; + cl_device * candidate_devices = nullptr; + unsigned n_candidate_devices = 0; unsigned n; if (user_platform_string != NULL && sscanf(user_platform_string, " %u", &n) == 1 && n < n_platforms) { @@ -1224,12 +1350,11 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { GGML_LOG_ERROR("ggml_opencl: invalid device number %d\n", user_device_number); exit(1); } - default_device = &platform->devices[user_device_number]; + default_device = &platform->devices[user_device_number]; + candidate_devices = platform->devices; + n_candidate_devices = platform->n_devices; } else { - - struct cl_device * selected_devices = devices; - unsigned n_selected_devices = n_devices; - + // Choose a platform by matching a substring. if (user_platform_number == -1 && user_platform_string != NULL && user_platform_string[0] != 0) { for (unsigned i = 0; i < n_platforms; i++) { struct cl_platform * p = &platforms[i]; @@ -1244,20 +1369,20 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { exit(1); } } - if (user_platform_number != -1) { - struct cl_platform * p = &platforms[user_platform_number]; - selected_devices = p->devices; - n_selected_devices = p->n_devices; - default_device = p->default_device; - if (n_selected_devices == 0) { - GGML_LOG_ERROR("ggml_opencl: selected platform '%s' does not have any devices.\n", p->name); - exit(1); - } + + int platform_idx = user_platform_number != -1 ? user_platform_number : default_platform_number; + struct cl_platform * p = &platforms[platform_idx]; + candidate_devices = p->devices; + n_candidate_devices = p->n_devices; + default_device = p->default_device; + if (n_candidate_devices == 0) { + GGML_LOG_ERROR("ggml_opencl: selected platform '%s' does not have any devices.\n", p->name); + exit(1); } if (user_device_number == -1 && user_device_string != NULL && user_device_string[0] != 0) { - for (unsigned i = 0; i < n_selected_devices; i++) { - struct cl_device * d = &selected_devices[i]; + for (unsigned i = 0; i < n_candidate_devices; i++) { + struct cl_device * d = &candidate_devices[i]; if (strstr(d->name, user_device_string) != NULL) { user_device_number = d->number; break; @@ -1269,71 +1394,145 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { } } if (user_device_number != -1) { - selected_devices = &devices[user_device_number]; - n_selected_devices = 1; - default_device = &selected_devices[0]; + candidate_devices = &devices[user_device_number]; + n_candidate_devices = 1; + default_device = &candidate_devices[0]; } - GGML_ASSERT(n_selected_devices > 0); + GGML_ASSERT(n_candidate_devices > 0); if (default_device == NULL) { - default_device = &selected_devices[0]; + default_device = &candidate_devices[0]; + } + } + + GGML_ASSERT(n_candidate_devices != 0 && candidate_devices); + + // Put the default device in front. + for (unsigned i = 1; i < n_candidate_devices; i++) { + if (&candidate_devices[i] == default_device) { + std::swap(candidate_devices[0], candidate_devices[i]); + default_device = &candidate_devices[0]; + break; + } + } + + GGML_LOG_INFO("ggml_opencl: selected platform: '%s'\n", default_device->platform->name); + + std::vector device_ids; + for (auto dev = candidate_devices, dev_end = candidate_devices + n_candidate_devices; dev != dev_end; dev++) { + device_ids.push_back(dev->id); + } + + cl_int err; + cl_context shared_context; + cl_context_properties properties[] = { (intptr_t) CL_CONTEXT_PLATFORM, (intptr_t) default_device->platform->id, 0 }; + + CL_CHECK( + (shared_context = clCreateContext(properties, device_ids.size(), device_ids.data(), NULL, NULL, &err), err)); + + for (auto dev = candidate_devices, dev_end = candidate_devices + n_candidate_devices; dev != dev_end; dev++) { + GGML_LOG_INFO("\nggml_opencl: device: '%s (%s)'\n", dev->name, dev->version); + + auto dev_ctx = std::unique_ptr(new ggml_backend_opencl_device_context{ + /*.platform =*/dev->platform->id, + /*.platform_nane =*/dev->platform->name, + /*.device =*/dev->id, + /*.device_name =*/dev->name, + /*.device_type =*/dev->type, + /*.device_version =*/dev->version, + /*.backend_ctx =*/nullptr, + /*.buffer_type =*/{}, + /*.context =*/shared_context, + }); + + found_devices.push_back(ggml_backend_device{ + /* .iface = */ ggml_backend_opencl_device_i, + /* .reg = */ reg, + /* .context = */ dev_ctx.get(), + }); + + if (!ggml_cl2_init(&found_devices.back())) { + found_devices.pop_back(); + GGML_LOG_INFO("ggml_opencl: drop unsupported device.\n"); + continue; + } + + dev_ctx.release(); + } + + if (found_devices.size()) { + auto * dev_ctx = static_cast(found_devices.front().context); + GGML_LOG_INFO("ggml_opencl: default device: '%s (%s)'\n", dev_ctx->device_name.c_str(), + dev_ctx->device_version.c_str()); + + if (dev_ctx->device_type != CL_DEVICE_TYPE_GPU) { + GGML_LOG_WARN("ggml_opencl: warning, the default device is not a GPU: '%s'.\n", + dev_ctx->device_name.c_str()); } } - GGML_LOG_INFO("ggml_opencl: selecting platform: '%s'\n", default_device->platform->name); - GGML_LOG_INFO("ggml_opencl: selecting device: '%s (%s)'\n", default_device->name, default_device->version); - if (default_device->type != CL_DEVICE_TYPE_GPU) { - GGML_LOG_WARN("ggml_opencl: warning, not a GPU: '%s'.\n", default_device->name); + return found_devices; +} + +// Initialize device if it is supported (returns nullptr if it is not). +static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { + GGML_ASSERT(dev); + GGML_ASSERT(dev->context); + + ggml_backend_opencl_device_context * dev_ctx = (ggml_backend_opencl_device_context *) dev->context; + GGML_ASSERT(dev_ctx->platform); + GGML_ASSERT(dev_ctx->device); + + if (dev_ctx->backend_ctx) { + return dev_ctx->backend_ctx; } - dev_ctx->platform = default_device->platform->id; - dev_ctx->device = default_device->id; - backend_ctx->device = default_device->id; + auto backend_ctx = std::make_unique(); + backend_ctx->device = dev_ctx->device; + backend_ctx->gpu_family = GPU_FAMILY::UNKNOWN; - if (strstr(default_device->name, "Adreno") || - strstr(default_device->name, "Qualcomm") || - strstr(default_device->version, "Adreno")) { + if (strstr(dev_ctx->device_name.c_str(), "Adreno") || + strstr(dev_ctx->device_name.c_str(), "Qualcomm") || + strstr(dev_ctx->device_version.c_str(), "Adreno")) { backend_ctx->gpu_family = GPU_FAMILY::ADRENO; // Usually device version contains the detailed device name - backend_ctx->adreno_gen = get_adreno_gpu_gen(default_device->version); + backend_ctx->adreno_gen = get_adreno_gpu_gen(dev_ctx->device_version.c_str()); if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::ADRENO_UNKNOWN) { - backend_ctx->adreno_gen = get_adreno_gpu_gen(default_device->name); + backend_ctx->adreno_gen = get_adreno_gpu_gen(dev_ctx->device_name.c_str()); } // Use wave size of 64 for all Adreno GPUs. backend_ctx->adreno_wave_size = 64; - } else if (strstr(default_device->name, "Intel")) { + } else if (strstr(dev_ctx->device_name.c_str(), "Intel")) { backend_ctx->gpu_family = GPU_FAMILY::INTEL; } else { - GGML_LOG_ERROR("Unsupported GPU: %s\n", default_device->name); + GGML_LOG_ERROR("Unsupported GPU: %s\n", dev_ctx->device_name.c_str()); backend_ctx->gpu_family = GPU_FAMILY::UNKNOWN; - return backend_ctx; + return nullptr; } #ifdef GGML_OPENCL_USE_ADRENO_KERNELS if (backend_ctx->gpu_family != GPU_FAMILY::ADRENO) { GGML_LOG_ERROR("ggml_opencl: Adreno-specific kernels should not be enabled for non-Adreno GPUs; " "run on an Adreno GPU or recompile with CMake option `-DGGML_OPENCL_USE_ADRENO_KERNELS=OFF`\n"); - return backend_ctx; + return nullptr; } #endif // Populate backend device name - dev_ctx->platform_name = default_device->platform->name; - dev_ctx->device_name = default_device->name; - backend_ctx->device_name = default_device->name; + backend_ctx->device_name = dev_ctx->device_name; // A local ref of cl_device_id for convenience cl_device_id device = backend_ctx->device; - ggml_cl_version platform_version = get_opencl_platform_version(default_device->platform->id); + ggml_cl_version platform_version = get_opencl_platform_version(dev_ctx->platform); // Check device OpenCL version, OpenCL 2.0 or above is required ggml_cl_version opencl_c_version = get_opencl_c_version(platform_version, device); if (opencl_c_version.major < 2) { GGML_LOG_ERROR("ggml_opencl: OpenCL 2.0 or above is required\n"); - return backend_ctx; + return nullptr; } // Check driver version @@ -1364,7 +1563,7 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { // fp16 is required if (!backend_ctx->fp16_support) { GGML_LOG_ERROR("ggml_opencl: device does not support FP16\n"); - return backend_ctx; + return nullptr; } // If OpenCL 3.0 is supported, then check for cl_khr_subgroups, which becomes @@ -1373,7 +1572,7 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { strstr(ext_buffer, "cl_intel_subgroups") == NULL) { GGML_LOG_ERROR("ggml_opencl: device does not support subgroups (cl_khr_subgroups or cl_intel_subgroups) " "(note that subgroups is an optional feature in OpenCL 3.0)\n"); - return backend_ctx; + return nullptr; } cl_uint base_align_in_bits; @@ -1397,6 +1596,15 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { GGML_LOG_INFO("ggml_opencl: SVM atomics support: %s\n", svm_caps & CL_DEVICE_SVM_ATOMICS ? "true" : "false"); + if (opencl_c_version.major >= 3) { + CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, sizeof(cl_bool), + &backend_ctx->non_uniform_workgroups, 0)); + } else { + GGML_ASSERT(opencl_c_version.major == 2); + // Non-uniform workgroup sizes is mandatory feature in v2.x. + backend_ctx->non_uniform_workgroups = true; + } + // Print out configurations #ifdef GGML_OPENCL_SOA_Q GGML_LOG_INFO("ggml_opencl: flattening quantized weights representation as struct of arrays (GGML_OPENCL_SOA_Q)\n"); @@ -1406,14 +1614,10 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { GGML_LOG_INFO("ggml_opencl: using kernels optimized for Adreno (GGML_OPENCL_USE_ADRENO_KERNELS)\n"); #endif // GGML_OPENCL_USE_ADRENO_KERNELS - cl_context_properties properties[] = { - (intptr_t)CL_CONTEXT_PLATFORM, (intptr_t)dev_ctx->platform, 0 - }; - - CL_CHECK((backend_ctx->context = clCreateContext(properties, 1, &device, NULL, NULL, &err), err)); + cl_int err; // A local ref of cl_context for convenience - cl_context context = backend_ctx->context; + cl_context context = backend_ctx->context = dev_ctx->context; //CL_CHECK((queue = clCreateCommandQueue(context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err), // (err != CL_INVALID_QUEUE_PROPERTIES && err != CL_INVALID_VALUE ? err : @@ -1426,7 +1630,7 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { CL_CHECK((backend_ctx->queue = clCreateCommandQueue(context, device, command_queue_props, &err), err)); // Load kernels - load_cl_kernels(backend_ctx, opencl_c_version); + load_cl_kernels(backend_ctx.get(), opencl_c_version); #ifdef GGML_OPENCL_USE_ADRENO_KERNELS // Allocate intermediate buffers and images @@ -1456,10 +1660,8 @@ static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) { CL_CHECK((backend_ctx->B_d_max = clCreateBuffer(context, 0, max_B_d_bytes, NULL, &err), err)); #endif // GGML_OPENCL_USE_ADRENO_KERNELS - // For now we support a single devices - ggml_backend_opencl_n_devices = 1; - - return backend_ctx; + dev_ctx->backend_ctx = backend_ctx.release(); + return dev_ctx->backend_ctx; } static void ggml_cl2_free(void) { @@ -1664,10 +1866,46 @@ static void ggml_backend_opencl_synchronize(ggml_backend_t backend) { GGML_UNUSED(backend); } +// Syncronizes the 'backend_ctx's device with others so that commands +// enqueued to it won't start until commands in the other devices have +// completed. +static void sync_with_other_backends(ggml_backend_opencl_context * backend_ctx) { + if (g_ggml_backend_opencl_devices.size() < 2) + return; // No other devices to synchronize with. + + std::vector events; + events.reserve(g_ggml_backend_opencl_devices.size()); + + for (ggml_backend_device & backend_dev : g_ggml_backend_opencl_devices) { + auto * other_backend_ctx = ggml_cl2_init(&backend_dev); + if (backend_ctx != other_backend_ctx) { + cl_event ev; + CL_CHECK(clEnqueueMarkerWithWaitList(other_backend_ctx->queue, 0, nullptr, &ev)); + CL_CHECK(clFlush(other_backend_ctx->queue)); + events.push_back(ev); + } + } + + CL_CHECK(clEnqueueBarrierWithWaitList(backend_ctx->queue, events.size(), events.data(), nullptr)); + for (auto ev : events) { + CL_CHECK(clReleaseEvent(ev)); + } +} + +static void sync_with_other_backends(ggml_backend_t backend) { + auto * backend_ctx = static_cast(backend->context); + sync_with_other_backends(backend_ctx); +} + static ggml_status ggml_backend_opencl_graph_compute(ggml_backend_t backend, ggml_cgraph * cgraph) { for (int i = 0; i < cgraph->n_nodes; i++) { ggml_tensor * node = cgraph->nodes[i]; + // NOTE: this may oversynchronize by synchronizing with + // backends/devices which don't compute 'cgraph's + // dependencies. + sync_with_other_backends(backend); + if (node->op == GGML_OP_RESHAPE || node->op == GGML_OP_TRANSPOSE || node->op == GGML_OP_VIEW || node->op == GGML_OP_PERMUTE || node->op == GGML_OP_NONE) { continue; } @@ -1729,6 +1967,8 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te case GGML_OP_ADD: case GGML_OP_SCALE: case GGML_OP_MUL: + case GGML_OP_DIV: + case GGML_OP_SUB: return op->src[0]->type == GGML_TYPE_F32; case GGML_OP_UNARY: switch (ggml_get_unary_op(op)) { @@ -1736,7 +1976,9 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te case GGML_UNARY_OP_SILU: case GGML_UNARY_OP_RELU: case GGML_UNARY_OP_GELU_QUICK: - return ggml_is_contiguous(op->src[0]) && op->src[0]->type == GGML_TYPE_F32; + return ggml_is_contiguous(op->src[0]) && op->src[0]->type == GGML_TYPE_F32; + case GGML_UNARY_OP_SIGMOID: + return ggml_is_contiguous(op->src[0]); default: return false; } @@ -1746,11 +1988,13 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te case GGML_OP_NORM: case GGML_OP_RMS_NORM: return true; + case GGML_OP_GROUP_NORM: + return ggml_is_contiguous(op->src[0]); case GGML_OP_MUL_MAT: if (op->src[0]->type == GGML_TYPE_F16) { return true; } else if (op->src[0]->type == GGML_TYPE_F32) { - return op->src[1]->type == GGML_TYPE_F32 && ggml_is_contiguous(op->src[0]) && ggml_is_contiguous(op->src[1]); + return op->src[1]->type == GGML_TYPE_F32; } else if (op->src[0]->type == GGML_TYPE_Q4_0 || op->src[0]->type == GGML_TYPE_Q6_K) { return op->src[1]->type == GGML_TYPE_F32 && ggml_is_contiguous(op->src[0]) && ggml_is_contiguous(op->src[1]); @@ -1785,6 +2029,10 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te } case GGML_OP_IM2COL: return true; + case GGML_OP_ARGSORT: + return op->src[0]->type == GGML_TYPE_F32; + case GGML_OP_SUM_ROWS: + return op->src[0]->type == GGML_TYPE_F32 && ggml_is_contiguous(op->src[0]); default: return false; } @@ -2058,15 +2306,16 @@ static void ggml_backend_opencl_buffer_set_tensor(ggml_backend_buffer_t buffer, // The original tensor memory is divided into scales and quants, i.e., // we first store scales, then quants. // Create subbuffer for scales. - region.origin = extra_orig->offset + tensor->view_offs + offset; + region.origin = align_to(extra_orig->offset + tensor->view_offs + offset, backend_ctx->alignment); region.size = size_d; extra->d = clCreateSubBuffer( extra_orig->data_device, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err); CL_CHECK(err); + auto previous_origin = region.origin; // Create subbuffer for quants. - region.origin = extra_orig->offset + tensor->view_offs + offset + size_d; + region.origin = align_to(previous_origin + size_d, backend_ctx->alignment); region.size = size_q; extra->q = clCreateSubBuffer( extra_orig->data_device, CL_MEM_READ_WRITE, @@ -2271,8 +2520,8 @@ static void ggml_backend_opencl_buffer_get_tensor(ggml_backend_buffer_t buffer, cl_context context = backend_ctx->context; cl_command_queue queue = backend_ctx->queue; - // Make sure all previously submitted commands are finished. - CL_CHECK(clFinish(queue)); + // Make sure all previously submitted commands in other devices are finished. + sync_with_other_backends(backend_ctx); #ifdef GGML_OPENCL_SOA_Q // In end-to-end runs, get_tensor is usually used to get back the logits, @@ -2376,13 +2625,8 @@ static ggml_backend_buffer_t ggml_backend_opencl_buffer_type_alloc_buffer(ggml_b } static size_t ggml_backend_opencl_buffer_type_get_alignment(ggml_backend_buffer_type_t buffer_type) { - // FIXME: not thread safe, device may not be initialized yet - static cl_uint alignment = -1; - if (alignment == (cl_uint)-1) { - ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(buffer_type->device); - alignment = backend_ctx->alignment; - } - return alignment; + ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(buffer_type->device); + return backend_ctx->alignment; } static size_t ggml_backend_opencl_buffer_type_get_max_size(ggml_backend_buffer_type_t buffer_type) { @@ -2409,16 +2653,6 @@ static ggml_backend_buffer_type_i ggml_backend_opencl_buffer_type_interface = { /* .is_host = */ NULL, }; -ggml_backend_buffer_type_t ggml_backend_opencl_buffer_type() { - static ggml_backend_buffer_type buffer_type = { - /* .iface = */ ggml_backend_opencl_buffer_type_interface, - /* .device = */ &g_ggml_backend_opencl_device, - /* .context = */ nullptr, - }; - - return &buffer_type; -} - // // backend device // @@ -2476,9 +2710,15 @@ static ggml_backend_t ggml_backend_opencl_device_init(ggml_backend_dev_t dev, co } static ggml_backend_buffer_type_t ggml_backend_opencl_device_get_buffer_type(ggml_backend_dev_t dev) { - return ggml_backend_opencl_buffer_type(); + auto * dev_ctx = static_cast(dev->context); - GGML_UNUSED(dev); + dev_ctx->buffer_type = ggml_backend_buffer_type{ + /* .iface = */ ggml_backend_opencl_buffer_type_interface, + /* .device = */ dev, + /* .context = */ nullptr, + }; + + return &dev_ctx->buffer_type; } static ggml_backend_buffer_t ggml_backend_opencl_device_buffer_from_ptr(ggml_backend_dev_t dev, void * ptr, size_t size, size_t max_tensor_size) { @@ -2494,12 +2734,21 @@ static bool ggml_backend_opencl_device_supports_op(ggml_backend_dev_t dev, const } static bool ggml_backend_opencl_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) { - return buft->iface.get_name == ggml_backend_opencl_buffer_type_get_name; + // Check 'dev' and 'buffer_type' are not objects belonging to this backend. + if (dev->iface.get_name != ggml_backend_opencl_device_get_name || + buft->iface.get_name != ggml_backend_opencl_buffer_type_get_name) { + return false; + } - GGML_UNUSED(dev); + // Check cl_context is the same. clEnqueue* commands may not use + // buffers from another cl_context. + ggml_backend_opencl_context * backend_ctx0 = ggml_cl2_init(dev); + ggml_backend_opencl_context * backend_ctx1 = ggml_cl2_init(buft->device); + return backend_ctx0->context == backend_ctx1->context; } -static struct ggml_backend_device_i ggml_backend_opencl_device_i = { +namespace /* anonymous */ { +struct ggml_backend_device_i ggml_backend_opencl_device_i = { /* .get_name = */ ggml_backend_opencl_device_get_name, /* .get_description = */ ggml_backend_opencl_device_get_description, /* .get_memory = */ ggml_backend_opencl_device_get_memory, @@ -2516,6 +2765,7 @@ static struct ggml_backend_device_i ggml_backend_opencl_device_i = { /* .event_free = */ NULL, /* .event_synchronize = */ NULL, }; +} // Backend registry @@ -2526,15 +2776,15 @@ static const char * ggml_backend_opencl_reg_get_name(ggml_backend_reg_t reg) { } static size_t ggml_backend_opencl_reg_device_count(ggml_backend_reg_t reg) { - return ggml_backend_opencl_n_devices; + return g_ggml_backend_opencl_devices.size(); GGML_UNUSED(reg); } static ggml_backend_dev_t ggml_backend_opencl_reg_device_get(ggml_backend_reg_t reg, size_t index) { - GGML_ASSERT(index == 0); + GGML_ASSERT(index < ggml_backend_opencl_reg_device_count(reg)); - return &g_ggml_backend_opencl_device; + return &g_ggml_backend_opencl_devices[index]; GGML_UNUSED(reg); GGML_UNUSED(index); @@ -2548,27 +2798,23 @@ static struct ggml_backend_reg_i ggml_backend_opencl_reg_i = { }; ggml_backend_reg_t ggml_backend_opencl_reg(void) { - // TODO: make this thread-safe somehow? + static std::mutex mutex; static ggml_backend_reg reg; static bool initialized = false; + std::lock_guard lock(mutex); - if (!initialized) { - reg = ggml_backend_reg { - /* .api_version = */ GGML_BACKEND_API_VERSION, - /* .iface = */ ggml_backend_opencl_reg_i, - /* .context = */ NULL, - }; - - g_ggml_backend_opencl_device = ggml_backend_device { - /* .iface = */ ggml_backend_opencl_device_i, - /* .reg = */ ®, - /* .context = */ &g_ggml_ctx_dev_main, - }; + if (initialized) { + return ® + } + initialized = true; - ggml_cl2_init(&g_ggml_backend_opencl_device); + g_ggml_backend_opencl_devices = ggml_opencl_probe_devices(®); - initialized = true; - } + reg = ggml_backend_reg{ + /* .api_version = */ GGML_BACKEND_API_VERSION, + /* .iface = */ ggml_backend_opencl_reg_i, + /* .context = */ NULL, + }; return ® } @@ -2942,14 +3188,19 @@ static void ggml_cl_add(ggml_backend_t backend, const ggml_tensor * src0, const size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } else { unsigned int nth = MIN(64, ne0); @@ -3077,14 +3328,19 @@ static void ggml_cl_mul(ggml_backend_t backend, const ggml_tensor * src0, const size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } else { unsigned int nth = MIN(64, ne0); @@ -3103,54 +3359,304 @@ static void ggml_cl_mul(ggml_backend_t backend, const ggml_tensor * src0, const } } -static void ggml_cl_gelu(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { +static void ggml_cl_div(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { GGML_ASSERT(src0); GGML_ASSERT(src0->extra); + GGML_ASSERT(src1); + GGML_ASSERT(src1->extra); GGML_ASSERT(dst); GGML_ASSERT(dst->extra); - UNUSED(src1); + const int ne00 = src0->ne[0]; + const int ne01 = src0->ne[1]; + const int ne02 = src0->ne[2]; + const int ne03 = src0->ne[3]; + + const cl_ulong nb00 = src0->nb[0]; + const cl_ulong nb01 = src0->nb[1]; + const cl_ulong nb02 = src0->nb[2]; + const cl_ulong nb03 = src0->nb[3]; + + const int ne10 = src1->ne[0]; + const int ne11 = src1->ne[1]; + const int ne12 = src1->ne[2]; + const int ne13 = src1->ne[3]; + + const cl_ulong nb10 = src1->nb[0]; + const cl_ulong nb11 = src1->nb[1]; + const cl_ulong nb12 = src1->nb[2]; + const cl_ulong nb13 = src1->nb[3]; + + const int ne0 = dst->ne[0]; + + const cl_ulong nb0 = dst->nb[0]; + const cl_ulong nb1 = dst->nb[1]; + const cl_ulong nb2 = dst->nb[2]; + const cl_ulong nb3 = dst->nb[3]; ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; cl_command_queue queue = backend_ctx->queue; ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra; ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offset1 = extra1->offset + src1->view_offs; cl_ulong offsetd = extrad->offset + dst->view_offs; + bool bcast_row = false; cl_kernel kernel; - int n = ggml_nelements(dst); + if (ggml_nelements(src1) == ne10 && ggml_is_contiguous(src1) && ne00 % 4 == 0 && ne10 % 4 == 0) { + GGML_ASSERT(ggml_is_contiguous(src0)); - if (n % 4 == 0) { - kernel = backend_ctx->kernel_gelu_4; - n /= 4; + // src1 is a row + GGML_ASSERT(ne11 == 1); + + bcast_row = true; + int ne = ne00 / 4; + kernel = backend_ctx->kernel_div_row; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne)); } else { - kernel = backend_ctx->kernel_gelu; + kernel = backend_ctx->kernel_div; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(cl_ulong), &nb00)); + CL_CHECK(clSetKernelArg(kernel, 7, sizeof(cl_ulong), &nb01)); + CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb02)); + CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb03)); + CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne10)); + CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne11)); + CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne12)); + CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &ne13)); + CL_CHECK(clSetKernelArg(kernel, 14, sizeof(cl_ulong), &nb10)); + CL_CHECK(clSetKernelArg(kernel, 15, sizeof(cl_ulong), &nb11)); + CL_CHECK(clSetKernelArg(kernel, 16, sizeof(cl_ulong), &nb12)); + CL_CHECK(clSetKernelArg(kernel, 17, sizeof(cl_ulong), &nb13)); + CL_CHECK(clSetKernelArg(kernel, 18, sizeof(int), &ne0)); + CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb0)); + CL_CHECK(clSetKernelArg(kernel, 20, sizeof(cl_ulong), &nb1)); + CL_CHECK(clSetKernelArg(kernel, 21, sizeof(cl_ulong), &nb2)); + CL_CHECK(clSetKernelArg(kernel, 22, sizeof(cl_ulong), &nb3)); } - CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); - CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); - CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); - CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + if (bcast_row) { + int n = ggml_nelements(dst)/4; + size_t global_work_size[] = {(size_t)n, 1, 1}; + size_t local_work_size[] = {64, 1, 1}; - size_t global_work_size[] = {(size_t)n, 1, 1}; - size_t local_work_size[] = {64, 1, 1}; +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif + } else { + unsigned int nth = MIN(64, ne0); + size_t global_work_size[] = {ne01*nth, (size_t)ne02, (size_t)ne03}; + size_t local_work_size[] = {nth, 1, 1}; #ifdef GGML_OPENCL_PROFILING - cl_event evt; - clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt); + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); - g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); #else - clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); #endif + } } -static void ggml_cl_gelu_quick(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { +static void ggml_cl_sub(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(src1); + GGML_ASSERT(src1->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + + const int ne00 = src0->ne[0]; + const int ne01 = src0->ne[1]; + const int ne02 = src0->ne[2]; + const int ne03 = src0->ne[3]; + + const cl_ulong nb00 = src0->nb[0]; + const cl_ulong nb01 = src0->nb[1]; + const cl_ulong nb02 = src0->nb[2]; + const cl_ulong nb03 = src0->nb[3]; + + const int ne10 = src1->ne[0]; + const int ne11 = src1->ne[1]; + const int ne12 = src1->ne[2]; + const int ne13 = src1->ne[3]; + + const cl_ulong nb10 = src1->nb[0]; + const cl_ulong nb11 = src1->nb[1]; + const cl_ulong nb12 = src1->nb[2]; + const cl_ulong nb13 = src1->nb[3]; + + const int ne0 = dst->ne[0]; + + const cl_ulong nb0 = dst->nb[0]; + const cl_ulong nb1 = dst->nb[1]; + const cl_ulong nb2 = dst->nb[2]; + const cl_ulong nb3 = dst->nb[3]; + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offset1 = extra1->offset + src1->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + bool bcast_row = false; + cl_kernel kernel; + + if (ggml_nelements(src1) == ne10 && ggml_is_contiguous(src1) && ne00 % 4 == 0 && ne10 % 4 == 0) { + GGML_ASSERT(ggml_is_contiguous(src0)); + + // src1 is a row + GGML_ASSERT(ne11 == 1); + + bcast_row = true; + int ne = ne00 / 4; + kernel = backend_ctx->kernel_sub_row; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne)); + } else { + kernel = backend_ctx->kernel_sub; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(cl_ulong), &nb00)); + CL_CHECK(clSetKernelArg(kernel, 7, sizeof(cl_ulong), &nb01)); + CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb02)); + CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb03)); + CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne10)); + CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne11)); + CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne12)); + CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &ne13)); + CL_CHECK(clSetKernelArg(kernel, 14, sizeof(cl_ulong), &nb10)); + CL_CHECK(clSetKernelArg(kernel, 15, sizeof(cl_ulong), &nb11)); + CL_CHECK(clSetKernelArg(kernel, 16, sizeof(cl_ulong), &nb12)); + CL_CHECK(clSetKernelArg(kernel, 17, sizeof(cl_ulong), &nb13)); + CL_CHECK(clSetKernelArg(kernel, 18, sizeof(int), &ne0)); + CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb0)); + CL_CHECK(clSetKernelArg(kernel, 20, sizeof(cl_ulong), &nb1)); + CL_CHECK(clSetKernelArg(kernel, 21, sizeof(cl_ulong), &nb2)); + CL_CHECK(clSetKernelArg(kernel, 22, sizeof(cl_ulong), &nb3)); + } + + if (bcast_row) { + int n = ggml_nelements(dst)/4; + size_t global_work_size[] = {(size_t)n, 1, 1}; + size_t local_work_size[] = {64, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif + } else { + unsigned int nth = MIN(64, ne0); + size_t global_work_size[] = {ne01*nth, (size_t)ne02, (size_t)ne03}; + size_t local_work_size[] = {nth, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif + } +} + +static void ggml_cl_gelu(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + + UNUSED(src1); + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + cl_kernel kernel; + + int n = ggml_nelements(dst); + + if (n % 4 == 0) { + kernel = backend_ctx->kernel_gelu_4; + n /= 4; + } else { + kernel = backend_ctx->kernel_gelu; + } + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + + size_t global_work_size[] = {(size_t)n, 1, 1}; + size_t local_work_size[] = {64, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL); +#endif +} + +static void ggml_cl_gelu_quick(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { GGML_ASSERT(src0); GGML_ASSERT(src0->extra); GGML_ASSERT(dst); @@ -3233,14 +3739,19 @@ static void ggml_cl_silu(ggml_backend_t backend, const ggml_tensor * src0, const size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } @@ -3273,14 +3784,71 @@ static void ggml_cl_relu(ggml_backend_t backend, const ggml_tensor * src0, const size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); +#endif +} + +static void ggml_cl_sigmoid(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + + UNUSED(src1); + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + cl_kernel kernel; + if (src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32) { + kernel = backend_ctx->kernel_sigmoid_f32; + } else if (src0->type == GGML_TYPE_F16 && dst->type == GGML_TYPE_F16) { + kernel = backend_ctx->kernel_sigmoid_f16; + } else { + GGML_ASSERT(false && "Unsupported data types for sigmoid (input and output must be both f32 or f16)"); + } + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + + const int64_t n = ggml_nelements(dst); + + size_t global_work_size[] = {(size_t)n, 1, 1}; + size_t local_work_size[] = {64, 1, 1}; + + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } @@ -3320,14 +3888,19 @@ static void ggml_cl_clamp(ggml_backend_t backend, const ggml_tensor * src0, cons size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } @@ -3476,6 +4049,65 @@ static void ggml_cl_rms_norm(ggml_backend_t backend, const ggml_tensor * src0, c #endif } +static void ggml_cl_group_norm(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + + UNUSED(src1); + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + int32_t n_groups = ((const int32_t *) dst->op_params)[0]; + int32_t group_size = src0->ne[0] * src0->ne[1] * ((src0->ne[2] + n_groups - 1) / n_groups); + float eps = ((const float *) dst->op_params)[1]; + + const int ne00 = src0->ne[0]; + const int ne01 = src0->ne[1]; + const int ne02 = src0->ne[2]; + const int ne = ne00*ne01*ne02; + + cl_kernel kernel = backend_ctx->kernel_group_norm; + + size_t sgs = 64; + if (backend_ctx->gpu_family == ADRENO) { + sgs = 64; + } else if (backend_ctx->gpu_family == INTEL) { + sgs = 32; + } else { + GGML_ASSERT(false && "Unsupported GPU"); + } + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &group_size)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(float), &eps)); + + size_t global_work_size[] = {(size_t)n_groups*sgs, 1, 1}; + size_t local_work_size[] = {(size_t)sgs, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif +} + static void ggml_cl_mul_mat(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { GGML_ASSERT(src0); GGML_ASSERT(src0->extra); @@ -4230,14 +4862,19 @@ static void ggml_cl_scale(ggml_backend_t backend, const ggml_tensor * src0, cons size_t global_work_size[] = {(size_t)n, 1, 1}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (n % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } @@ -4418,14 +5055,19 @@ static void ggml_cl_diag_mask_inf(ggml_backend_t backend, const ggml_tensor * sr size_t global_work_size[] = {(size_t)ne00, (size_t)ne01, (size_t)ne02}; size_t local_work_size[] = {64, 1, 1}; + size_t * local_work_size_ptr = local_work_size; + if (ne00 % 64 != 0 && !backend_ctx->non_uniform_workgroups) { + local_work_size_ptr = nullptr; // Let driver choose the work-group sizes. + } + #ifdef GGML_OPENCL_PROFILING cl_event evt; - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, &evt)); g_profiling_info.emplace_back(); - populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size_ptr, dst); #else - CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size_ptr, 0, NULL, NULL)); #endif } } @@ -4815,6 +5457,124 @@ static void ggml_cl_im2col(ggml_backend_t backend, const ggml_tensor * src0, con #endif } +static void ggml_cl_argsort(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + GGML_UNUSED(src1); + + GGML_ASSERT(src0->type == GGML_TYPE_F32); + GGML_ASSERT( dst->type == GGML_TYPE_I32); + GGML_ASSERT(ggml_is_contiguous(src0)); + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + const int ne00 = src0->ne[0]; + const int nrows = ggml_nrows(src0); + + int ne00_padded = 1; + while (ne00_padded < ne00) { + ne00_padded *= 2; + } + + int order = (enum ggml_sort_order) dst->op_params[0]; + + cl_kernel kernel = backend_ctx->kernel_argsort_f32_i32; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne00_padded)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &order)); + CL_CHECK(clSetKernelArg(kernel, 7, ne00_padded*sizeof(int), NULL)); + + size_t global_work_size[] = {(size_t)ne00_padded, (size_t)nrows, (size_t)1}; + size_t local_work_size[] = {(size_t)ne00_padded, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif +} + +static void ggml_cl_sum_rows(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + GGML_ASSERT(src0); + GGML_ASSERT(src0->extra); + GGML_ASSERT(dst); + GGML_ASSERT(dst->extra); + GGML_UNUSED(src1); + + GGML_ASSERT(src0->nb[0] == ggml_type_size(src0->type)); + GGML_ASSERT(ggml_is_contiguous(src0)); + + ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context; + cl_command_queue queue = backend_ctx->queue; + + ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra; + ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra; + + cl_ulong offset0 = extra0->offset + src0->view_offs; + cl_ulong offsetd = extrad->offset + dst->view_offs; + + const int ne00 = src0->ne[0]; + const int ne01 = src0->ne[1]; + const int ne02 = src0->ne[2]; + const int ne03 = src0->ne[3]; + + const cl_ulong nb01 = src0->nb[1]; + const cl_ulong nb02 = src0->nb[2]; + const cl_ulong nb03 = src0->nb[3]; + + const cl_ulong nb1 = dst->nb[1]; + const cl_ulong nb2 = dst->nb[2]; + const cl_ulong nb3 = dst->nb[3]; + + cl_kernel kernel = backend_ctx->kernel_sum_rows_f32; + + CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device)); + CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0)); + CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device)); + CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd)); + CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00)); + CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01)); + CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne02)); + CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne03)); + CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb01)); + CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb02)); + CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb03)); + CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb1)); + CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb2)); + CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_ulong), &nb3)); + + size_t global_work_size[] = {(size_t)ne01, (size_t)ne02, (size_t)ne03}; + size_t local_work_size[] = {(size_t)64, 1, 1}; + +#ifdef GGML_OPENCL_PROFILING + cl_event evt; + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt)); + + g_profiling_info.emplace_back(); + populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst); +#else + CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL)); +#endif +} + //------------------------------------------------------------------------------ // Op offloading //------------------------------------------------------------------------------ @@ -4863,6 +5623,18 @@ bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor } func = ggml_cl_mul; break; + case GGML_OP_DIV: + if (!any_on_device) { + return false; + } + func = ggml_cl_div; + break; + case GGML_OP_SUB: + if (!any_on_device) { + return false; + } + func = ggml_cl_sub; + break; case GGML_OP_UNARY: switch (ggml_get_unary_op(tensor)) { case GGML_UNARY_OP_GELU: @@ -4889,6 +5661,12 @@ bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor } func = ggml_cl_relu; break; + case GGML_UNARY_OP_SIGMOID: + if (!any_on_device) { + return false; + } + func = ggml_cl_sigmoid; + break; default: return false; } break; @@ -4910,6 +5688,12 @@ bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor } func = ggml_cl_rms_norm; break; + case GGML_OP_GROUP_NORM: + if (!any_on_device) { + return false; + } + func = ggml_cl_group_norm; + break; case GGML_OP_MUL_MAT: if (!any_on_device && !ggml_cl_can_mul_mat(tensor->src[0], tensor->src[1], tensor)) { return false; @@ -4955,6 +5739,18 @@ bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor } func = ggml_cl_im2col; break; + case GGML_OP_ARGSORT: + if (!any_on_device) { + return false; + } + func = ggml_cl_argsort; + break; + case GGML_OP_SUM_ROWS: + if (!any_on_device) { + return false; + } + func = ggml_cl_sum_rows; + break; default: return false; } diff --git a/ggml/src/ggml-opencl/kernels/argsort.cl b/ggml/src/ggml-opencl/kernels/argsort.cl new file mode 100644 index 0000000000000..af4adc7b83f0a --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/argsort.cl @@ -0,0 +1,86 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#ifdef cl_intel_subgroups +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#else +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif + +#ifdef cl_intel_required_subgroup_size +#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable +#define INTEL_GPU 1 +#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16))) +#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32))) +#elif defined(cl_qcom_reqd_sub_group_size) +#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable +#define ADRENO_GPU 1 +#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half"))) +#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full"))) +#endif + +#define SWAP(x, y, T) { T tmp = (x); (x) = (y); (y) = tmp; } + +enum ggml_sort_order { + GGML_SORT_ORDER_ASC, + GGML_SORT_ORDER_DESC, +}; + +kernel void kernel_argsort_f32_i32( + global float * src0, + ulong offset0, + global int * dst, + ulong offsetd, + const int ne00, + const int ne00_pad, + const int order, + local int * dst_row +) { + // bitonic sort + int col = get_local_id(0); + int row = get_group_id(1); + + if (col >= ne00_pad) { + return; + } + + src0 = (global char *)((global char *)src0 + offset0); + dst = (global float *)((global char *)dst + offsetd); + + global float * x_row = src0 + row * ne00; + + // initialize indices + dst_row[col] = col; + + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k = 2; k <= ne00_pad; k *= 2) { + for (int j = k / 2; j > 0; j /= 2) { + int ixj = col ^ j; + if (ixj > col) { + if ((col & k) == 0) { + if (dst_row[col] >= ne00 || + (dst_row[ixj] < ne00 && (order == GGML_SORT_ORDER_ASC ? + x_row[dst_row[col]] > x_row[dst_row[ixj]] : + x_row[dst_row[col]] < x_row[dst_row[ixj]])) + ) { + SWAP(dst_row[col], dst_row[ixj], int); + } + } else { + if (dst_row[ixj] >= ne00 || + (dst_row[col] < ne00 && (order == GGML_SORT_ORDER_ASC ? + x_row[dst_row[col]] < x_row[dst_row[ixj]] : + x_row[dst_row[col]] > x_row[dst_row[ixj]])) + ) { + SWAP(dst_row[col], dst_row[ixj], int); + } + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + } + + // copy the result to dst without the padding + if (col < ne00) { + dst[row * ne00 + col] = dst_row[col]; + } +} diff --git a/ggml/src/ggml-opencl/kernels/div.cl b/ggml/src/ggml-opencl/kernels/div.cl new file mode 100644 index 0000000000000..d453ad99be47d --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/div.cl @@ -0,0 +1,72 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +//------------------------------------------------------------------------------ +// div +//------------------------------------------------------------------------------ +kernel void kernel_div( + global char * src0, + ulong offset0, + global char * src1, + ulong offset1, + global char * dst, + ulong offsetd, + ulong nb00, + ulong nb01, + ulong nb02, + ulong nb03, + int ne10, + int ne11, + int ne12, + int ne13, + ulong nb10, + ulong nb11, + ulong nb12, + ulong nb13, + int ne0, + ulong nb0, + ulong nb1, + ulong nb2, + ulong nb3 +) { + src0 = src0 + offset0; + src1 = src1 + offset1; + dst = dst + offsetd; + + int i03 = get_group_id(2); + int i02 = get_group_id(1); + int i01 = get_group_id(0); + + int i13 = i03 % ne13; + int i12 = i02 % ne12; + int i11 = i01 % ne11; + + global char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01; + global char * src1_ptr = src1 + i13*nb13 + i12*nb12 + i11*nb11; + global char * dst_ptr = dst + i03*nb3 + i02*nb2 + i01*nb1; + + for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) { + const int i10 = i0 % ne10; + *((global float *)(dst_ptr + i0*nb0)) = *((global float *)(src0_ptr + i0*nb00)) / *((global float *)(src1_ptr + i10*nb10)); + } +} + +// assumption: src1 is a row +// broadcast src1 into src0 +kernel void kernel_div_row( + global float4 * src0, + ulong offset0, + global float4 * src1, + ulong offset1, + global float4 * dst, + ulong offsetd, + int ne +) { + src0 = (global float4*)((global char*)src0 + offset0); + src1 = (global float4*)((global char*)src1 + offset1); + dst = (global float4*)((global char*)dst + offsetd); + + // This performs better than using %. + uint gid = get_global_id(0); + uint idx1 = gid - (gid/ne)*ne; // get_global_id(0) % ne + dst[gid] = src0[gid] / src1[idx1]; +} diff --git a/ggml/src/ggml-opencl/kernels/group_norm.cl b/ggml/src/ggml-opencl/kernels/group_norm.cl new file mode 100644 index 0000000000000..57c9df4d35b09 --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/group_norm.cl @@ -0,0 +1,72 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#ifdef cl_intel_subgroups +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#else +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif + +#ifdef cl_intel_required_subgroup_size +#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable +#define INTEL_GPU 1 +#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16))) +#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32))) +#elif defined(cl_qcom_reqd_sub_group_size) +#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable +#define ADRENO_GPU 1 +#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half"))) +#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full"))) +#endif + +// Workgroup must be a subgroup +#ifdef INTEL_GPU +REQD_SUBGROUP_SIZE_32 +#elif defined (ADRENO_GPU) +REQD_SUBGROUP_SIZE_64 +#endif +kernel void kernel_group_norm( + global float * src0, + ulong offset0, + global float * dst, + ulong offsetd, + int ne, + int group_size, + float eps +) { + src0 = (global float *)((global char *)src0 + offset0); + dst = (global float *)((global char *)dst + offsetd); + + int start = get_group_id(0) * group_size; + int end = start + group_size; + + start += get_local_id(0); + + if (end >= ne) { + end = ne; + } + + float tmp = 0.0f; + + for (int j = start; j < end; j += get_local_size(0)) { + tmp += src0[j]; + } + + tmp = sub_group_reduce_add(tmp); + + const float mean = tmp / group_size; + tmp = 0.0f; + + for (int j = start; j < end; j += get_local_size(0)) { + float xi = src0[j] - mean; + dst[j] = xi; + tmp += xi * xi; + } + + tmp = sub_group_reduce_add(tmp); + + const float variance = tmp / group_size; + const float scale = 1.0f/sqrt(variance + eps); + for (int j = start; j < end; j += get_local_size(0)) { + dst[j] *= scale; + } +} diff --git a/ggml/src/ggml-opencl/kernels/sigmoid.cl b/ggml/src/ggml-opencl/kernels/sigmoid.cl new file mode 100644 index 0000000000000..e3f669dde830b --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/sigmoid.cl @@ -0,0 +1,29 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +//------------------------------------------------------------------------------ +// sigmoid +//------------------------------------------------------------------------------ + +kernel void kernel_sigmoid_f32( + global float * src0, + ulong offset0, + global float * dst, + ulong offsetd +) { + src0 = (global float*)((global char*)src0 + offset0); + dst = (global float*)((global char*)dst + offsetd); + + dst[get_global_id(0)] = 1.0f / (1.0f + exp(-src0[get_global_id(0)])); +} + +kernel void kernel_sigmoid_f16( + global half * src0, + ulong offset0, + global half * dst, + ulong offsetd +) { + src0 = (global half*)((global char*)src0 + offset0); + dst = (global half*)((global char*)dst + offsetd); + + dst[get_global_id(0)] = 1.0f / (1.0f + exp(-src0[get_global_id(0)])); +} diff --git a/ggml/src/ggml-opencl/kernels/sub.cl b/ggml/src/ggml-opencl/kernels/sub.cl new file mode 100644 index 0000000000000..041e88ad3a080 --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/sub.cl @@ -0,0 +1,72 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +//------------------------------------------------------------------------------ +// div +//------------------------------------------------------------------------------ +kernel void kernel_sub( + global char * src0, + ulong offset0, + global char * src1, + ulong offset1, + global char * dst, + ulong offsetd, + ulong nb00, + ulong nb01, + ulong nb02, + ulong nb03, + int ne10, + int ne11, + int ne12, + int ne13, + ulong nb10, + ulong nb11, + ulong nb12, + ulong nb13, + int ne0, + ulong nb0, + ulong nb1, + ulong nb2, + ulong nb3 +) { + src0 = src0 + offset0; + src1 = src1 + offset1; + dst = dst + offsetd; + + int i03 = get_group_id(2); + int i02 = get_group_id(1); + int i01 = get_group_id(0); + + int i13 = i03 % ne13; + int i12 = i02 % ne12; + int i11 = i01 % ne11; + + global char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01; + global char * src1_ptr = src1 + i13*nb13 + i12*nb12 + i11*nb11; + global char * dst_ptr = dst + i03*nb3 + i02*nb2 + i01*nb1; + + for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) { + const int i10 = i0 % ne10; + *((global float *)(dst_ptr + i0*nb0)) = *((global float *)(src0_ptr + i0*nb00)) - *((global float *)(src1_ptr + i10*nb10)); + } +} + +// assumption: src1 is a row +// broadcast src1 into src0 +kernel void kernel_sub_row( + global float4 * src0, + ulong offset0, + global float4 * src1, + ulong offset1, + global float4 * dst, + ulong offsetd, + int ne +) { + src0 = (global float4*)((global char*)src0 + offset0); + src1 = (global float4*)((global char*)src1 + offset1); + dst = (global float4*)((global char*)dst + offsetd); + + // This performs better than using %. + uint gid = get_global_id(0); + uint idx1 = gid - (gid/ne)*ne; // get_global_id(0) % ne + dst[gid] = src0[gid] - src1[idx1]; +} diff --git a/ggml/src/ggml-opencl/kernels/sum_rows.cl b/ggml/src/ggml-opencl/kernels/sum_rows.cl new file mode 100644 index 0000000000000..c5f7c570f9514 --- /dev/null +++ b/ggml/src/ggml-opencl/kernels/sum_rows.cl @@ -0,0 +1,39 @@ + +kernel void kernel_sum_rows_f32( + global float * src0, + ulong offset0, + global float * dst, + ulong offsetd, + int ne00, + int ne01, + int ne02, + int ne03, + ulong nb01, + ulong nb02, + ulong nb03, + ulong nb1, + ulong nb2, + ulong nb3 +) { + src0 = (global float *)((global char *)src0 + offset0); + dst = (global float *)((global char *)dst + offsetd); + + int i3 = get_global_id(2); + int i2 = get_global_id(1); + int i1 = get_global_id(0); + + if (i3 >= ne03 || i2 >= ne02 || i1 >= ne01) { + return; + } + + global float * src_row = (global float *) ((global char *) src0 + i1*nb01 + i2*nb02 + i3*nb03); + global float * dst_row = (global float *) ((global char *) dst + i1*nb1 + i2*nb2 + i3*nb3); + + float row_sum = 0; + + for (int i0 = 0; i0 < ne00; i0++) { + row_sum += src_row[i0]; + } + + dst_row[0] = row_sum; +} diff --git a/ggml/src/ggml-opt.cpp b/ggml/src/ggml-opt.cpp index 58d77578f458d..a3c82d6757714 100644 --- a/ggml/src/ggml-opt.cpp +++ b/ggml/src/ggml-opt.cpp @@ -576,6 +576,10 @@ void ggml_opt_reset(ggml_opt_context_t opt_ctx, bool optimizer) { } } +bool ggml_opt_static_graphs(ggml_opt_context_t opt_ctx) { + return opt_ctx->static_graphs; +} + struct ggml_tensor * ggml_opt_inputs(ggml_opt_context_t opt_ctx) { return opt_ctx->inputs; } @@ -842,6 +846,7 @@ void ggml_opt_epoch( int64_t idata_split, ggml_opt_epoch_callback callback_train, ggml_opt_epoch_callback callback_eval) { + GGML_ASSERT(ggml_opt_static_graphs(opt_ctx) && "ggml_opt_epoch requires static graphs"); struct ggml_tensor * inputs = ggml_opt_inputs(opt_ctx); struct ggml_tensor * labels = ggml_opt_labels(opt_ctx); struct ggml_tensor * data = ggml_opt_dataset_data(dataset); diff --git a/ggml/src/ggml-sycl/binbcast.cpp b/ggml/src/ggml-sycl/binbcast.cpp index aaa94176f168c..0a3883ae1eda5 100644 --- a/ggml/src/ggml-sycl/binbcast.cpp +++ b/ggml/src/ggml-sycl/binbcast.cpp @@ -1,74 +1,93 @@ #include "binbcast.hpp" -#include #include #include #include -#include "dpct/helper.hpp" #include "ggml.h" -template -static __dpct_inline__ void k_bin_bcast_contiguous(const src0_t * __restrict__ src0, const src1_t * __restrict__ src1, - dst_t * dst, std::size_t num_elements, const sycl::nd_item<1> & it) { - auto element_id = it.get_global_id(0); - auto global_range = it.get_global_range(0); - for (; element_id < num_elements; element_id += global_range) { - auto src0_float_val = sycl::vec(src0[element_id]).template convert(); - auto src1_float_val = sycl::vec(src1[element_id]).template convert(); - float dst_val = bin_op(src0_float_val[0], src1_float_val[0]); - auto val_to_store = sycl::vec(dst_val).template convert(); - dst[element_id] = val_to_store; +template +static void k_bin_bcast(const src0_t * src0, const src1_t * src1, dst_t * dst, + int ne0, int ne1, int ne2, int ne3, + int ne10, int ne11, int ne12, int ne13, + /*int s0, */ int s1, int s2, int s3, + /*int s00,*/ int s01, int s02, int s03, + /*int s10,*/ int s11, int s12, int s13, + const sycl::nd_item<3> &item_ct1) { + const int i0s = item_ct1.get_local_range(2) * item_ct1.get_group(2) + + item_ct1.get_local_id(2); + const int i1 = (item_ct1.get_local_range(1) * item_ct1.get_group(1) + + item_ct1.get_local_id(1)); + const int i2 = (item_ct1.get_local_range(0) * item_ct1.get_group(0) + + item_ct1.get_local_id(0)) / + ne3; + const int i3 = (item_ct1.get_local_range(0) * item_ct1.get_group(0) + + item_ct1.get_local_id(0)) % + ne3; + + if (i0s >= ne0 || i1 >= ne1 || i2 >= ne2 || i3 >= ne3) { + return; + } + + const int i11 = i1 % ne11; + const int i12 = i2 % ne12; + const int i13 = i3 % ne13; + + const size_t i_src0 = i3*s03 + i2*s02 + i1*s01; + const size_t i_src1 = i13*s13 + i12*s12 + i11*s11; + const size_t i_dst = i3*s3 + i2*s2 + i1*s1; + + const src0_t * src0_row = src0 + i_src0; + const src1_t * src1_row = src1 + i_src1; + dst_t * dst_row = dst + i_dst; + + for (int i0 = i0s; i0 < ne0; + i0 += item_ct1.get_local_range(2) * item_ct1.get_group_range(2)) { + const int i10 = i0 % ne10; + dst_row[i0] = (dst_t)bin_op(src0 ? (float)src0_row[i0] : 0.0f, (float)src1_row[i10]); } } -template -static __dpct_inline__ void k_bin_bcast(const src0_t * __restrict__ src0, const src1_t * __restrict__ src1, dst_t * dst, - int ne0, int ne1, int ne2, int ne3, int ne10, int ne11, int ne12, int ne13, - int s0, int s1, int s2, int s3, int s00, int s01, int s02, int s03, int s10, - int s11, int s12, int s13, std::size_t num_dst_elements, - const sycl::nd_item<1> & item_ct1) { - auto calculate_logical_index = - [](const std::array & dims, std::size_t element_id) __attribute__((always_inline))->std::array { - std::array logical_index; -#pragma unroll(4) - for (int i = 3; i >= 0; i--) { - logical_index[i] = element_id % dims[i]; - element_id /= dims[i]; - } - return logical_index; - }; - - auto calculate_index = [](const std::array & dims, const std::array & strides, - const std::array & indices) __attribute__((always_inline)) - ->std::size_t { - std::size_t index = 0; -#pragma unroll(4) - for (int i = 0; i < 4; i++) { - auto index_i = indices[i]; - if (indices[i] >= dims[i]) { - index_i = indices[i] % dims[i]; - } - index += strides[i] * index_i; - } - return index; - }; - - auto element_id = item_ct1.get_global_id(0); - for (; element_id < num_dst_elements; element_id += item_ct1.get_global_range(0)) { - auto logical_index = calculate_logical_index({ ne3, ne2, ne1, ne0 }, element_id); - auto src_0_index = calculate_index({ ne3, ne2, ne1, ne0 }, { s03, s02, s01, s00 }, logical_index); - auto src_1_index = calculate_index({ ne13, ne12, ne11, ne10 }, { s13, s12, s11, s10 }, logical_index); - auto dst_index = calculate_index({ ne3, ne2, ne1, ne0 }, { s3, s2, s1, s0 }, logical_index); - auto src0_float_val = sycl::vec(src0[src_0_index]).template convert(); - auto src1_float_val = sycl::vec(src1[src_1_index]).template convert(); - float dst_val = bin_op(src0_float_val[0], src1_float_val[0]); - auto val_to_store = sycl::vec(dst_val).template convert(); - dst[dst_index] = val_to_store; +template +static void k_bin_bcast_unravel(const src0_t * src0, const src1_t * src1, dst_t * dst, + int ne0, int ne1, int ne2, int ne3, + int ne10, int ne11, int ne12, int ne13, + /*int s0, */ int s1, int s2, int s3, + /*int s00,*/ int s01, int s02, int s03, + /*int s10,*/ int s11, int s12, int s13, + const sycl::nd_item<3> &item_ct1) { + + const int i = item_ct1.get_local_range(2) * item_ct1.get_group(2) + + item_ct1.get_local_id(2); + + const int i3 = i/(ne2*ne1*ne0); + const int i2 = (i/(ne1*ne0)) % ne2; + const int i1 = (i/ne0) % ne1; + const int i0 = i % ne0; + + if (i0 >= ne0 || i1 >= ne1 || i2 >= ne2 || i3 >= ne3) { + return; } + + const int i11 = i1 % ne11; + const int i12 = i2 % ne12; + const int i13 = i3 % ne13; + + const size_t i_src0 = i3*s03 + i2*s02 + i1*s01; + const size_t i_src1 = i13*s13 + i12*s12 + i11*s11; + const size_t i_dst = i3*s3 + i2*s2 + i1*s1; + + const src0_t * src0_row = src0 + i_src0; + const src1_t * src1_row = src1 + i_src1; + dst_t * dst_row = dst + i_dst; + + const int i10 = i0 % ne10; + dst_row[i0] = (dst_t)bin_op(src0 ? (float)src0_row[i0] : 0.0f, (float)src1_row[i10]); } -template struct bin_bcast_sycl { + +template +struct bin_bcast_sycl { template void operator()(const src0_t * src0_dd, const src1_t * src1_dd, dst_t * dst_dd, const int64_t ne00, const int64_t ne01, const int64_t ne02, const int64_t ne03, const int64_t ne10, const int64_t ne11, @@ -77,73 +96,165 @@ template struct bin_bcast_sycl { const size_t nb10, const size_t nb11, const size_t nb12, const size_t nb13, const size_t nb0, const size_t nb1, const size_t nb2, const size_t nb3, const bool src0_is_contiguous, const bool src1_is_contiguous, const bool dst_is_contiguous, queue_ptr stream) { - auto check_bcast_required = [](const std::array & src_dims, - const std::array & dst_dims) -> bool { + int nr0 = ne10 / ne0; + int nr1 = ne11/ne1; + int nr2 = ne12/ne2; + int nr3 = ne13/ne3; + + int nr[4] = { nr0, nr1, nr2, nr3 }; + + // collapse dimensions until first broadcast dimension + int64_t cne[] = {ne0, ne1, ne2, ne3}; + int64_t cne0[] = {ne00, ne01, ne02, ne03}; + int64_t cne1[] = {ne10, ne11, ne12, ne13}; + size_t cnb[] = {nb0, nb1, nb2, nb3}; + size_t cnb0[] = {nb00, nb01, nb02, nb03}; + size_t cnb1[] = {nb10, nb11, nb12, nb13}; + auto collapse = [](int64_t cne[]) { + cne[0] *= cne[1]; + cne[1] = cne[2]; + cne[2] = cne[3]; + cne[3] = 1; + }; + + auto collapse_nb = [](size_t cnb[], int64_t cne[]) { + cnb[1] *= cne[1]; + cnb[2] *= cne[2]; + cnb[3] *= cne[3]; + }; + + if (src0_is_contiguous && src1_is_contiguous && dst_is_contiguous) { for (int i = 0; i < 4; i++) { - if (dst_dims[i] > src_dims[i]) { - return true; + if (nr[i] != 1) { + break; + } + if (i > 0) { + collapse_nb(cnb, cne); + collapse_nb(cnb0, cne0); + collapse_nb(cnb1, cne1); + collapse(cne); + collapse(cne0); + collapse(cne1); } } - return false; - }; - - dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 }); - - GGML_ASSERT(nb0 % sizeof(dst_t) == 0); - GGML_ASSERT(nb1 % sizeof(dst_t) == 0); - GGML_ASSERT(nb2 % sizeof(dst_t) == 0); - GGML_ASSERT(nb3 % sizeof(dst_t) == 0); - - GGML_ASSERT(nb00 % sizeof(src0_t) == 0); - GGML_ASSERT(nb01 % sizeof(src0_t) == 0); - GGML_ASSERT(nb02 % sizeof(src0_t) == 0); - GGML_ASSERT(nb03 % sizeof(src0_t) == 0); - - GGML_ASSERT(nb10 % sizeof(src1_t) == 0); - GGML_ASSERT(nb11 % sizeof(src1_t) == 0); - GGML_ASSERT(nb12 % sizeof(src1_t) == 0); - GGML_ASSERT(nb13 % sizeof(src1_t) == 0); - - // dst strides in number of elements - size_t s0 = nb0 / sizeof(dst_t); - size_t s1 = nb1 / sizeof(dst_t); - size_t s2 = nb2 / sizeof(dst_t); - size_t s3 = nb3 / sizeof(dst_t); - - // src1 strides in number of elements - size_t s10 = nb10 / sizeof(src0_t); - size_t s11 = nb11 / sizeof(src1_t); - size_t s12 = nb12 / sizeof(src1_t); - size_t s13 = nb13 / sizeof(src1_t); - - // src0 strides in number of elements - size_t s00 = nb00 / sizeof(src0_t); - size_t s01 = nb01 / sizeof(src0_t); - size_t s02 = nb02 / sizeof(src0_t); - size_t s03 = nb03 / sizeof(src0_t); - - std::size_t num_dst_elements = static_cast(ne0) * static_cast(ne1) * - static_cast(ne2) * static_cast(ne3); - std::size_t local_range = 256; - std::size_t global_range = ceil_div(num_dst_elements, local_range) * local_range; - - bool needs_broadcasting = check_bcast_required({ ne00, ne01, ne02, ne03 }, { ne0, ne1, ne2, ne3 }) || - check_bcast_required({ ne10, ne11, ne12, ne13 }, { ne0, ne1, ne2, ne3 }); - bool all_contiguous = src0_is_contiguous && src1_is_contiguous && dst_is_contiguous; - - if (! needs_broadcasting && all_contiguous) { - stream->submit([&](sycl::handler & cgh) { - cgh.parallel_for(sycl::nd_range<1>({ global_range }, { local_range }), [=](sycl::nd_item<1> it) { - k_bin_bcast_contiguous(src0_dd, src1_dd, dst_dd, num_dst_elements, it); - }); - }); - } else { - stream->submit([&](sycl::handler & cgh) { - cgh.parallel_for(sycl::nd_range<1>({ global_range }, { local_range }), [=](sycl::nd_item<1> it) { - k_bin_bcast(src0_dd, src1_dd, dst_dd, ne0, ne1, ne2, ne3, ne10, ne11, ne12, ne13, s0, s1, - s2, s3, s00, s01, s02, s03, s10, s11, s12, s13, num_dst_elements, it); - }); - }); + } + { + int64_t ne0 = cne[0]; + int64_t ne1 = cne[1]; + int64_t ne2 = cne[2]; + int64_t ne3 = cne[3]; + + int64_t ne10 = cne1[0]; + int64_t ne11 = cne1[1]; + int64_t ne12 = cne1[2]; + int64_t ne13 = cne1[3]; + + size_t nb0 = cnb[0]; + size_t nb1 = cnb[1]; + size_t nb2 = cnb[2]; + size_t nb3 = cnb[3]; + + size_t nb00 = cnb0[0]; + size_t nb01 = cnb0[1]; + size_t nb02 = cnb0[2]; + size_t nb03 = cnb0[3]; + + size_t nb10 = cnb1[0]; + size_t nb11 = cnb1[1]; + size_t nb12 = cnb1[2]; + size_t nb13 = cnb1[3]; + + size_t s0 = nb0 / sizeof(dst_t); + size_t s1 = nb1 / sizeof(dst_t); + size_t s2 = nb2 / sizeof(dst_t); + size_t s3 = nb3 / sizeof(dst_t); + + size_t s10 = nb10 / sizeof(src1_t); + size_t s11 = nb11 / sizeof(src1_t); + size_t s12 = nb12 / sizeof(src1_t); + size_t s13 = nb13 / sizeof(src1_t); + + size_t s00 = nb00 / sizeof(src0_t); + size_t s01 = nb01 / sizeof(src0_t); + size_t s02 = nb02 / sizeof(src0_t); + size_t s03 = nb03 / sizeof(src0_t); + + GGML_UNUSED(s00); + + GGML_ASSERT(nb0 % sizeof(dst_t) == 0); + GGML_ASSERT(nb1 % sizeof(dst_t) == 0); + GGML_ASSERT(nb2 % sizeof(dst_t) == 0); + GGML_ASSERT(nb3 % sizeof(dst_t) == 0); + + GGML_ASSERT(nb00 % sizeof(src0_t) == 0); + GGML_ASSERT(nb01 % sizeof(src0_t) == 0); + GGML_ASSERT(nb02 % sizeof(src0_t) == 0); + GGML_ASSERT(nb03 % sizeof(src0_t) == 0); + + GGML_ASSERT(nb10 % sizeof(src1_t) == 0); + GGML_ASSERT(nb11 % sizeof(src1_t) == 0); + GGML_ASSERT(nb12 % sizeof(src1_t) == 0); + GGML_ASSERT(nb13 % sizeof(src1_t) == 0); + + GGML_ASSERT(s0 == 1); + GGML_ASSERT(s10 == 1); + + const int block_size = 128; + + int64_t hne0 = std::max(ne0/2LL, 1LL); + + sycl::range<3> block_dims(1, 1, 1); + block_dims[2] = std::min(hne0, block_size); + block_dims[1] = std::min( + ne1, block_size / (unsigned int)block_dims[2]); + block_dims[0] = std::min( + std::min( + ne2 * ne3, block_size / (unsigned int)block_dims[2] / + (unsigned int)block_dims[1]), + 64U); + + sycl::range<3> block_nums( + (ne2 * ne3 + block_dims[0] - 1) / block_dims[0], + (ne1 + block_dims[1] - 1) / block_dims[1], + (hne0 + block_dims[2] - 1) / block_dims[2]); + + if (block_nums[0] > 65535) { + // this is the maximum number of blocks in z direction, fallback to 1D grid kernel + int block_num = (ne0*ne1*ne2*ne3 + block_size - 1) / block_size; + { + dpct::has_capability_or_fail(stream->get_device(), + {sycl::aspect::fp16}); + + stream->parallel_for( + sycl::nd_range<3>(sycl::range<3>(1, 1, block_num) * + sycl::range<3>(1, 1, block_size), + sycl::range<3>(1, 1, block_size)), + [=](sycl::nd_item<3> item_ct1) { + k_bin_bcast_unravel( + src0_dd, src1_dd, dst_dd, ne0, ne1, ne2, ne3, + ne10, ne11, ne12, ne13, s1, s2, s3, s01, s02, + s03, s11, s12, s13, item_ct1); + }); + } + } else { + /* + DPCT1049:16: The work-group size passed to the SYCL kernel may + exceed the limit. To get the device limit, query + info::device::max_work_group_size. Adjust the work-group size if + needed. + */ + dpct::has_capability_or_fail(stream->get_device(), + {sycl::aspect::fp16}); + + stream->parallel_for( + sycl::nd_range<3>(block_nums * block_dims, block_dims), + [=](sycl::nd_item<3> item_ct1) { + k_bin_bcast(src0_dd, src1_dd, dst_dd, ne0, ne1, + ne2, ne3, ne10, ne11, ne12, ne13, + s1, s2, s3, s01, s02, s03, s11, s12, s13, + item_ct1); + }); + } } } }; @@ -208,32 +319,27 @@ inline void ggml_sycl_op_repeat(ggml_backend_sycl_context & ctx, ggml_tensor *ds void ggml_sycl_add(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_add(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_sub(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_sub(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_mul(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_mul(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_div(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_div(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_repeat(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_repeat(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } diff --git a/ggml/src/ggml-sycl/common.hpp b/ggml/src/ggml-sycl/common.hpp index 60909dde7d087..15ee9dc69d149 100644 --- a/ggml/src/ggml-sycl/common.hpp +++ b/ggml/src/ggml-sycl/common.hpp @@ -13,8 +13,10 @@ #ifndef GGML_SYCL_COMMON_HPP #define GGML_SYCL_COMMON_HPP +#include #include #include +#include #include "dpct/helper.hpp" #include "ggml-sycl.h" @@ -44,11 +46,20 @@ extern int g_ggml_sycl_debug; extern int g_ggml_sycl_disable_optimize; extern int g_ggml_sycl_prioritize_dmmv; -#define GGML_SYCL_DEBUG(...) \ - do { \ - if (g_ggml_sycl_debug) \ - fprintf(stderr, __VA_ARGS__); \ - } while (0) +#if defined(__clang__) && __has_builtin(__builtin_expect) +// Hint the optimizer to pipeline the more likely following instruction in branches +# define LIKELY(expr) __builtin_expect(expr, true) +# define UNLIKELY(expr) __builtin_expect(expr, false) +#else +# define LIKELY(expr) (expr) +# define UNLIKELY(expr) (expr) +#endif + +#define GGML_SYCL_DEBUG(...) \ + do { \ + if (UNLIKELY(g_ggml_sycl_debug)) \ + fprintf(stderr, __VA_ARGS__); \ + } while (0) #define CHECK_TRY_ERROR(expr) \ [&]() { \ @@ -471,6 +482,19 @@ static __dpct_inline__ float warp_reduce_max(float x, return x; } +/* Helper for Computing the linear offset of a ggml_tensor given +per-dimension sizes, strides, and indices */ +template +__dpct_inline__ size_t calculate_offset(const std::array & strides, const std::array & indices) { + size_t offset = 0; +#pragma unroll + for (int i = 0; i < N; i++) { + auto index_i = indices[i]; + offset += strides[i] * index_i; + } + return offset; +} + // Helper for vec loading aligned data template inline sycl::vec vec_aligned_load(const Tp* aligned_ptr) { @@ -490,4 +514,76 @@ constexpr size_t ceil_div(const size_t m, const size_t n) { } bool gpu_has_xmx(sycl::device &dev); + +template void debug_print_array(const std::string & prefix, const T array[N]) { + if (LIKELY(!g_ggml_sycl_debug)) { + return; + } + std::stringstream ss; + ss << prefix << "=["; + for (std::size_t i = 0; i < N - 1; ++i) { + ss << array[i] << ", "; + } + if constexpr (N > 0) { + ss << array[N - 1]; + } + ss << "]"; + GGML_SYCL_DEBUG("%s", ss.str().c_str()); +} + +inline void debug_print_tensor(const std::string & prefix, const ggml_tensor * tensor, + const std::string & suffix = "") { + if (LIKELY(!g_ggml_sycl_debug)) { + return; + } + GGML_SYCL_DEBUG("%s=", prefix.c_str()); + if (tensor) { + GGML_SYCL_DEBUG("'%s':type=%s", tensor->name, ggml_type_name(tensor->type)); + debug_print_array(";ne", tensor->ne); + debug_print_array(";nb", tensor->nb); + if (!ggml_is_contiguous(tensor)) { + GGML_SYCL_DEBUG(";strided"); + } + if (ggml_is_permuted(tensor)) { + GGML_SYCL_DEBUG(";permuted"); + } + } else { + GGML_SYCL_DEBUG("nullptr"); + } + GGML_SYCL_DEBUG("%s", suffix.c_str()); +} + +// Use scope_op_debug_print to log operations coming from running a model +struct scope_op_debug_print { + // Use string_views to avoid the cost of creating a string and concatenating them + // string_views must be alive for as long as the object is alive + // scope_op_debug_print are used with string literals in practice which are stored in constant space so always accessible + scope_op_debug_print(const std::string_view & func, const std::string_view & func_suffix, const ggml_tensor * dst, + std::size_t num_src, const std::string_view & suffix = "") : + func(func), + func_suffix(func_suffix) { + if (LIKELY(!g_ggml_sycl_debug)) { + return; + } + GGML_SYCL_DEBUG("[SYCL][OP] call %s%s:", func.data(), func_suffix.data()); + debug_print_tensor(" dst", dst); + if (dst) { + for (std::size_t i = 0; i < num_src; ++i) { + debug_print_tensor("\tsrc" + std::to_string(i), dst->src[i]); + } + } + GGML_SYCL_DEBUG("%s\n", suffix.data()); + } + + scope_op_debug_print(const std::string_view & func, const ggml_tensor * dst, std::size_t num_src, + const std::string_view & suffix = "") : + scope_op_debug_print(func, "", dst, num_src, suffix) {} + + ~scope_op_debug_print() { GGML_SYCL_DEBUG("[SYCL][OP] call %s%s done\n", func.data(), func_suffix.data()); } + + private: + std::string_view func; + std::string_view func_suffix; +}; + #endif // GGML_SYCL_COMMON_HPP diff --git a/ggml/src/ggml-sycl/concat.cpp b/ggml/src/ggml-sycl/concat.cpp index d41cfd3a6ec88..7aa91c861d583 100644 --- a/ggml/src/ggml-sycl/concat.cpp +++ b/ggml/src/ggml-sycl/concat.cpp @@ -159,39 +159,37 @@ static void concat_f32_sycl_non_cont( } void ggml_sycl_op_concat(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - const ggml_tensor *src0 = dst->src[0]; - const ggml_tensor *src1 = dst->src[1]; - queue_ptr stream = ctx.stream(); - - const int32_t dim = ((int32_t *)dst->op_params)[0]; - - if (ggml_is_contiguous(src0) && ggml_is_contiguous(src1)) { - const float *src0_d = (const float *)src0->data; - const float *src1_d = (const float *)src1->data; - - float *dst_d = (float *)dst->data; - - if (dim != 3) { - for (int i3 = 0; i3 < dst->ne[3]; i3++) { - concat_f32_sycl( - src0_d + i3 * (src0->nb[3] / 4), src1_d + i3 * (src1->nb[3] / 4), - dst_d + i3 * (dst->nb[3] / 4), src0->ne[0], src0->ne[1], - src0->ne[2], dst->ne[0], dst->ne[1], dst->ne[2], dim, stream); - } + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); + const ggml_tensor * src0 = dst->src[0]; + const ggml_tensor * src1 = dst->src[1]; + queue_ptr stream = ctx.stream(); + + const int32_t dim = ((int32_t *) dst->op_params)[0]; + + if (ggml_is_contiguous(src0) && ggml_is_contiguous(src1)) { + const float * src0_d = (const float *) src0->data; + const float * src1_d = (const float *) src1->data; + + float * dst_d = (float *) dst->data; + + if (dim != 3) { + for (int i3 = 0; i3 < dst->ne[3]; i3++) { + concat_f32_sycl(src0_d + i3 * (src0->nb[3] / 4), src1_d + i3 * (src1->nb[3] / 4), + dst_d + i3 * (dst->nb[3] / 4), src0->ne[0], src0->ne[1], src0->ne[2], dst->ne[0], + dst->ne[1], dst->ne[2], dim, stream); + } + } else { + const size_t size0 = ggml_nbytes(src0); + const size_t size1 = ggml_nbytes(src1); + + SYCL_CHECK(CHECK_TRY_ERROR(stream->memcpy(dst_d, src0_d, size0).wait())); + SYCL_CHECK(CHECK_TRY_ERROR(stream->memcpy(dst_d + size0 / 4, src1_d, size1).wait())); + } } else { - const size_t size0 = ggml_nbytes(src0); - const size_t size1 = ggml_nbytes(src1); - - SYCL_CHECK(CHECK_TRY_ERROR(stream->memcpy(dst_d, src0_d, size0).wait())); - SYCL_CHECK(CHECK_TRY_ERROR( - stream->memcpy(dst_d + size0 / 4, src1_d, size1).wait())); + concat_f32_sycl_non_cont(stream, (const char *) src0->data, (const char *) src1->data, (char *) dst->data, + src0->ne[0], src0->ne[1], src0->ne[2], src0->ne[3], src0->nb[0], src0->nb[1], + src0->nb[2], src0->nb[3], src1->ne[0], src1->ne[1], src1->ne[2], src1->ne[3], + src1->nb[0], src1->nb[1], src1->nb[2], src1->nb[3], dst->ne[0], dst->ne[1], dst->ne[2], + dst->ne[3], dst->nb[0], dst->nb[1], dst->nb[2], dst->nb[3], dim); } - } else - concat_f32_sycl_non_cont( - stream, (const char *)src0->data, (const char *)src1->data, - (char *)dst->data, src0->ne[0], src0->ne[1], src0->ne[2], src0->ne[3], - src0->nb[0], src0->nb[1], src0->nb[2], src0->nb[3], src1->ne[0], - src1->ne[1], src1->ne[2], src1->ne[3], src1->nb[0], src1->nb[1], - src1->nb[2], src1->nb[3], dst->ne[0], dst->ne[1], dst->ne[2], - dst->ne[3], dst->nb[0], dst->nb[1], dst->nb[2], dst->nb[3], dim); } diff --git a/ggml/src/ggml-sycl/conv.cpp b/ggml/src/ggml-sycl/conv.cpp index ddba601e10fcc..475bd34a25d56 100644 --- a/ggml/src/ggml-sycl/conv.cpp +++ b/ggml/src/ggml-sycl/conv.cpp @@ -72,6 +72,7 @@ static void conv_transpose_1d_f32_f32_sycl( } void ggml_sycl_op_conv_transpose_1d(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); const ggml_tensor *src0 = dst->src[0]; const ggml_tensor *src1 = dst->src[1]; const float * src0_d = (const float *)src0->data; diff --git a/ggml/src/ggml-sycl/cpy.cpp b/ggml/src/ggml-sycl/cpy.cpp index 5a23145895f26..44487c25646d6 100644 --- a/ggml/src/ggml-sycl/cpy.cpp +++ b/ggml/src/ggml-sycl/cpy.cpp @@ -616,6 +616,9 @@ static void ggml_cpy_i32_i32_sycl(const char * cx, char * cdst, const int ne, co } void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1) try { + // Unlike other operators ggml_sycl_cpy takes 2 distinct tensors instead of a dst ggml_tensor and rely on its src field + scope_op_debug_print scope_dbg_print(__func__, src1, /*num_src=*/0, + std::string(" src0 type=") + ggml_type_name(src0->type)); const int64_t ne = ggml_nelements(src0); GGML_ASSERT(ne == ggml_nelements(src1)); @@ -629,8 +632,6 @@ void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, co char * src0_ddc = (char *) src0->data; char * src1_ddc = (char *) src1->data; - GGML_SYCL_DEBUG("[SYCL] %s: Tensor supplied: %s to %s\n", __func__, ggml_type_name(src0->type), - ggml_type_name(src1->type)); if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32) { ggml_cpy_f32_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10, @@ -694,8 +695,6 @@ void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, co } void ggml_sycl_dup(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - // TODO: why do we pass dst as src1 here? - GGML_SYCL_DEBUG("[SYCL] call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_cpy(ctx, dst->src[0], dst); - GGML_SYCL_DEBUG("[SYCL] call %s done\n", __func__); } diff --git a/ggml/src/ggml-sycl/dmmv.cpp b/ggml/src/ggml-sycl/dmmv.cpp index b58150c687b71..4f2760110c212 100644 --- a/ggml/src/ggml-sycl/dmmv.cpp +++ b/ggml/src/ggml-sycl/dmmv.cpp @@ -1092,6 +1092,8 @@ void ggml_sycl_op_dequantize_mul_mat_vec( src0->type == GGML_TYPE_Q8_0 || src0->type == GGML_TYPE_F16; if (src1_convert_f16) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp16_sycl", dst, /*num_src=*/2, + " : converting src1 to fp16"); src1_dfloat = src1_dfloat_a.alloc(ne00); const to_fp16_sycl_t to_fp16_sycl = ggml_get_to_fp16_sycl(src1->type, dst); GGML_ASSERT(to_fp16_sycl != nullptr); diff --git a/ggml/src/ggml-sycl/element_wise.cpp b/ggml/src/ggml-sycl/element_wise.cpp index becaac4048a7f..5b7c4f0b4f003 100644 --- a/ggml/src/ggml-sycl/element_wise.cpp +++ b/ggml/src/ggml-sycl/element_wise.cpp @@ -84,6 +84,15 @@ static void gelu_quick(const T *x, T *dst, int k, dst[i] = x[i] * (static_cast(1.0f) / (static_cast(1.0f) + sycl::native::exp(GELU_QUICK_COEF * x[i]))); } +template +static void gelu_erf(const T * x, T * dst, const int k, const sycl::nd_item<3> &item_ct1) { + const T SQRT_2_INV = static_cast(0.70710678118654752440084436210484f); + for(auto i = item_ct1.get_global_id(2); i < (const size_t)k; i += item_ct1.get_global_range(2)) { + auto x_i = x[i]; + dst[i] = static_cast(0.5f) * x_i * (static_cast(1.0f) + sycl::erf(x_i * SQRT_2_INV)); + } +} + template static void tanh(const T *x, T *dst, int k, const sycl::nd_item<3> &item_ct1) { @@ -400,6 +409,20 @@ static void gelu_quick_sycl(const T *x, T *dst, const int k, }); } + +template +static void gelu_erf_sycl(const T *x, T *dst, const int k, + queue_ptr stream) { + const int num_blocks = ceil_div(k, SYCL_GELU_BLOCK_SIZE); + stream->parallel_for( + sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * + sycl::range<3>(1, 1, SYCL_GELU_BLOCK_SIZE), + sycl::range<3>(1, 1, SYCL_GELU_BLOCK_SIZE)), + [=](sycl::nd_item<3> item_ct1) { + gelu_erf(x, dst, k, item_ct1); + }); +} + template static void tanh_sycl(const T *x, T *dst, const int k, queue_ptr stream) { @@ -816,6 +839,38 @@ inline void ggml_sycl_op_gelu_quick(ggml_backend_sycl_context & ctx, ggml_tensor } } +inline void ggml_sycl_op_gelu_erf(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { +#if defined (GGML_SYCL_F16) + GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32 || dst->src[0]->type == GGML_TYPE_F16); + GGML_ASSERT(dst->type == GGML_TYPE_F32 || dst->type == GGML_TYPE_F16); +#else + GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); + GGML_ASSERT(dst->type == GGML_TYPE_F32); +#endif + GGML_ASSERT(dst->src[0]->type == dst->type); + dpct::queue_ptr main_stream = ctx.stream(); + SYCL_CHECK(ggml_sycl_set_device(ctx.device)); + switch (dst->type) { +#if defined (GGML_SYCL_F16) + case GGML_TYPE_F16: + { + auto data_pts = cast_data(dst); + gelu_erf_sycl(data_pts.src, data_pts.dst, ggml_nelements(dst->src[0]), main_stream); + break; + } +#endif + case GGML_TYPE_F32: + { + auto data_pts = cast_data(dst); + gelu_erf_sycl(data_pts.src, data_pts.dst, ggml_nelements(dst->src[0]), main_stream); + break; + } + default: + GGML_ABORT("GGML tensor type not supported!\n"); + } +} + + inline void ggml_sycl_op_tanh(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { #if defined (GGML_SYCL_F16) GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32 || dst->src[0]->type == GGML_TYPE_F16); @@ -1391,146 +1446,126 @@ inline void ggml_sycl_op_acc(ggml_backend_sycl_context & ctx, ggml_tensor *dst) void ggml_sycl_sqrt(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_sqrt(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_sin(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_sin(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_cos(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_cos(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_acc(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_acc(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_gelu(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_gelu(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_silu(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_silu(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_gelu_quick(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_gelu_quick(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); +} + +void ggml_sycl_gelu_erf(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); + ggml_sycl_op_gelu_erf(ctx, dst); } void ggml_sycl_tanh(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_tanh(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_relu(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_relu(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_sigmoid(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_sigmoid(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_hardsigmoid(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_hardsigmoid(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_hardswish(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_hardswish(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } - void ggml_sycl_exp(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_exp(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_log(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_log(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_neg(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_neg(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_step(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_step(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_leaky_relu(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_leaky_relu(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_sqr(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_sqr(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_upscale(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_upscale(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_pad(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_pad(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_clamp(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_clamp(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_sgn(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_sgn(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_abs(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_abs(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } void ggml_sycl_elu(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s: DST Tensor type: %s\n", __func__, ggml_type_name(dst->type)); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_elu(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } diff --git a/ggml/src/ggml-sycl/element_wise.hpp b/ggml/src/ggml-sycl/element_wise.hpp index f4199d69da694..bd40113f09705 100644 --- a/ggml/src/ggml-sycl/element_wise.hpp +++ b/ggml/src/ggml-sycl/element_wise.hpp @@ -38,6 +38,8 @@ void ggml_sycl_silu(ggml_backend_sycl_context & ctx, ggml_tensor * dst); void ggml_sycl_gelu_quick(ggml_backend_sycl_context & ctx, ggml_tensor * dst); +void ggml_sycl_gelu_erf(ggml_backend_sycl_context & ctx, ggml_tensor * dst); + void ggml_sycl_tanh(ggml_backend_sycl_context & ctx, ggml_tensor * dst); void ggml_sycl_relu(ggml_backend_sycl_context & ctx, ggml_tensor * dst); diff --git a/ggml/src/ggml-sycl/getrows.cpp b/ggml/src/ggml-sycl/getrows.cpp index 64665be464762..4a7712781364e 100644 --- a/ggml/src/ggml-sycl/getrows.cpp +++ b/ggml/src/ggml-sycl/getrows.cpp @@ -257,8 +257,7 @@ static void get_rows_sycl_float(ggml_backend_sycl_context & ctx, const ggml_tens GGML_UNUSED(ctx); } -void ggml_sycl_op_get_rows(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - +void ggml_sycl_op_get_rows(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[1]->type == GGML_TYPE_I32); GGML_ASSERT(dst->type == GGML_TYPE_F32); @@ -308,4 +307,3 @@ void ggml_sycl_op_get_rows(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { GGML_ABORT("fatal error"); } } - diff --git a/ggml/src/ggml-sycl/ggml-sycl.cpp b/ggml/src/ggml-sycl/ggml-sycl.cpp index 5ff7fa13db0be..bcd2ea5366f76 100644 --- a/ggml/src/ggml-sycl/ggml-sycl.cpp +++ b/ggml/src/ggml-sycl/ggml-sycl.cpp @@ -346,6 +346,8 @@ static void * ggml_backend_sycl_buffer_get_base(ggml_backend_buffer_t buffer) { static enum ggml_status ggml_backend_sycl_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor, "\n"); ggml_backend_sycl_buffer_context * ctx = (ggml_backend_sycl_buffer_context *)buffer->context; if (tensor->view_src != NULL) { @@ -381,20 +383,23 @@ static void ggml_backend_sycl_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor, const void *data, size_t offset, size_t size) try { - + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); ggml_backend_sycl_buffer_context * ctx = ( ggml_backend_sycl_buffer_context *)buffer->context; ggml_sycl_set_device(ctx->device); auto stream = &(dpct::dev_mgr::instance().get_device(ctx->device).default_queue()); - SYCL_CHECK( - CHECK_TRY_ERROR(dpct::dev_mgr::instance().get_device(ctx->device).queues_wait_and_throw())); + SYCL_CHECK(CHECK_TRY_ERROR(dpct::dev_mgr::instance().get_device(ctx->device).queues_wait_and_throw())); +#ifndef _WIN32 // Note: Use host buffer to save the data from mmap(), then copy to device. It's workaround for mmap() issue on PVC GPU. // This function will be called during load model from disk. Use memory buffer replace dynamic won't save more time and brings potential memory leak risk here. - char* host_buf = (char*)malloc(size); + char * host_buf = (char *) malloc(size); memcpy(host_buf, data, size); - SYCL_CHECK( - CHECK_TRY_ERROR((*stream).memcpy((char *)tensor->data + offset, host_buf, size) - .wait())); + SYCL_CHECK(CHECK_TRY_ERROR((*stream).memcpy((char *) tensor->data + offset, host_buf, size).wait())); free(host_buf); +#else + SYCL_CHECK(CHECK_TRY_ERROR((*stream).memcpy((char *) tensor->data + offset, data, size).wait())); +#endif } catch (sycl::exception const &exc) { std::cerr << exc.what() << "Exception caught at file:" << __FILE__ @@ -406,7 +411,9 @@ static void ggml_backend_sycl_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor *tensor, void *data, size_t offset, size_t size) try { - + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); ggml_backend_sycl_buffer_context * ctx = ( ggml_backend_sycl_buffer_context *)buffer->context; ggml_sycl_set_device(ctx->device); @@ -434,7 +441,12 @@ static bool ggml_backend_sycl_buffer_cpy_tensor(ggml_backend_buffer_t buffer, const ggml_tensor *src, ggml_tensor *dst) try { - if (ggml_backend_buffer_is_sycl(src->buffer)) { + bool is_cpy_supported = ggml_backend_buffer_is_sycl(src->buffer); + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": dst=", dst); + debug_print_tensor(" src=", src); + GGML_SYCL_DEBUG(" is_cpy_supported=%d\n", is_cpy_supported); + if (is_cpy_supported) { ggml_backend_sycl_buffer_context * src_ctx = (ggml_backend_sycl_buffer_context *)src->buffer->context; ggml_backend_sycl_buffer_context * dst_ctx = (ggml_backend_sycl_buffer_context *)dst->buffer->context; @@ -491,7 +503,8 @@ ggml_backend_sycl_buffer_cpy_tensor(ggml_backend_buffer_t buffer, static void ggml_backend_sycl_buffer_clear(ggml_backend_buffer_t buffer, uint8_t value) try { - ggml_backend_sycl_buffer_context * ctx = ( ggml_backend_sycl_buffer_context *)buffer->context; + GGML_SYCL_DEBUG("[SYCL] call %s: size=%zu\n", __func__, buffer->size); + ggml_backend_sycl_buffer_context * ctx = (ggml_backend_sycl_buffer_context *) buffer->context; ggml_sycl_set_device(ctx->device); queue_ptr stream = ctx->stream; @@ -510,7 +523,9 @@ catch (sycl::exception const &exc) { static void ggml_backend_sycl_buffer_memset_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor, uint8_t value, size_t offset, size_t size) { - GGML_SYCL_DEBUG(" [SYCL] call %s\n", __func__); + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu value=%u\n", size, offset, value); ggml_backend_sycl_buffer_context * ctx = (ggml_backend_sycl_buffer_context *) buffer->context; SYCL_CHECK(ggml_sycl_set_device(ctx->device)); auto stream = &(dpct::dev_mgr::instance().get_device(ctx->device).default_queue()); @@ -788,6 +803,8 @@ static void * ggml_backend_sycl_split_buffer_get_base(ggml_backend_buffer_t buff static enum ggml_status ggml_backend_sycl_split_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor, "\n"); GGML_ASSERT(tensor->view_src == nullptr); // views of split tensors are not supported ggml_backend_sycl_split_buffer_context * ctx = (ggml_backend_sycl_split_buffer_context *)buffer->context; @@ -872,6 +889,9 @@ static void ggml_backend_sycl_split_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor, const void *data, size_t offset, size_t size) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); // split tensors must always be set in their entirety at once GGML_ASSERT(offset == 0); GGML_ASSERT(size == ggml_nbytes(tensor)); @@ -925,6 +945,9 @@ static void ggml_backend_sycl_split_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor *tensor, void *data, size_t offset, size_t size) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); // split tensors must always be set in their entirety at once GGML_ASSERT(offset == 0); GGML_ASSERT(size == ggml_nbytes(tensor)); @@ -2014,12 +2037,12 @@ inline void ggml_sycl_op_mul_mat_sycl( #else bool use_fp16 = false; #endif - if ((src0->type == GGML_TYPE_F16 || ggml_is_quantized(src0->type)) && - use_fp16 && ggml_is_contiguous(src0) && row_diff == src0->ne[1] && - dst->op_params[0] == GGML_PREC_DEFAULT) { - // GGML_SYCL_DEBUG("ggml_sycl_op_mul_mat_sycl - fp16 path\n"); + if ((src0->type == GGML_TYPE_F16 || ggml_is_quantized(src0->type)) && use_fp16 && ggml_is_contiguous(src0) && + row_diff == src0->ne[1] && dst->op_params[0] == GGML_PREC_DEFAULT) { ggml_sycl_pool_alloc src0_as_f16(ctx.pool()); if (src0->type != GGML_TYPE_F16) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp16_sycl", dst, /*num_src=*/2, + " : converting src0 to fp16"); const to_fp16_sycl_t to_fp16_sycl = ggml_get_to_fp16_sycl(src0->type, dst); GGML_ASSERT(to_fp16_sycl != nullptr); size_t ne = row_diff*ne00; @@ -2032,6 +2055,8 @@ inline void ggml_sycl_op_mul_mat_sycl( ggml_sycl_pool_alloc src1_as_f16(ctx.pool()); if (src1->type != GGML_TYPE_F16) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp16_sycl", dst, /*num_src=*/2, + " : converting src1 to fp16"); const to_fp16_sycl_t to_fp16_sycl = ggml_get_to_fp16_sycl(src1->type, dst); GGML_ASSERT(to_fp16_sycl != nullptr); size_t ne = src1_ncols*ne10; @@ -2048,6 +2073,8 @@ inline void ggml_sycl_op_mul_mat_sycl( DnnlGemmWrapper::row_gemm(ctx, src1_ncols, row_diff, ne10, src1_ptr, DnnlGemmWrapper::to_dt(), src0_ptr, DnnlGemmWrapper::to_dt(), dst_f16.get(), DnnlGemmWrapper::to_dt(), stream); + scope_op_debug_print scope_dbg_print(__func__, "/to_fp32_sycl", dst, /*num_src=*/2, + " : converting dst to fp32"); const to_fp32_sycl_t to_fp32_sycl = ggml_get_to_fp32_sycl(GGML_TYPE_F16, dst); to_fp32_sycl(dst_f16.get(), dst_dd_i, row_diff* src1_ncols, stream); } @@ -2063,21 +2090,25 @@ inline void ggml_sycl_op_mul_mat_sycl( src1_ptr, dpct::library_data_t::real_half, ne10, &beta_f16, dst_f16.get(), dpct::library_data_t::real_half, ldc, dpct::library_data_t::real_half))); + scope_op_debug_print scope_dbg_print(__func__, "/to_fp32_sycl", dst, /*num_src=*/2, + " : converting dst to fp32"); const to_fp32_sycl_t to_fp32_sycl = ggml_get_to_fp32_sycl(GGML_TYPE_F16, dst); to_fp32_sycl(dst_f16.get(), dst_dd_i, row_diff*src1_ncols, stream); } - } - else { - // GGML_SYCL_DEBUG("ggml_sycl_op_mul_mat_sycl - fp32 path\n"); + } else { ggml_sycl_pool_alloc src0_ddq_as_f32(ctx.pool()); ggml_sycl_pool_alloc src1_ddq_as_f32(ctx.pool()); if (src0->type != GGML_TYPE_F32) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp32_sycl", dst, /*num_src=*/2, + " : converting src0 to fp32"); const to_fp32_sycl_t to_fp32_sycl = ggml_get_to_fp32_sycl(src0->type, dst); GGML_ASSERT(to_fp32_sycl != nullptr); src0_ddq_as_f32.alloc(row_diff*ne00); to_fp32_sycl(src0_dd_i, src0_ddq_as_f32.get(), row_diff*ne00, stream); } if (src1->type != GGML_TYPE_F32) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp32_sycl", dst, /*num_src=*/2, + " : converting src1 to fp32"); const to_fp32_sycl_t to_fp32_sycl = ggml_get_to_fp32_sycl(src1->type, dst); GGML_ASSERT(to_fp32_sycl != nullptr); src1_ddq_as_f32.alloc(src1_ncols*ne10); @@ -2113,8 +2144,7 @@ catch (sycl::exception const &exc) { std::exit(1); } -static void ggml_sycl_op_pool2d(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - +static void ggml_sycl_op_pool2d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_F32); dpct::queue_ptr main_stream = ctx.stream(); @@ -2166,8 +2196,7 @@ inline void ggml_sycl_op_sum(ggml_backend_sycl_context & ctx, ggml_tensor *dst) sum_rows_f32_sycl(src0_dd, dst_dd, ne, 1, main_stream); } -inline void ggml_sycl_op_sum_rows(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - +inline void ggml_sycl_op_sum_rows(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_F32); dpct::queue_ptr main_stream = ctx.stream(); @@ -2198,8 +2227,7 @@ inline void ggml_sycl_op_argsort(ggml_backend_sycl_context & ctx, ggml_tensor * argsort_f32_i32_sycl(src0_dd, (int *) dst_dd, ncols, nrows, order, main_stream); } -inline void ggml_sycl_op_argmax(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - +inline void ggml_sycl_op_argmax(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_I32); @@ -2214,8 +2242,7 @@ inline void ggml_sycl_op_argmax(ggml_backend_sycl_context & ctx, ggml_tensor *ds argmax_f32_i32_sycl(src0_dd, dst_dd, ncols, nrows, main_stream); } -inline void ggml_sycl_op_diag_mask_inf(ggml_backend_sycl_context & ctx,ggml_tensor *dst) { - +inline void ggml_sycl_op_diag_mask_inf(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_F32); dpct::queue_ptr main_stream = ctx.stream(); @@ -2232,8 +2259,7 @@ inline void ggml_sycl_op_diag_mask_inf(ggml_backend_sycl_context & ctx,ggml_tens diag_mask_inf_f32_sycl(src0_dd, dst_dd, ne00, nrows0, ne01, n_past, main_stream); } -inline void ggml_sycl_op_scale(ggml_backend_sycl_context & ctx, ggml_tensor *dst) { - +inline void ggml_sycl_op_scale(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_F32); dpct::queue_ptr main_stream = ctx.stream(); @@ -2420,6 +2446,8 @@ static void ggml_sycl_op_mul_mat(ggml_backend_sycl_context & ctx, const ggml_ten dev[i].src1_ddq = dev[i].src1_ddq_alloc.alloc(ctx.pool(i), nrows1*src1_padded_col_size*q8_1_ts/q8_1_bs); if (src1_on_device && src1_is_contiguous) { + scope_op_debug_print scope_dbg_print(__func__, "/quantize_row_q8_1_sycl", dst, + /*num_src=*/2, " : converting src1 to Q8_1"); quantize_row_q8_1_sycl(dev[i].src1_ddf, dev[i].src1_ddq, ne10, nrows1, src1_padded_col_size, stream); /* DPCT1010:90: SYCL uses exceptions to report errors and does not @@ -2524,6 +2552,8 @@ static void ggml_sycl_op_mul_mat(ggml_backend_sycl_context & ctx, const ggml_ten } if (convert_src1_to_q8_1 && !src1_is_contiguous) { + scope_op_debug_print scope_dbg_print(__func__, "/quantize_row_q8_1_sycl", dst, + /*num_src=*/2, " : converting src1 to Q8_1"); quantize_row_q8_1_sycl(src1_ddf_i, src1_ddq_i, ne10, src1_ncols, src1_padded_col_size, stream); /* DPCT1010:92: SYCL uses exceptions to report errors and does @@ -2618,33 +2648,28 @@ catch (sycl::exception const &exc) { static void ggml_sycl_get_rows(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_get_rows(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } static void ggml_sycl_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_norm(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } static void ggml_sycl_rms_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_rms_norm(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } static void ggml_sycl_l2_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_l2_norm(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } static void ggml_sycl_group_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_group_norm(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } static void ggml_sycl_mul_mat_vec_p021(ggml_backend_sycl_context & ctx, const ggml_tensor *src0, @@ -2772,6 +2797,8 @@ static void ggml_sycl_mul_mat_batched_sycl(ggml_backend_sycl_context & ctx, cons // convert src1 to fp16 if (src1->type != GGML_TYPE_F16) { + scope_op_debug_print scope_dbg_print(__func__, "/to_fp16_nc_sycl", dst, /*num_src=*/2, + " : converting src1 to fp16"); const to_fp16_nc_sycl_t to_fp16_nc_sycl = get_to_fp16_nc_sycl(src1->type); GGML_ASSERT(to_fp16_nc_sycl != nullptr); const int64_t ne_src1 = ggml_nelements(src1); @@ -3027,7 +3054,7 @@ static bool should_reorder_tensor(ggml_backend_sycl_context& ctx, const ggml_ten return !g_ggml_sycl_disable_optimize && //allow optimize, controlled by $GGML_SYCL_DISABLE_OPT ctx.opt_feature.reorder && //allow this device due to good perf, skip the devices with bad perf. dst->op == GGML_OP_MUL_MAT && //limit to some supported cases of Q4_0, to do for more cases. - dst->src[1]->ne[2]==1 && dst->src[1]->ne[3]==1; + dst->src[1]->ne[1]==1 && dst->src[1]->ne[2]==1 && dst->src[1]->ne[3]==1; } static void opt_for_reorder(ggml_backend_sycl_context * ctx, const ggml_tensor * src0, const ggml_tensor * /* src1 */, @@ -3075,6 +3102,7 @@ static bool can_use_mul_mat_vec_q(const ggml_tensor * src0, const ggml_tensor * } static void ggml_sycl_mul_mat(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); const bool split = ggml_backend_buffer_is_sycl_split(src0->buffer); int64_t min_compute_capability = INT_MAX; @@ -3150,11 +3178,8 @@ static void ggml_sycl_mul_mat(ggml_backend_sycl_context & ctx, const ggml_tensor ggml_sycl_op_mul_mat(ctx, src0, src1, dst, ggml_sycl_op_mul_mat_q, convert_src1_to_q8_1); } else { constexpr bool convert_src1_to_q8_1 = false; - // MUL_MAT_SYCL supports reorder - opt_for_reorder(&ctx, src0, src1, dst, mul_mat_algo::MUL_MAT_SYCL); ggml_sycl_op_mul_mat(ctx, src0, src1, dst, ggml_sycl_op_mul_mat_sycl, convert_src1_to_q8_1); } - GGML_SYCL_DEBUG("call %s done\n", __func__); } @@ -3225,6 +3250,7 @@ __dpct_inline__ static void k_copy_dst_from_contiguous( static void ggml_sycl_mul_mat_id(ggml_backend_sycl_context & ctx, ggml_tensor *dst) try { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/3); const ggml_tensor *src0 = dst->src[0]; const ggml_tensor *src1 = dst->src[1]; GGML_ASSERT(!ggml_backend_buffer_is_sycl_split(src0->buffer) && "mul_mat_id does not support split buffers"); @@ -3393,37 +3419,45 @@ catch (sycl::exception const &exc) { } static void ggml_sycl_scale(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_scale(ctx, dst); } static void ggml_sycl_diag_mask_inf(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_diag_mask_inf(ctx, dst); } static void ggml_sycl_pool2d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); ggml_sycl_op_pool2d(ctx, dst); } static void ggml_sycl_im2col(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); ggml_sycl_op_im2col(ctx, dst); } static void ggml_sycl_sum(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); GGML_ASSERT(ggml_is_contiguous(dst->src[0])); ggml_sycl_op_sum(ctx, dst); } static void ggml_sycl_sum_rows(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); GGML_ASSERT(ggml_is_contiguous(dst->src[0])); ggml_sycl_op_sum_rows(ctx, dst); } static void ggml_sycl_argsort(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); GGML_ASSERT(ggml_is_contiguous(dst->src[0])); ggml_sycl_op_argsort(ctx, dst); } static void ggml_sycl_argmax(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); GGML_ASSERT(ggml_is_contiguous(dst->src[0])); ggml_sycl_op_argmax(ctx, dst); } @@ -3509,6 +3543,9 @@ static bool ggml_sycl_compute_forward(ggml_backend_sycl_context & ctx, struct gg case GGML_UNARY_OP_GELU_QUICK: ggml_sycl_gelu_quick(ctx, dst); break; + case GGML_UNARY_OP_GELU_ERF: + ggml_sycl_gelu_erf(ctx, dst); + break; case GGML_UNARY_OP_TANH: ggml_sycl_tanh(ctx, dst); break; @@ -3717,6 +3754,9 @@ static void ggml_backend_sycl_set_tensor_async(ggml_backend_t backend, ggml_tensor *tensor, const void *data, size_t offset, size_t size) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); ggml_backend_sycl_context * sycl_ctx = (ggml_backend_sycl_context *)backend->context; ggml_backend_buffer_t buf = tensor->view_src ? tensor->view_src->buffer : tensor->buffer; @@ -3735,13 +3775,16 @@ static void ggml_backend_sycl_get_tensor_async(ggml_backend_t backend, const ggml_tensor *tensor, void *data, size_t offset, size_t size) try { + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": tensor=", tensor); + GGML_SYCL_DEBUG(" size=%zu offset=%zu\n", size, offset); ggml_backend_sycl_context * sycl_ctx = (ggml_backend_sycl_context *)backend->context; ggml_backend_buffer_t buf = tensor->view_src ? tensor->view_src->buffer : tensor->buffer; GGML_ASSERT(buf->buft == ggml_backend_sycl_buffer_type(sycl_ctx->device) && "unsupported buffer type"); const queue_ptr stream = sycl_ctx->stream(sycl_ctx->device, 0); SYCL_CHECK(CHECK_TRY_ERROR((stream)->memcpy( - data, (const char *)tensor->data + offset, size).wait())); + data, (const char *)tensor->data + offset, size))); } catch (sycl::exception const &exc) { std::cerr << exc.what() << "Exception caught at file:" << __FILE__ @@ -3753,7 +3796,13 @@ static bool ggml_backend_sycl_cpy_tensor_async(ggml_backend_t backend, const ggml_tensor *src, ggml_tensor *dst) try { ggml_backend_sycl_context * sycl_ctx = (ggml_backend_sycl_context *)backend->context; - if (dst->buffer->buft == ggml_backend_sycl_buffer_type(sycl_ctx->device) && ggml_backend_buffer_is_sycl(src->buffer)) { + bool is_cpy_supported = dst->buffer->buft == ggml_backend_sycl_buffer_type(sycl_ctx->device) && + ggml_backend_buffer_is_sycl(src->buffer); + GGML_SYCL_DEBUG("[SYCL] call %s", __func__); + debug_print_tensor(": dst=", dst); + debug_print_tensor(" src=", src); + GGML_SYCL_DEBUG(" is_cpy_supported=%d\n", is_cpy_supported); + if (is_cpy_supported) { /* DPCT1009:215: SYCL uses exceptions to report errors and does not use the error codes. The original code was commented out and a warning string @@ -3761,7 +3810,7 @@ static bool ggml_backend_sycl_cpy_tensor_async(ggml_backend_t backend, */ const queue_ptr stream = sycl_ctx->stream(sycl_ctx->device, 0); SYCL_CHECK(CHECK_TRY_ERROR((stream)->memcpy( - dst->data, src->data, ggml_nbytes(dst)).wait())); + dst->data, src->data, ggml_nbytes(dst)))); return true; } @@ -3774,6 +3823,7 @@ catch (sycl::exception const &exc) { } static void ggml_backend_sycl_synchronize(ggml_backend_t backend) try { + GGML_SYCL_DEBUG("[SYCL] call %s\n", __func__); ggml_backend_sycl_context * sycl_ctx = (ggml_backend_sycl_context *)backend->context; const queue_ptr stream = sycl_ctx->stream(sycl_ctx->device, 0); SYCL_CHECK(CHECK_TRY_ERROR((stream)->wait())); @@ -3810,11 +3860,43 @@ static void ggml_backend_sycl_graph_compute_impl(ggml_backend_sycl_context * syc } } +#ifdef GGML_SYCL_GRAPH +static bool check_graph_compatibility(ggml_cgraph * cgraph) { + if (ggml_sycl_info().device_count > 1) { + // A sycl_ex::command_graph object can only be created for a single device + GGML_LOG_INFO("%s: disabling SYCL graphs due to multiple devices\n", __func__); + return false; + } + + for (int i = 0; i < cgraph->n_nodes; i++) { + const ggml_op node_op = cgraph->nodes[i]->op; + switch (node_op) { + default: + break; + case GGML_OP_CONCAT: + // ggml_sycl_op_concat() does a blocking host wait after memcpy operations, + // but wait() can't be called on the events returned by a queue recording + // to a graph. + [[fallthrough]]; + case GGML_OP_MUL_MAT_ID: + // ggml_sycl_mul_mat_id() does a blocking host wait on the sycl queue after + // submitting a memcpy operation, but wait() can't be called on a queue that + // is recording to a graph. + GGML_LOG_INFO("%s: disabling SYCL graphs due to unsupported node type %s\n", __func__, + ggml_op_name(node_op)); + return false; + } + } + return true; +} +#endif + static ggml_status ggml_backend_sycl_graph_compute(ggml_backend_t backend, ggml_cgraph * cgraph) { auto * sycl_ctx = static_cast(backend->context); #ifdef GGML_SYCL_GRAPH - if (!g_ggml_sycl_disable_graph) { + bool use_sycl_graph = !g_ggml_sycl_disable_graph && check_graph_compatibility(cgraph); + if (use_sycl_graph) { const bool graph_support = dpct::get_device(sycl_ctx->device).has(sycl::aspect::ext_oneapi_limited_graph); if (!graph_support) { GGML_SYCL_DEBUG("[SYCL-GRAPH] can not use graphs on device:%d\n", sycl_ctx->device); @@ -3875,7 +3957,7 @@ catch (sycl::exception const &exc) } static void ggml_backend_sycl_event_wait(ggml_backend_t backend, ggml_backend_event_t event) try { - + GGML_SYCL_DEBUG("[SYCL] call %s\n", __func__); sycl::event* sycl_event = static_cast(event->context); if (ggml_backend_is_sycl(backend)) { @@ -4017,6 +4099,7 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g case GGML_UNARY_OP_HARDSIGMOID: case GGML_UNARY_OP_HARDSWISH: case GGML_UNARY_OP_GELU_QUICK: + case GGML_UNARY_OP_GELU_ERF: case GGML_UNARY_OP_TANH: case GGML_UNARY_OP_EXP: case GGML_UNARY_OP_SGN: @@ -4162,6 +4245,7 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g #endif case GGML_OP_NORM: case GGML_OP_RMS_NORM: + return true; case GGML_OP_L2_NORM: case GGML_OP_GROUP_NORM: return ggml_is_contiguous(op->src[0]); @@ -4173,14 +4257,6 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g case GGML_OP_SOFT_MAX: return true; case GGML_OP_ROPE: - { - const int mode = ((const int32_t *) op->op_params)[2]; - // mode is not used as a bitmask in practice, the various rope type modes are independent implementations - if (mode == GGML_ROPE_TYPE_MROPE) { - return false; - } - return true; - } case GGML_OP_IM2COL: return true; case GGML_OP_UPSCALE: @@ -4270,6 +4346,7 @@ static void ggml_backend_sycl_device_event_free(ggml_backend_dev_t dev, ggml_bac static void ggml_backend_sycl_device_event_synchronize(ggml_backend_dev_t dev, ggml_backend_event_t event) try { GGML_UNUSED(dev); + GGML_SYCL_DEBUG("[SYCL] call %s\n", __func__); sycl::event *sycl_event = static_cast(event->context); SYCL_CHECK(CHECK_TRY_ERROR(sycl_event->wait())); diff --git a/ggml/src/ggml-sycl/gla.cpp b/ggml/src/ggml-sycl/gla.cpp index eedb47486430a..879184fdd3111 100644 --- a/ggml/src/ggml-sycl/gla.cpp +++ b/ggml/src/ggml-sycl/gla.cpp @@ -76,6 +76,7 @@ static void gated_linear_attn_f32_kernel(const dpct::queue_ptr stream, u_int B, } void ggml_sycl_op_gated_linear_attn(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/5); const float * k_d = static_cast(dst->src[0]->data); const float * v_d = static_cast(dst->src[1]->data); const float * r_d = static_cast(dst->src[2]->data); diff --git a/ggml/src/ggml-sycl/mmvq.cpp b/ggml/src/ggml-sycl/mmvq.cpp index 23eeb74da0d84..cb70f83a4f9a6 100644 --- a/ggml/src/ggml-sycl/mmvq.cpp +++ b/ggml/src/ggml-sycl/mmvq.cpp @@ -1059,8 +1059,10 @@ void ggml_sycl_op_mul_mat_vec_q(ggml_backend_sycl_context & ctx, const ggml_tens case GGML_TYPE_Q4_K: if ((ggml_tensor_extra_gpu *) dst->src[0]->extra && ((ggml_tensor_extra_gpu *) dst->src[0]->extra)->optimized_feature.reorder) { + GGML_SYCL_DEBUG("Calling reorder_mul_mat_vec_q4_k_q8_1_sycl\n"); reorder_mul_mat_vec_q4_k_q8_1_sycl(src0_dd_i, src1_ddq_i_bs, dst_dd_i_bs, ne00, row_diff, stream); } else { + GGML_SYCL_DEBUG("Calling mul_mat_vec_q4_K_q8_1_sycl\n"); mul_mat_vec_q4_K_q8_1_sycl(src0_dd_i, src1_ddq_i_bs, dst_dd_i_bs, ne00, row_diff, stream); } break; diff --git a/ggml/src/ggml-sycl/norm.cpp b/ggml/src/ggml-sycl/norm.cpp index 4e9f438b46ba6..4ec1416849c7e 100644 --- a/ggml/src/ggml-sycl/norm.cpp +++ b/ggml/src/ggml-sycl/norm.cpp @@ -1,40 +1,50 @@ #include "norm.hpp" +#include "ggml-sycl/common.hpp" +#include "ggml-sycl/presets.hpp" -static void norm_f32(const float* x, float* dst, const int ncols, const float eps, - const sycl::nd_item<3>& item_ct1, sycl::float2* s_sum, int block_size) { - const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) + - item_ct1.get_local_id(1); - const int tid = item_ct1.get_local_id(2); +static void norm_f32(const float* x, float* dst, const int ncols, const int64_t stride_row, const int64_t stride_channel, + const int64_t stride_sample, const float eps, const sycl::nd_item<3>& item_ct1, sycl::float2* s_sum, int block_size) { + + const int nrows = item_ct1.get_group_range(2); + const int nchannels = item_ct1.get_group_range(1); const int nthreads = item_ct1.get_local_range(2); + const int sample = item_ct1.get_group(0); + const int channel = item_ct1.get_group(1); + const int row = item_ct1.get_group(2); + + const int tid = item_ct1.get_local_id(2); const int nwarps = nthreads / WARP_SIZE; + + const auto strided_offset = calculate_offset<3>({stride_sample, stride_channel, stride_row}, {sample, channel, row}); + const auto packed_offset = calculate_offset<3>({nchannels * nrows * ncols, nrows * ncols, ncols}, {sample, channel, row}); + + x += strided_offset; + dst += packed_offset; + sycl::float2 mean_var = sycl::float2(0.f, 0.f); for (int col = tid; col < ncols; col += block_size) { - const float xi = x[row * ncols + col]; + const float xi = x[col]; mean_var.x() += xi; mean_var.y() += xi * xi; } // sum up partial sums mean_var = warp_reduce_sum(mean_var, item_ct1); - if (block_size > WARP_SIZE) { - - int warp_id = item_ct1.get_local_id(2) / WARP_SIZE; - int lane_id = item_ct1.get_local_id(2) % WARP_SIZE; - if (lane_id == 0) { - s_sum[warp_id] = mean_var; + if (block_size > WARP_SIZE) { + const auto sub_group = item_ct1.get_sub_group(); + const auto sg_id = sub_group.get_group_linear_id(); + const auto wi_in_sg = sub_group.get_local_linear_id(); + if (wi_in_sg == 0) { + s_sum[sg_id] = mean_var; } - /* - DPCT1118:0: SYCL group functions and algorithms must be encountered in - converged control flow. You may need to adjust the code. - */ item_ct1.barrier(sycl::access::fence_space::local_space); mean_var = 0.f; - size_t nreduce = nwarps / WARP_SIZE; + const size_t nreduce = ceil_div(nwarps, WARP_SIZE); for (size_t i = 0; i < nreduce; i += 1) { - mean_var += s_sum[lane_id + i * WARP_SIZE]; + mean_var += s_sum[wi_in_sg + i * WARP_SIZE]; } mean_var = warp_reduce_sum(mean_var, item_ct1); } @@ -44,7 +54,7 @@ static void norm_f32(const float* x, float* dst, const int ncols, const float ep const float inv_std = sycl::rsqrt(var + eps); for (int col = tid; col < ncols; col += block_size) { - dst[row * ncols + col] = (x[row * ncols + col] - mean) * inv_std; + dst[col] = (x[col] - mean) * inv_std; } } @@ -135,39 +145,51 @@ static void group_norm_f32(const float* x, float* dst, const int group_size, con } } -static void rms_norm_f32(const float* x, float* dst, const int ncols, const float eps, - const sycl::nd_item<3>& item_ct1, float* s_sum, int block_size) { - const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) + - item_ct1.get_local_id(1); - const int tid = item_ct1.get_local_id(2); +static void rms_norm_f32(const float* x, float* dst, const int ncols, const int64_t stride_row, const int64_t stride_channel, + const int64_t stride_sample, const float eps, const sycl::nd_item<3>& item_ct1, float* s_sum, int block_size) { + + const int nrows = item_ct1.get_group_range(2); + const int nchannels = item_ct1.get_group_range(1); + + const int sample = item_ct1.get_group(0); + const int channel = item_ct1.get_group(1); + const int row = item_ct1.get_group(2); + const int nthreads = item_ct1.get_local_range(2); + + const int tid = item_ct1.get_local_id(2); const int nwarps = nthreads / WARP_SIZE; + + const auto strided_offset = calculate_offset<3>({stride_sample, stride_channel, stride_row}, {sample, channel, row}); + const auto packed_offset = calculate_offset<3>({nchannels * nrows * ncols, nrows * ncols, ncols}, {sample, channel, row}); + + x += strided_offset; + dst += packed_offset; + + float tmp = 0.0f; // partial sum for thread in warp for (int col = tid; col < ncols; col += block_size) { - const float xi = x[row * ncols + col]; + const float xi = x[col]; tmp += xi * xi; } // sum up partial sums tmp = warp_reduce_sum(tmp, item_ct1); if (block_size > WARP_SIZE) { - - int warp_id = item_ct1.get_local_id(2) / WARP_SIZE; - int lane_id = item_ct1.get_local_id(2) % WARP_SIZE; - if (lane_id == 0) { - s_sum[warp_id] = tmp; + const auto sub_group = item_ct1.get_sub_group(); + const auto sg_id = sub_group.get_group_linear_id(); + const auto wi_in_sg = sub_group.get_local_linear_id(); + if (wi_in_sg == 0) { + s_sum[sg_id] = tmp; } - /* - DPCT1118:3: SYCL group functions and algorithms must be encountered in - converged control flow. You may need to adjust the code. - */ + item_ct1.barrier(sycl::access::fence_space::local_space); - size_t nreduce = nwarps / WARP_SIZE; + const size_t nreduce = ceil_div(nwarps, WARP_SIZE); tmp = 0.f; for (size_t i = 0; i < nreduce; i += 1) { - tmp += s_sum[lane_id + i * WARP_SIZE]; + tmp += s_sum[wi_in_sg + i * WARP_SIZE]; } tmp = warp_reduce_sum(tmp, item_ct1); } @@ -176,7 +198,7 @@ static void rms_norm_f32(const float* x, float* dst, const int ncols, const floa const float scale = sycl::rsqrt(mean + eps); for (int col = tid; col < ncols; col += block_size) { - dst[row * ncols + col] = scale * x[row * ncols + col]; + dst[col] = scale * x[col]; } } @@ -224,20 +246,20 @@ static void l2_norm_f32(const float* x, float* dst, const int ncols, const float } } -static void norm_f32_sycl(const float* x, float* dst, const int ncols, - const int nrows, const float eps, - queue_ptr stream, int device) { +static void norm_f32_sycl(const float * x, float * dst, const int ncols, const int nrows, const int nchannels, const int nsamples, + const int64_t stride_row, const int64_t stride_channel, const int64_t stride_sample, + const float eps, queue_ptr stream, int device) { + + const sycl::range<3> global_dims(nsamples, nchannels, nrows); GGML_ASSERT(ncols % WARP_SIZE == 0); if (ncols < 1024) { const sycl::range<3> block_dims(1, 1, WARP_SIZE); stream->submit([&](sycl::handler& cgh) { cgh.parallel_for( - sycl::nd_range<3>(sycl::range<3>(1, 1, nrows) * block_dims, - block_dims), + sycl::nd_range<3>(global_dims * block_dims, block_dims), [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] { - norm_f32(x, dst, ncols, eps, item_ct1, - nullptr, WARP_SIZE); + norm_f32(x, dst, ncols, stride_row, stride_channel, stride_sample, eps, item_ct1, nullptr, WARP_SIZE); }); }); } @@ -252,15 +274,12 @@ static void norm_f32_sycl(const float* x, float* dst, const int ncols, */ stream->submit([&](sycl::handler& cgh) { sycl::local_accessor s_sum_acc_ct1( - sycl::range<1>(work_group_size / WARP_SIZE), cgh); - + sycl::range<1>(work_group_size / WARP_SIZE), cgh); cgh.parallel_for( - sycl::nd_range<3>(sycl::range<3>(1, 1, nrows) * block_dims, - block_dims), + sycl::nd_range<3>(global_dims * block_dims, block_dims), [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] { - norm_f32(x, dst, ncols, eps, item_ct1, - get_pointer(s_sum_acc_ct1), work_group_size); + norm_f32(x, dst, ncols, stride_row, stride_channel, stride_sample, eps, item_ct1, get_pointer(s_sum_acc_ct1), work_group_size); }); }); } @@ -313,21 +332,20 @@ static void group_norm_f32_sycl(const float* x, float* dst, } } -static void rms_norm_f32_sycl(const float* x, float* dst, const int ncols, - const int nrows, const float eps, - queue_ptr stream, int device) { +static void rms_norm_f32_sycl(const float* x, float* dst, const int ncols, const int nrows, const int nchannels, const int nsamples, + const int64_t stride_row, const int64_t stride_channel, const int64_t stride_sample, const float eps, queue_ptr stream, int device) { GGML_ASSERT(ncols % WARP_SIZE == 0); // printf("%s ncols=%d, nrows=%d, WARP_SIZE=%d\n", __func__, ncols, nrows, WARP_SIZE); + + const sycl::range<3> global_dims(nsamples, nchannels, nrows); if (ncols < 1024) { const sycl::range<3> block_dims(1, 1, WARP_SIZE); stream->submit([&](sycl::handler& cgh) { cgh.parallel_for( - sycl::nd_range<3>(sycl::range<3>(1, 1, nrows) * block_dims, - block_dims), + sycl::nd_range<3>(global_dims * block_dims, block_dims), [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] { - rms_norm_f32(x, dst, ncols, eps, item_ct1, - nullptr, WARP_SIZE); + rms_norm_f32(x, dst, ncols, stride_row, stride_channel, stride_sample, eps, item_ct1, nullptr, WARP_SIZE); }); }); } @@ -344,12 +362,10 @@ static void rms_norm_f32_sycl(const float* x, float* dst, const int ncols, sycl::local_accessor s_sum_acc_ct1(sycl::range<1>(work_group_size / WARP_SIZE), cgh); cgh.parallel_for( - sycl::nd_range<3>(sycl::range<3>(1, 1, nrows) * block_dims, - block_dims), + sycl::nd_range<3>(global_dims * block_dims, block_dims), [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] { - rms_norm_f32(x, dst, ncols, eps, item_ct1, - get_pointer(s_sum_acc_ct1), work_group_size); + rms_norm_f32(x, dst, ncols, stride_row, stride_channel, stride_sample, eps, item_ct1, get_pointer(s_sum_acc_ct1), work_group_size); }); }); } @@ -398,12 +414,12 @@ static void l2_norm_f32_sycl(const float* x, float* dst, const int ncols, } void ggml_sycl_op_norm(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { + const ggml_tensor * src0 = dst->src[0]; GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT(dst->type == GGML_TYPE_F32); - const int64_t ne00 = dst->src[0]->ne[0]; - const int64_t nrows = ggml_nrows(dst->src[0]); + GGML_TENSOR_UNARY_OP_LOCALS dpct::queue_ptr main_stream = ctx.stream(); SYCL_CHECK(ggml_sycl_set_device(ctx.device)); const float * src0_dd = static_cast(dst->src[0]->data); @@ -411,8 +427,14 @@ void ggml_sycl_op_norm(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { float eps; memcpy(&eps, dst->op_params, sizeof(float)); - - norm_f32_sycl(src0_dd, dst_dd, ne00, nrows, eps, main_stream, ctx.device); + GGML_ASSERT(eps >= 0.0f); + const size_t ts0 = ggml_type_size(src0->type); + GGML_ASSERT(nb00 == ts0); + const int64_t s01 = nb01 / ts0; + const int64_t s02 = nb02 / ts0; + const int64_t s03 = nb03 / ts0; + + norm_f32_sycl(src0_dd, dst_dd, ne00, ne01, ne02, ne03, s01, s02, s03, eps, main_stream, ctx.device); } void ggml_sycl_op_group_norm(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { @@ -436,11 +458,10 @@ void ggml_sycl_op_group_norm(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { void ggml_sycl_op_rms_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { + const ggml_tensor * src0 = dst->src[0]; GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT(dst->type == GGML_TYPE_F32); - const int64_t ne00 = dst->src[0]->ne[0]; - const int64_t nrows = ggml_nrows(dst->src[0]); dpct::queue_ptr main_stream = ctx.stream(); SYCL_CHECK(ggml_sycl_set_device(ctx.device)); @@ -450,7 +471,13 @@ void ggml_sycl_op_rms_norm(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { float eps; memcpy(&eps, dst->op_params, sizeof(float)); - rms_norm_f32_sycl(src0_dd, dst_dd, ne00, nrows, eps, main_stream, ctx.device); + GGML_TENSOR_UNARY_OP_LOCALS + const size_t ts0 = ggml_type_size(src0->type); + GGML_ASSERT(nb00 == ts0); + const int64_t s01 = nb01 / ts0; + const int64_t s02 = nb02 / ts0; + const int64_t s03 = nb03 / ts0; + rms_norm_f32_sycl(src0_dd, dst_dd, ne00, ne01, ne02, ne03, s01, s02, s03, eps, main_stream, ctx.device); } void ggml_sycl_op_l2_norm(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { diff --git a/ggml/src/ggml-sycl/outprod.cpp b/ggml/src/ggml-sycl/outprod.cpp index b60415784f32d..3a17f3a1b88ab 100644 --- a/ggml/src/ggml-sycl/outprod.cpp +++ b/ggml/src/ggml-sycl/outprod.cpp @@ -1,6 +1,7 @@ #include "outprod.hpp" void ggml_sycl_op_out_prod(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); const ggml_tensor *src0 = dst->src[0]; const ggml_tensor *src1 = dst->src[1]; diff --git a/ggml/src/ggml-sycl/rope.cpp b/ggml/src/ggml-sycl/rope.cpp index 4e276d3b62e42..44473e1e5580c 100644 --- a/ggml/src/ggml-sycl/rope.cpp +++ b/ggml/src/ggml-sycl/rope.cpp @@ -49,10 +49,7 @@ static void rope_norm(const T * x, T * dst, const int ne0, const int ne1, const if (i0 >= n_dims) { const int i = row * ne0 + i0; - - dst[i + 0] = x[i + 0]; - dst[i + 1] = x[i + 1]; - + *reinterpret_cast *>(dst + i) = *reinterpret_cast *>(x + i); return; } @@ -93,10 +90,7 @@ static void rope_neox(const T * x, T * dst, const int ne0, const int ne1, const if (i0 >= n_dims) { const int i = row * ne0 + i0; - - dst[i + 0] = x[i + 0]; - dst[i + 1] = x[i + 1]; - + *reinterpret_cast *>(dst + i) = *reinterpret_cast *>(x + i); return; } @@ -122,6 +116,63 @@ static void rope_neox(const T * x, T * dst, const int ne0, const int ne1, const dst[i + n_dims / 2] = x0 * sin_theta + x1 * cos_theta; } +template +static void rope_multi(const T * x, T * dst, const int ne0, const int ne1, const int ne2, const size_t s1, + const size_t s2, const int n_dims, const int32_t * pos, const float freq_scale, + const float ext_factor, const float attn_factor, const rope_corr_dims corr_dims, + const float theta_scale, const float * freq_factors, const mrope_sections sections, + const sycl::nd_item<3> & item_ct1) { + // get index pos + const int i0 = 2 * (item_ct1.get_group(1) * item_ct1.get_local_range(1) + item_ct1.get_local_id(1)); + if (i0 >= ne0) { + return; + } + const int row_dst = (item_ct1.get_group(2) * item_ct1.get_local_range(2)) + item_ct1.get_local_id(2); + + if (i0 >= n_dims) { + const int i = row_dst*ne0 + i0; + *reinterpret_cast *>(dst + i) = *reinterpret_cast *>(x + i); + return; + } + + const int row_x = row_dst % ne1; + const int channel_x = row_dst / ne1; + const int idst = (row_dst * ne0) + (i0 / 2); + const size_t ix = ((size_t) channel_x * s2) + ((size_t) row_x * s1) + (i0 / 2); + + const int sect_dims = sections.v[0] + sections.v[1] + sections.v[2] + sections.v[3]; + const int sec_w = sections.v[1] + sections.v[0]; + const int sector = (i0 / 2) % sect_dims; + + + float theta_base = 0.0; + if (sector < sections.v[0]) { + theta_base = pos[channel_x]*sycl::pow(theta_scale, i0/2.0f); + } + else if (sector >= sections.v[0] && sector < sec_w) { + theta_base = pos[channel_x + ne2 * 1]*sycl::pow(theta_scale, i0/2.0f); + } + else if (sector >= sec_w && sector < sec_w + sections.v[2]) { + theta_base = pos[channel_x + ne2 * 2]*sycl::pow(theta_scale, i0/2.0f); + } + else if (sector >= sec_w + sections.v[2]) { + theta_base = pos[channel_x + ne2 * 3]*sycl::pow(theta_scale, i0/2.0f); + } + + const float freq_factor = has_ff ? freq_factors[i0 / 2] : 1.0f; + float cos_theta; + float sin_theta; + rope_yarn(theta_base / freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor, &cos_theta, &sin_theta); + const float x0 = x[ix + 0]; + const float x1 = x[ix + n_dims/2]; + + // store results in dst + dst[idst + 0] = x0 * cos_theta - x1 * sin_theta; + dst[idst + n_dims/2] = x0 * sin_theta + x1 * cos_theta; +} + + + template static void rope_vision(const T * x, T * dst, const int ne0, const int ne1, const int ne2, const size_t s1, const size_t s2, const int n_dims, const int32_t * pos, const float freq_scale, @@ -171,7 +222,7 @@ static void rope_norm_sycl(const T * x, T * dst, const int ne0, const int ne1, c const float * freq_factors, queue_ptr stream) { GGML_ASSERT(ne0 % 2 == 0); const sycl::range<3> block_dims(1, SYCL_ROPE_BLOCK_SIZE, 1); - const int num_blocks_x = (ne0 + 2 * SYCL_ROPE_BLOCK_SIZE - 1) / (2 * SYCL_ROPE_BLOCK_SIZE); + const int num_blocks_x = ceil_div(ne0, (2 * SYCL_ROPE_BLOCK_SIZE)); const sycl::range<3> block_nums(1, num_blocks_x, nr); const float theta_scale = powf(freq_base, -2.0f / n_dims); @@ -208,7 +259,7 @@ static void rope_neox_sycl(const T * x, T * dst, const int ne0, const int ne1, c const rope_corr_dims corr_dims, const float * freq_factors, queue_ptr stream) { GGML_ASSERT(ne0 % 2 == 0); const sycl::range<3> block_dims(1, SYCL_ROPE_BLOCK_SIZE, 1); - const int num_blocks_x = (ne0 + 2 * SYCL_ROPE_BLOCK_SIZE - 1) / (2 * SYCL_ROPE_BLOCK_SIZE); + const int num_blocks_x = ceil_div(ne0, (2 * SYCL_ROPE_BLOCK_SIZE)); const sycl::range<3> block_nums(1, num_blocks_x, nr); const float theta_scale = powf(freq_base, -2.0f / n_dims); @@ -228,6 +279,40 @@ static void rope_neox_sycl(const T * x, T * dst, const int ne0, const int ne1, c } } +template +static void rope_multi_sycl(const T * x, T * dst, const int ne0, const int ne1, const int ne2, const size_t s1, + const size_t s2, const int n_dims, const int nr, const int32_t * pos, + const float freq_scale, const float freq_base, const float ext_factor, + const float attn_factor, const rope_corr_dims corr_dims, const float * freq_factors, + const mrope_sections sections, queue_ptr stream) { + GGML_ASSERT(ne0 % 2 == 0); + const sycl::range<3> block_dims(1, SYCL_ROPE_BLOCK_SIZE, 1); + const int n_blocks_y = ceil_div(ne0, (2 * SYCL_ROPE_BLOCK_SIZE)); + const sycl::range<3> grid_dims(1, n_blocks_y, nr); + const sycl::nd_range<3> nd_range(grid_dims * block_dims, block_dims); + + const float theta_scale = std::pow(freq_base, -2.0f / n_dims); + // Add FP16 capability check if T could be sycl::half + if constexpr (std::is_same_v) { + dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 }); + } + // launch kernel + if (freq_factors == nullptr) { + stream->parallel_for(nd_range, [=](sycl::nd_item<3> item_ct1) { + rope_multi(x, dst, ne0, ne1, ne2, s1, s2, n_dims, pos, freq_scale, ext_factor, attn_factor, + corr_dims, theta_scale, freq_factors, sections, item_ct1); + }); + } else { + stream->parallel_for(nd_range, [=](sycl::nd_item<3> item_ct1) { + rope_multi(x, dst, ne0, ne1, ne2, s1, s2, n_dims, pos, freq_scale, ext_factor, attn_factor, + corr_dims, theta_scale, freq_factors, sections, item_ct1); + }); + } +} + + + + // rope vision template static void rope_vision_sycl(const T * x, T * dst, const int ne0, const int ne1, const int ne2, const size_t s1, @@ -237,7 +322,7 @@ static void rope_vision_sycl(const T * x, T * dst, const int ne0, const int ne1, const mrope_sections sections, queue_ptr stream) { GGML_ASSERT(ne0 % 2 == 0); const sycl::range<3> block_dims(1, SYCL_ROPE_BLOCK_SIZE, 1); - const int n_blocks_y = (ne0 + 2 * SYCL_ROPE_BLOCK_SIZE - 1) / (2 * SYCL_ROPE_BLOCK_SIZE); + const int n_blocks_y = ceil_div(ne0, (2 * SYCL_ROPE_BLOCK_SIZE)); const sycl::range<3> grid_dims(1, n_blocks_y, nr); const sycl::nd_range<3> nd_range(grid_dims * block_dims, block_dims); @@ -298,8 +383,17 @@ inline void ggml_sycl_op_rope(ggml_backend_sycl_context & ctx, ggml_tensor *dst) memcpy(§ions.v, (int32_t *) dst->op_params + 11, sizeof(int)*4); const bool is_neox = mode & GGML_ROPE_TYPE_NEOX; + const bool is_mrope = mode & GGML_ROPE_TYPE_MROPE; const bool is_vision = mode == GGML_ROPE_TYPE_VISION; + if (is_mrope) { + GGML_ASSERT(sections.v[0] > 0 || sections.v[1] > 0 || sections.v[2] > 0); + } + + if (is_vision) { + GGML_ASSERT(n_dims == ne00/2); + } + const int32_t * pos = (const int32_t *) dst->src[1]->data; const float * freq_factors = nullptr; @@ -326,6 +420,19 @@ inline void ggml_sycl_op_rope(ggml_backend_sycl_context & ctx, ggml_tensor *dst) } else { GGML_ABORT("fatal error"); } + } else if (is_mrope && !is_vision) { + GGML_SYCL_DEBUG("%s: mrope path\n", __func__); + if (dst->src[0]->type == GGML_TYPE_F16) { + rope_multi_sycl((const sycl::half *)dst->src[0]->data, (sycl::half *)dst->data, ne00, ne01, ne02, s01, + s02, n_dims, nr, pos, freq_scale, freq_base, ext_factor, attn_factor, corr_dims, + freq_factors, sections, main_stream); + } else if (dst->src[0]->type == GGML_TYPE_F32) { + rope_multi_sycl((const float *) dst->src[0]->data, (float *) dst->data, ne00, ne01, ne02, s01, s02, n_dims, + nr, pos, freq_scale, freq_base, ext_factor, attn_factor, corr_dims, freq_factors, sections, + main_stream); + } else { + GGML_ABORT("Fatal error: Tensor type unsupported!"); + } } else if (is_vision) { GGML_SYCL_DEBUG("%s: vision path\n", __func__); if (dst->src[0]->type == GGML_TYPE_F16) { @@ -355,8 +462,7 @@ inline void ggml_sycl_op_rope(ggml_backend_sycl_context & ctx, ggml_tensor *dst) } void ggml_sycl_rope(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - GGML_SYCL_DEBUG("call %s\n", __func__); + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/3); ggml_sycl_op_rope(ctx, dst); - GGML_SYCL_DEBUG("call %s done\n", __func__); } diff --git a/ggml/src/ggml-sycl/softmax.cpp b/ggml/src/ggml-sycl/softmax.cpp index 7563d9ceda654..52fcf4b3dbd24 100644 --- a/ggml/src/ggml-sycl/softmax.cpp +++ b/ggml/src/ggml-sycl/softmax.cpp @@ -225,7 +225,7 @@ static void soft_max_f32_sycl(const float * x, const T * mask, } void ggml_sycl_op_soft_max(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2); GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32); GGML_ASSERT( dst->type == GGML_TYPE_F32); @@ -249,16 +249,13 @@ void ggml_sycl_op_soft_max(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { if (dst->src[1] && dst->src[1]->type == GGML_TYPE_F16) { const sycl::half * src1_dd = static_cast(dst->src[1]->data); - GGML_SYCL_DEBUG("%s: F16 mask\n", __func__); soft_max_f32_sycl(src0_dd, src1_dd, dst_dd, ne00, nrows_x, nrows_y, scale, max_bias, main_stream, ctx.device); } else if (dst->src[1] && dst->src[1]->type == GGML_TYPE_F32) { const float * src1_dd = static_cast(dst->src[1]->data); - GGML_SYCL_DEBUG("%s: F32 mask\n", __func__); soft_max_f32_sycl(src0_dd, src1_dd, dst_dd, ne00, nrows_x, nrows_y, scale, max_bias, main_stream, ctx.device); } else { /* mask unavailable */ - GGML_SYCL_DEBUG("%s: No mask\n", __func__); soft_max_f32_sycl(src0_dd, nullptr, dst_dd, ne00, nrows_x, nrows_y, scale, max_bias, main_stream, ctx.device); } } diff --git a/ggml/src/ggml-sycl/tsembd.cpp b/ggml/src/ggml-sycl/tsembd.cpp index b877d18c1730a..f6ca626ea7a53 100644 --- a/ggml/src/ggml-sycl/tsembd.cpp +++ b/ggml/src/ggml-sycl/tsembd.cpp @@ -56,8 +56,8 @@ static void timestep_embedding_f32_sycl( } void ggml_sycl_op_timestep_embedding(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { - const ggml_tensor *src0 = dst->src[0]; - const ggml_tensor *src1 = dst->src[1]; + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1); + const ggml_tensor * src0 = dst->src[0]; const float * src0_d = (const float *)src0->data; float * dst_d = (float *)dst->data; dpct::queue_ptr stream = ctx.stream(); @@ -69,5 +69,4 @@ void ggml_sycl_op_timestep_embedding(ggml_backend_sycl_context & ctx, ggml_tenso const int max_period = dst->op_params[1]; timestep_embedding_f32_sycl(src0_d, dst_d, src0->ne[0], dst->nb[1], dim, max_period, stream); - GGML_UNUSED(src1); } diff --git a/ggml/src/ggml-sycl/wkv.cpp b/ggml/src/ggml-sycl/wkv.cpp index 540f6fbf5f0d9..c10e2f7645e89 100644 --- a/ggml/src/ggml-sycl/wkv.cpp +++ b/ggml/src/ggml-sycl/wkv.cpp @@ -180,10 +180,7 @@ static void rwkv_wkv7_f32_kernel( } void ggml_sycl_op_rwkv_wkv6(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { - - const ggml_tensor *src0 = dst->src[0]; - const ggml_tensor *src1 = dst->src[1]; - + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/6); const float* k_d = (const float*)dst->src[0]->data; const float* v_d = (const float*)dst->src[1]->data; const float* r_d = (const float*)dst->src[2]->data; @@ -236,16 +233,10 @@ void ggml_sycl_op_rwkv_wkv6(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { }); }); } - - GGML_UNUSED(src0); - GGML_UNUSED(src1); } void ggml_sycl_op_rwkv_wkv7(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { - - const ggml_tensor *src0 = dst->src[0]; - const ggml_tensor *src1 = dst->src[1]; - + scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/7); const float* r_d = (const float*)dst->src[0]->data; const float* w_d = (const float*)dst->src[1]->data; const float* k_d = (const float*)dst->src[2]->data; @@ -299,7 +290,4 @@ void ggml_sycl_op_rwkv_wkv7(ggml_backend_sycl_context& ctx, ggml_tensor* dst) { }); }); } - - GGML_UNUSED(src0); - GGML_UNUSED(src1); } diff --git a/ggml/src/ggml-vulkan/CMakeLists.txt b/ggml/src/ggml-vulkan/CMakeLists.txt index 662f137710716..4a88415f96eae 100644 --- a/ggml/src/ggml-vulkan/CMakeLists.txt +++ b/ggml/src/ggml-vulkan/CMakeLists.txt @@ -109,10 +109,6 @@ if (Vulkan_FOUND) add_compile_definitions(GGML_VULKAN_SHADER_DEBUG_INFO) endif() - if (GGML_VULKAN_PERF) - add_compile_definitions(GGML_VULKAN_PERF) - endif() - if (GGML_VULKAN_VALIDATE) add_compile_definitions(GGML_VULKAN_VALIDATE) endif() diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index fe3669b462c38..ab0303646f505 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -1,6 +1,6 @@ #include "ggml-vulkan.h" #include -#if defined(GGML_VULKAN_RUN_TESTS) || defined(GGML_VULKAN_PERF) || defined(GGML_VULKAN_CHECK_RESULTS) +#if defined(GGML_VULKAN_RUN_TESTS) || defined(GGML_VULKAN_CHECK_RESULTS) #include #include "ggml-cpu.h" #endif @@ -184,9 +184,7 @@ static ggml_backend_buffer_type_i ggml_backend_vk_buffer_type_interface = { #ifdef GGML_VULKAN_MEMORY_DEBUG class vk_memory_logger; #endif -#ifdef GGML_VULKAN_PERF class vk_perf_logger; -#endif static void ggml_vk_destroy_buffer(vk_buffer& buf); static constexpr uint32_t mul_mat_vec_max_cols = 8; @@ -442,9 +440,11 @@ struct vk_device_struct { #ifdef GGML_VULKAN_MEMORY_DEBUG std::unique_ptr memory_logger; #endif -#ifdef GGML_VULKAN_PERF + + // for GGML_VK_PERF_LOGGER std::unique_ptr perf_logger; -#endif + vk::QueryPool query_pool; + uint32_t num_queries; ~vk_device_struct() { VK_LOG_DEBUG("destroy device " << name); @@ -828,8 +828,6 @@ class vk_memory_logger { #define VK_LOG_MEMORY(msg) ((void) 0) #endif // GGML_VULKAN_MEMORY_DEBUG -#if defined(GGML_VULKAN_PERF) - class vk_perf_logger { public: void print_timings() { @@ -839,7 +837,7 @@ class vk_perf_logger { for (const auto& time : t.second) { total += time; } - std::cerr << t.first << ": " << t.second.size() << " x " << (total / t.second.size() / 1000.0) << " ms" << std::endl; + std::cerr << t.first << ": " << t.second.size() << " x " << (total / t.second.size() / 1000.0) << " us" << std::endl; } timings.clear(); @@ -868,7 +866,6 @@ class vk_perf_logger { private: std::map> timings; }; -#endif // GGML_VULKAN_PERF struct ggml_backend_vk_context { std::string name; @@ -958,6 +955,8 @@ struct vk_instance_t { static bool vk_instance_initialized = false; static vk_instance_t vk_instance; +static bool vk_perf_logger_enabled = false; + #ifdef GGML_VULKAN_CHECK_RESULTS static size_t vk_skip_checks; static size_t vk_output_tensor; @@ -2031,25 +2030,25 @@ static void ggml_vk_load_shaders(vk_device& device) { CREATE_MM(pipeline_matmul_bf16, matmul_bf16, , wg_denoms, warptile, vk_mat_mat_push_constants, 3) } #endif - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_0].f16acc, matmul_q4_0_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_1].f16acc, matmul_q4_1_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_0].f16acc, matmul_q5_0_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_1].f16acc, matmul_q5_1_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q8_0].f16acc, matmul_q8_0_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q2_K].f16acc, matmul_q2_k_f16, _f16acc, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q3_K].f16acc, matmul_q3_k_f16, _f16acc, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_K].f16acc, matmul_q4_k_f16, _f16acc, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_K].f16acc, matmul_q5_k_f16, _f16acc, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q6_K].f16acc, matmul_q6_k_f16, _f16acc, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ1_S].f16acc, matmul_iq1_s_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ1_M].f16acc, matmul_iq1_m_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_XXS].f16acc, matmul_iq2_xxs_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_XS].f16acc, matmul_iq2_xs_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_S].f16acc, matmul_iq2_s_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ3_XXS].f16acc, matmul_iq3_xxs_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ3_S].f16acc, matmul_iq3_s_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ4_XS].f16acc, matmul_iq4_xs_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) - CREATE_MM(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ4_NL].f16acc, matmul_iq4_nl_f16, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_0], matmul_q4_0_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_1], matmul_q4_1_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_0], matmul_q5_0_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_1], matmul_q5_1_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q8_0], matmul_q8_0_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q2_K], matmul_q2_k_f16, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q3_K], matmul_q3_k_f16, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q4_K], matmul_q4_k_f16, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q5_K], matmul_q5_k_f16, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_Q6_K], matmul_q6_k_f16, mmq_wg_denoms_k, warptile_mmq_k, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ1_S], matmul_iq1_s_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ1_M], matmul_iq1_m_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_XXS], matmul_iq2_xxs_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_XS], matmul_iq2_xs_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ2_S], matmul_iq2_s_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ3_XXS], matmul_iq3_xxs_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ3_S], matmul_iq3_s_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ4_XS], matmul_iq4_xs_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) + CREATE_MM2(pipeline_dequant_mul_mat_mat_f16[GGML_TYPE_IQ4_NL], matmul_iq4_nl_f16, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3) CREATE_MM2(pipeline_matmul_id_f16, matmul_id_f16, wg_denoms, warptile, vk_mat_mat_id_push_constants, 4) #if defined(GGML_VULKAN_BFLOAT16_GLSLC_SUPPORT) @@ -2117,47 +2116,47 @@ static void ggml_vk_load_shaders(vk_device& device) { #endif if (device->coopmat_acc_f16_support) { - CREATE_MM(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0].f16acc, matmul_q4_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1].f16acc, matmul_q4_1_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0].f16acc, matmul_q5_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1].f16acc, matmul_q5_1_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0].f16acc, matmul_q8_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - - CREATE_MM(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K].f16acc, matmul_q2_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K].f16acc, matmul_q3_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K].f16acc, matmul_q4_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K].f16acc, matmul_q5_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K].f16acc, matmul_q6_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S].f16acc, matmul_iq1_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M].f16acc, matmul_iq1_m_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS].f16acc, matmul_iq2_xxs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS].f16acc, matmul_iq2_xs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S].f16acc, matmul_iq2_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS].f16acc, matmul_iq3_xxs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S].f16acc, matmul_iq3_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS].f16acc, matmul_iq4_xs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL].f16acc, matmul_iq4_nl_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0], matmul_q4_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1], matmul_q4_1_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0], matmul_q5_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1], matmul_q5_1_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0], matmul_q8_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + + CREATE_MM2(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K], matmul_q2_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K], matmul_q3_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K], matmul_q4_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K], matmul_q5_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K], matmul_q6_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S], matmul_iq1_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M], matmul_iq1_m_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS], matmul_iq2_xxs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS], matmul_iq2_xs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S], matmul_iq2_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS], matmul_iq3_xxs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S], matmul_iq3_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS], matmul_iq4_xs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL], matmul_iq4_nl_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); } else { - CREATE_MM(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0].f16acc, matmul_q4_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1].f16acc, matmul_q4_1_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0].f16acc, matmul_q5_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1].f16acc, matmul_q5_1_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0].f16acc, matmul_q8_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - - CREATE_MM(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K].f16acc, matmul_q2_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K].f16acc, matmul_q3_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K].f16acc, matmul_q4_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K].f16acc, matmul_q5_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K].f16acc, matmul_q6_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S].f16acc, matmul_iq1_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M].f16acc, matmul_iq1_m_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS].f16acc, matmul_iq2_xxs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS].f16acc, matmul_iq2_xs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S].f16acc, matmul_iq2_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS].f16acc, matmul_iq3_xxs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S].f16acc, matmul_iq3_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS].f16acc, matmul_iq4_xs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL].f16acc, matmul_iq4_nl_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0].f32acc, matmul_q4_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1].f32acc, matmul_q4_1_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0].f32acc, matmul_q5_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1].f32acc, matmul_q5_1_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0].f32acc, matmul_q8_0_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + + CREATE_MM(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K].f32acc, matmul_q2_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K].f32acc, matmul_q3_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K].f32acc, matmul_q4_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K].f32acc, matmul_q5_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K].f32acc, matmul_q6_k_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S].f32acc, matmul_iq1_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M].f32acc, matmul_iq1_m_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS].f32acc, matmul_iq2_xxs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS].f32acc, matmul_iq2_xs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S].f32acc, matmul_iq2_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS].f32acc, matmul_iq3_xxs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S].f32acc, matmul_iq3_s_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS].f32acc, matmul_iq4_xs_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL].f32acc, matmul_iq4_nl_f32, , mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); } CREATE_MM(GGML_TYPE_F32, pipeline_matmul_id_f32, matmul_id_f32_f32, , wg_denoms, warptile, vk_mat_mat_push_constants, 4, _id); @@ -2232,13 +2231,19 @@ static void ggml_vk_load_shaders(vk_device& device) { if (device->mul_mat ## ID ## _s[TYPE]) \ ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->a_s, #NAMELC #F16ACC "_aligned_s", NAMELC ## _aligned ## F16ACC ## _len, NAMELC ## _aligned ## F16ACC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, s_align); \ -#define CREATE_MMQ(TYPE, PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \ - if (device->mul_mat ## ID ## _l[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->l, #NAMELC #F16ACC "_l", NAMELC ## F16ACC ## _len, NAMELC ## F16ACC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), l_ ## WG_DENOMS, l_ ## WARPTILE, 1); \ - if (device->mul_mat ## ID ## _m[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->m, #NAMELC #F16ACC "_m", NAMELC ## F16ACC ## _len, NAMELC ## F16ACC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), m_ ## WG_DENOMS, m_ ## WARPTILE, 1); \ - if (device->mul_mat ## ID ## _s[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->s, #NAMELC #F16ACC "_s", NAMELC ## F16ACC ## _len, NAMELC ## F16ACC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, 1); \ +#define CREATE_MMQ(TYPE, PIPELINE_NAME, NAMELC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \ + if (device->mul_mat ## ID ## _l[TYPE]) { \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f16acc->l, #NAMELC "_f16acc_l", NAMELC ## _f16acc_len, NAMELC ## _f16acc_data, "main", PARAMCOUNT, sizeof(PUSHCONST), l_ ## WG_DENOMS, l_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f32acc->l, #NAMELC "_l", NAMELC ## _len, NAMELC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), l_ ## WG_DENOMS, l_ ## WARPTILE, 1); \ + } \ + if (device->mul_mat ## ID ## _m[TYPE]) { \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f16acc->m, #NAMELC "_f16acc_m", NAMELC ## _f16acc_len, NAMELC ## _f16acc_data, "main", PARAMCOUNT, sizeof(PUSHCONST), m_ ## WG_DENOMS, m_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f32acc->m, #NAMELC "_m", NAMELC ## _len, NAMELC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), m_ ## WG_DENOMS, m_ ## WARPTILE, 1); \ + } \ + if (device->mul_mat ## ID ## _s[TYPE]) { \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f16acc->s, #NAMELC "_f16acc_s", NAMELC ## _f16acc_len, NAMELC ## _f16acc_data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME .f32acc->s, #NAMELC "_s", NAMELC ## _len, NAMELC ## _data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, 1); \ + } \ // Create 2 variants, {f16,f32} accumulator #define CREATE_MM2(TYPE, PIPELINE_NAME, NAMELC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \ @@ -2252,34 +2257,34 @@ static void ggml_vk_load_shaders(vk_device& device) { CREATE_MM(GGML_TYPE_BF16, pipeline_matmul_bf16, matmul_bf16, , wg_denoms, warptile, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0].f16acc, matmul_q4_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1].f16acc, matmul_q4_1_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0].f16acc, matmul_q5_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1].f16acc, matmul_q5_1_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0].f16acc, matmul_q8_0_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - - CREATE_MM(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K].f16acc, matmul_q2_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K].f16acc, matmul_q3_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K].f16acc, matmul_q4_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K].f16acc, matmul_q5_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K].f16acc, matmul_q6_k_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S].f16acc, matmul_iq1_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M].f16acc, matmul_iq1_m_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS].f16acc, matmul_iq2_xxs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS].f16acc, matmul_iq2_xs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S].f16acc, matmul_iq2_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS].f16acc, matmul_iq3_xxs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S].f16acc, matmul_iq3_s_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS].f16acc, matmul_iq4_xs_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); - CREATE_MM(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL].f16acc, matmul_iq4_nl_f32, _f16acc, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_0], matmul_q4_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_1], matmul_q4_1_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_0], matmul_q5_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_1], matmul_q5_1_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q8_0], matmul_q8_0_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + + CREATE_MM2(GGML_TYPE_Q2_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q2_K], matmul_q2_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q3_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q3_K], matmul_q3_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q4_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q4_K], matmul_q4_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q5_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q5_K], matmul_q5_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_Q6_K, pipeline_dequant_mul_mat_mat[GGML_TYPE_Q6_K], matmul_q6_k_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ1_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_S], matmul_iq1_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ1_M, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ1_M], matmul_iq1_m_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XXS], matmul_iq2_xxs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_XS], matmul_iq2_xs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ2_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ2_S], matmul_iq2_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ3_XXS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_XXS], matmul_iq3_xxs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ3_S, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ3_S], matmul_iq3_s_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ4_XS, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_XS], matmul_iq4_xs_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); + CREATE_MM2(GGML_TYPE_IQ4_NL, pipeline_dequant_mul_mat_mat[GGML_TYPE_IQ4_NL], matmul_iq4_nl_f32, mmq_wg_denoms, warptile_mmq, vk_mat_mat_push_constants, 3, ); #if defined(GGML_VULKAN_INTEGER_DOT_GLSLC_SUPPORT) if (device->integer_dot_product) { - CREATE_MMQ(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_0].f16acc, matmul_q4_0_q8_1, _f16acc, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_1].f16acc, matmul_q4_1_q8_1, _f16acc, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_0].f16acc, matmul_q5_0_q8_1, _f16acc, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_1].f16acc, matmul_q5_1_q8_1, _f16acc, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q8_0].f16acc, matmul_q8_0_q8_1, _f16acc, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_0], matmul_q4_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_1], matmul_q4_1_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_0], matmul_q5_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_1], matmul_q5_1_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q8_0], matmul_q8_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); } #endif @@ -2328,13 +2333,13 @@ static void ggml_vk_load_shaders(vk_device& device) { if (device->mul_mat ## ID ## _s[TYPE]) \ ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->a_s, #NAMELC #F16ACC "_aligned_s", NAMELC ## _aligned ## F16ACC ## _fp32_len, NAMELC ## _aligned ## F16ACC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, s_align); \ -#define CREATE_MMQ(TYPE, PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \ +#define CREATE_MMQ(TYPE, PIPELINE_NAME, NAMELC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \ if (device->mul_mat ## ID ## _l[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->l, #NAMELC #F16ACC "_l", NAMELC ## F16ACC ## _fp32_len, NAMELC ## F16ACC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), l_ ## WG_DENOMS, l_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->l, #NAMELC "_l", NAMELC ## _fp32_len, NAMELC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), l_ ## WG_DENOMS, l_ ## WARPTILE, 1); \ if (device->mul_mat ## ID ## _m[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->m, #NAMELC #F16ACC "_m", NAMELC ## F16ACC ## _fp32_len, NAMELC ## F16ACC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), m_ ## WG_DENOMS, m_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->m, #NAMELC "_m", NAMELC ## _fp32_len, NAMELC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), m_ ## WG_DENOMS, m_ ## WARPTILE, 1); \ if (device->mul_mat ## ID ## _s[TYPE]) \ - ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->s, #NAMELC #F16ACC "_s", NAMELC ## F16ACC ## _fp32_len, NAMELC ## F16ACC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, 1); \ + ggml_vk_create_pipeline(device, device-> PIPELINE_NAME ->s, #NAMELC "_s", NAMELC ## _fp32_len, NAMELC ## _fp32_data, "main", PARAMCOUNT, sizeof(PUSHCONST), s_ ## WG_DENOMS, s_ ## WARPTILE, 1); \ CREATE_MM(GGML_TYPE_F32, pipeline_matmul_f32, matmul_f32_f32, , wg_denoms, warptile, vk_mat_mat_push_constants, 3, ); CREATE_MM(GGML_TYPE_F32, pipeline_matmul_f32_f16, matmul_f32_f16, , wg_denoms, warptile, vk_mat_mat_push_constants, 3, ); @@ -2366,11 +2371,11 @@ static void ggml_vk_load_shaders(vk_device& device) { #if defined(GGML_VULKAN_INTEGER_DOT_GLSLC_SUPPORT) if (device->integer_dot_product) { - CREATE_MMQ(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_0].f32acc, matmul_q4_0_q8_1, , mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_1].f32acc, matmul_q4_1_q8_1, , mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_0].f32acc, matmul_q5_0_q8_1, , mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_1].f32acc, matmul_q5_1_q8_1, , mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); - CREATE_MMQ(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q8_0].f32acc, matmul_q8_0_q8_1, , mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q4_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_0].f32acc, matmul_q4_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q4_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q4_1].f32acc, matmul_q4_1_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q5_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_0].f32acc, matmul_q5_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q5_1, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q5_1].f32acc, matmul_q5_1_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); + CREATE_MMQ(GGML_TYPE_Q8_0, pipeline_dequant_mul_mat_mat_q8_1[GGML_TYPE_Q8_0].f32acc, matmul_q8_0_q8_1, mmq_wg_denoms, warptile_mmq_int, vk_mat_mat_push_constants, 3, ); } #endif @@ -2751,9 +2756,9 @@ static vk_device ggml_vk_get_device(size_t idx) { #ifdef GGML_VULKAN_MEMORY_DEBUG device->memory_logger = std::unique_ptr(new vk_memory_logger()); #endif -#ifdef GGML_VULKAN_PERF - device->perf_logger = std::unique_ptr(new vk_perf_logger()); -#endif + if (vk_perf_logger_enabled) { + device->perf_logger = std::unique_ptr(new vk_perf_logger()); + } size_t dev_num = vk_instance.device_indices[idx]; @@ -2798,23 +2803,29 @@ static vk_device ggml_vk_get_device(size_t idx) { pipeline_robustness = true; } else if (strcmp("VK_EXT_subgroup_size_control", properties.extensionName) == 0) { device->subgroup_size_control = true; +#if defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) } else if (strcmp("VK_KHR_cooperative_matrix", properties.extensionName) == 0 && !getenv("GGML_VK_DISABLE_COOPMAT")) { device->coopmat_support = true; device->coopmat_m = 0; device->coopmat_n = 0; device->coopmat_k = 0; +#endif +#if defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) } else if (strcmp("VK_NV_cooperative_matrix2", properties.extensionName) == 0 && !getenv("GGML_VK_DISABLE_COOPMAT2")) { coopmat2_support = true; +#endif #if defined(GGML_VULKAN_INTEGER_DOT_GLSLC_SUPPORT) } else if (strcmp("VK_KHR_shader_integer_dot_product", properties.extensionName) == 0 && !getenv("GGML_VK_DISABLE_INTEGER_DOT_PRODUCT")) { device->integer_dot_product = true; #endif +#if defined(GGML_VULKAN_BFLOAT16_GLSLC_SUPPORT) } else if (strcmp("VK_KHR_shader_bfloat16", properties.extensionName) == 0 && !getenv("GGML_VK_DISABLE_BFLOAT16")) { bfloat16_support = true; +#endif } } @@ -3535,6 +3546,8 @@ static void ggml_vk_instance_init() { vk_instance.instance = vk::createInstance(instance_create_info); vk_instance_initialized = true; + vk_perf_logger_enabled = getenv("GGML_VK_PERF_LOGGER") != nullptr; + size_t num_available_devices = vk_instance.instance.enumeratePhysicalDevices().size(); // Emulate behavior of CUDA_VISIBLE_DEVICES for Vulkan @@ -3711,7 +3724,7 @@ static vk_pipeline ggml_vk_get_to_fp16(ggml_backend_vk_context * ctx, ggml_type } static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_pipeline(ggml_backend_vk_context * ctx, ggml_type src0_type, ggml_type src1_type, ggml_prec prec) { - VK_LOG_DEBUG("ggml_vk_get_mul_mat_mat_pipeline(" << ggml_type_name(src0_type) << ", " << ggml_type_name(src1_type) << ")"); + VK_LOG_DEBUG("ggml_vk_get_mul_mat_mat_pipeline(" << ggml_type_name(src0_type) << ", " << ggml_type_name(src1_type) << ", " << prec << ")"); if (src0_type == GGML_TYPE_F32 && src1_type == GGML_TYPE_F32) { return ctx->device->pipeline_matmul_f32; } @@ -3739,7 +3752,7 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_pipeline(ggml_backend_vk_conte // MMQ if (src1_type == GGML_TYPE_Q8_1) { - vk_matmul_pipeline pipelines = ctx->device->pipeline_dequant_mul_mat_mat_q8_1[src0_type].f16acc; + vk_matmul_pipeline pipelines = (ctx->device->fp16 && prec == GGML_PREC_DEFAULT) ? ctx->device->pipeline_dequant_mul_mat_mat_q8_1[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat_q8_1[src0_type].f32acc; if (pipelines->s == nullptr && pipelines->m == nullptr && pipelines->l == nullptr) { return nullptr; @@ -3779,9 +3792,12 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_pipeline(ggml_backend_vk_conte if (ctx->device->coopmat2) { assert(src1_type == GGML_TYPE_F16); - return ctx->device->pipeline_dequant_mul_mat_mat_f16[src0_type].f16acc; + return prec == GGML_PREC_DEFAULT ? ctx->device->pipeline_dequant_mul_mat_mat_f16[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat_f16[src0_type].f32acc; + } + if (ctx->device->coopmat_support) { + return (ctx->device->fp16 && ctx->device->coopmat_acc_f16_support && prec == GGML_PREC_DEFAULT) ? ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f32acc; } - return ctx->device->fp16 ? ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f32acc; + return (ctx->device->fp16 && prec == GGML_PREC_DEFAULT) ? ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat[src0_type].f32acc; } static vk_pipeline ggml_vk_get_dequantize_mul_mat_vec(ggml_backend_vk_context * ctx, ggml_type a_type, ggml_type b_type, uint32_t num_cols) { @@ -4504,6 +4520,8 @@ static vk_pipeline ggml_vk_guess_matmul_pipeline(ggml_backend_vk_context * ctx, return aligned ? mmp->a_m : mmp->m; } return aligned ? mmp->a_l : mmp->l; + + GGML_UNUSED(src1_type); } static uint32_t ggml_vk_guess_matmul_pipeline_align(ggml_backend_vk_context * ctx, vk_matmul_pipeline& mmp, int m, int n, ggml_type src0_type, ggml_type src1_type) { @@ -4659,6 +4677,19 @@ static vk_pipeline ggml_vk_get_cpy_pipeline(ggml_backend_vk_context * ctx, const } } + if (src->type == to) { + // Copy two or four bytes at a time, depending on block size. + // For quantized types, we scale by block size/type size. But + // this path is also used for bf16->bf16 for example, where the + // type size must be exactly 2 or 4. + GGML_ASSERT(ggml_is_quantized(to) || ggml_type_size(src->type) == 2 || ggml_type_size(src->type) == 4); + if ((ggml_type_size(src->type) % 4) == 0) { + return ctx->device->pipeline_contig_cpy_f32_f32; + } else { + return ctx->device->pipeline_contig_cpy_f16_f16; + } + } + std::cerr << "Missing CPY op for types: " << ggml_type_name(src->type) << " " << ggml_type_name(to) << std::endl; GGML_ABORT("fatal error"); } @@ -6422,6 +6453,7 @@ static bool ggml_vk_op_supports_incontiguous(ggml_op op) { case GGML_OP_ROPE: case GGML_OP_RMS_NORM: case GGML_OP_CONV_2D_DW: + case GGML_OP_IM2COL: return true; default: return false; @@ -6720,7 +6752,16 @@ static void ggml_vk_op_f32(ggml_backend_vk_context * ctx, vk_context& subctx, co case GGML_OP_UNARY: case GGML_OP_CONV_2D_DW: { - const uint32_t ne = ggml_nelements(dst); + uint32_t ne = ggml_nelements(dst); + if (op == GGML_OP_CPY && ggml_is_quantized(src0->type) && ggml_is_quantized(dst->type)) { + // Convert from number of logical elements to 2- or 4-byte units. + ne /= ggml_blck_size(src0->type); + if ((ggml_type_size(src0->type) % 4) == 0) { + ne *= ggml_type_size(src0->type) / 4; + } else { + ne *= ggml_type_size(src0->type) / 2; + } + } if (ne > 262144) { elements = { 512, 512, CEIL_DIV(ne, 262144) }; } else if (ne > 512) { @@ -7270,8 +7311,19 @@ static void ggml_vk_cpy(ggml_backend_vk_context * ctx, vk_context& subctx, const const uint32_t src0_type_size = ggml_type_size(src0->type); const uint32_t dst_type_size = ggml_type_size(dst->type); + uint32_t ne = (uint32_t)ggml_nelements(src0); + if (ggml_is_quantized(src0->type) && ggml_is_quantized(dst->type)) { + // Convert from number of logical elements to 2- or 4-byte units. + ne /= ggml_blck_size(src0->type); + if ((ggml_type_size(src0->type) % 4) == 0) { + ne *= ggml_type_size(src0->type) / 4; + } else { + ne *= ggml_type_size(src0->type) / 2; + } + } + ggml_vk_op_f32(ctx, subctx, src0, nullptr, nullptr, dst, GGML_OP_CPY, { - (uint32_t)ggml_nelements(src0), + ne, (uint32_t)src0->ne[0], (uint32_t)src0->ne[1], (uint32_t)src0->ne[2], (uint32_t)src0->ne[3], (uint32_t)src0->nb[0] / src0_type_size, (uint32_t)src0->nb[1] / src0_type_size, (uint32_t)src0->nb[2] / src0_type_size, (uint32_t)src0->nb[3] / src0_type_size, (uint32_t) dst->ne[0], (uint32_t) dst->ne[1], (uint32_t) dst->ne[2], (uint32_t) dst->ne[3], (uint32_t) dst->nb[0] / dst_type_size, (uint32_t) dst->nb[1] / dst_type_size, (uint32_t) dst->nb[2] / dst_type_size, (uint32_t) dst->nb[3] / dst_type_size, 0, @@ -8834,7 +8886,7 @@ static bool ggml_vk_build_graph(ggml_backend_vk_context * ctx, ggml_tensor * nod ctx->tensor_ctxs[node_idx] = compute_ctx; -#if defined(GGML_VULKAN_CHECK_RESULTS) || defined(GGML_VULKAN_PERF) +#if defined(GGML_VULKAN_CHECK_RESULTS) // Force context reset on each node so that each tensor ends up in its own context // and can be run and compared to its CPU equivalent separately last_node = true; @@ -9253,8 +9305,7 @@ static ggml_backend_buffer_t ggml_backend_vk_host_buffer_type_alloc_buffer(ggml_ try { ptr = ggml_vk_host_malloc(vk_instance.devices[0], size); } catch (vk::SystemError& e) { - std::cerr << "ggml_vulkan: Failed to allocate pinned memory." << std::endl; - std::cerr << "ggml_vulkan: " << e.what() << std::endl; + GGML_LOG_WARN("ggml_vulkan: Failed to allocate pinned memory (%s)\n", e.what()); // fallback to cpu buffer return ggml_backend_buft_alloc_buffer(ggml_backend_cpu_buffer_type(), size); } @@ -9455,6 +9506,29 @@ static ggml_status ggml_backend_vk_graph_compute(ggml_backend_t backend, ggml_cg bool first_node_in_batch = true; // true if next node will be first node in a batch int submit_node_idx = 0; // index to first node in a batch + vk_context compute_ctx; + if (vk_perf_logger_enabled) { + // allocate/resize the query pool + if (ctx->device->num_queries < cgraph->n_nodes + 1) { + if (ctx->device->query_pool) { + ctx->device->device.destroyQueryPool(ctx->device->query_pool); + } + VkQueryPoolCreateInfo query_create_info = { VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO }; + query_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; + query_create_info.queryCount = cgraph->n_nodes + 100; + ctx->device->query_pool = ctx->device->device.createQueryPool(query_create_info); + ctx->device->num_queries = query_create_info.queryCount; + } + + ctx->device->device.resetQueryPool(ctx->device->query_pool, 0, cgraph->n_nodes+1); + + GGML_ASSERT(ctx->compute_ctx.expired()); + compute_ctx = ggml_vk_create_context(ctx, ctx->device->compute_queue); + ctx->compute_ctx = compute_ctx; + ggml_vk_ctx_begin(ctx->device, compute_ctx); + compute_ctx->s->buffer.writeTimestamp(vk::PipelineStageFlagBits::eAllCommands, ctx->device->query_pool, 0); + } + // Submit after enough work has accumulated, to overlap CPU cmdbuffer generation with GPU execution. // Estimate the amount of matmul work by looking at the weight matrix size, and submit every 100MB // (and scaled down based on model size, so smaller models submit earlier). @@ -9482,6 +9556,17 @@ static ggml_status ggml_backend_vk_graph_compute(ggml_backend_t backend, ggml_cg bool enqueued = ggml_vk_build_graph(ctx, cgraph->nodes[i], i, cgraph->nodes[submit_node_idx], submit_node_idx, false, i == last_node, almost_ready, submit); + if (vk_perf_logger_enabled) { + if (ctx->compute_ctx.expired()) { + compute_ctx = ggml_vk_create_context(ctx, ctx->device->compute_queue); + ctx->compute_ctx = compute_ctx; + ggml_vk_ctx_begin(ctx->device, compute_ctx); + } else { + compute_ctx = ctx->compute_ctx.lock(); + } + compute_ctx->s->buffer.writeTimestamp(vk::PipelineStageFlagBits::eAllCommands, ctx->device->query_pool, i+1); + } + if (enqueued) { ++submitted_nodes; @@ -9503,9 +9588,27 @@ static ggml_status ggml_backend_vk_graph_compute(ggml_backend_t backend, ggml_cg } } -#ifdef GGML_VULKAN_PERF - ctx->device->perf_logger->print_timings(); -#endif + if (vk_perf_logger_enabled) { + // End the command buffer and submit/wait + GGML_ASSERT(!ctx->compute_ctx.expired()); + compute_ctx = ctx->compute_ctx.lock(); + ggml_vk_ctx_end(compute_ctx); + + ggml_vk_submit(compute_ctx, ctx->device->fence); + VK_CHECK(ctx->device->device.waitForFences({ ctx->device->fence }, true, UINT64_MAX), "GGML_VULKAN_PERF waitForFences"); + ctx->device->device.resetFences({ ctx->device->fence }); + + // Get the results and pass them to the logger + std::vector timestamps(cgraph->n_nodes + 1); + ctx->device->device.getQueryPoolResults(ctx->device->query_pool, 0, cgraph->n_nodes + 1, (cgraph->n_nodes + 1)*sizeof(uint64_t), timestamps.data(), sizeof(uint64_t), vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait); + for (int i = 0; i < cgraph->n_nodes; i++) { + if (!ggml_vk_is_empty(cgraph->nodes[i])) { + ctx->device->perf_logger->log_timing(cgraph->nodes[i], uint64_t((timestamps[i+1] - timestamps[i]) * ctx->device->properties.limits.timestampPeriod)); + } + } + + ctx->device->perf_logger->print_timings(); + } ggml_vk_graph_cleanup(ctx); @@ -9856,6 +9959,15 @@ static bool ggml_backend_vk_device_supports_op(ggml_backend_dev_t dev, const ggm if (src0_type == GGML_TYPE_F16 && src1_type == GGML_TYPE_F16) { return true; } + + // We can handle copying from a type to the same type if it's + // contiguous (memcpy). We use f16 or f32 shaders to do the copy, + // so the type/block size must be a multiple of 4. + if (src0_type == src1_type && + ggml_is_contiguous(op->src[0]) && ggml_is_contiguous(op) && + (ggml_type_size(src0_type) % 2) == 0) { + return true; + } return false; } break; case GGML_OP_REPEAT: @@ -10261,7 +10373,7 @@ static void ggml_vk_check_results_0(ggml_tensor * tensor) { } else if (tensor->op == GGML_OP_CONCAT) { tensor_clone = ggml_concat(ggml_ctx, src_clone[0], src_clone[1], *(int *)tensor->op_params); } else if (tensor->op == GGML_OP_UPSCALE) { - tensor_clone = ggml_upscale_ext(ggml_ctx, src_clone[0], tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3], tensor->op_params[0], tensor->op_params[1], (ggml_scale_mode) tensor->op_params[0]); + tensor_clone = ggml_upscale_ext(ggml_ctx, src_clone[0], tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3], (ggml_scale_mode) tensor->op_params[0]); } else if (tensor->op == GGML_OP_SCALE) { const float * params = (const float *)tensor->op_params; tensor_clone = ggml_scale(ggml_ctx, src_clone[0], params[0]); @@ -10550,7 +10662,8 @@ static void ggml_vk_check_results_1(ggml_tensor * tensor) { ggml_vk_print_graph_origin(tensor, done); GGML_ABORT("fatal error"); } - if (first_error[0] == -1 && std::fabs(correct - result) > 0.1f) { + const double denom = std::fabs(correct) > 1.0f ? (std::fabs(correct) > 1e-8 ? std::fabs(correct) : 1e-8) : 1.0f; + if (first_error[0] == -1 && std::fabs(correct - result) / denom > 0.5) { first_error[0] = i0; first_error[1] = i1; first_error[2] = i2; @@ -10562,7 +10675,7 @@ static void ggml_vk_check_results_1(ggml_tensor * tensor) { // Special case, value is infinite, avoid NaN result in avg_err // NaN also appears in results, if both are nan error is 0 if (!std::isinf(correct) && !std::isinf(result) && !std::isnan(correct) && !std::isnan(result)) { - avg_err += std::fabs(correct - result); + avg_err += std::fabs(correct - result) / denom; } counter++; } @@ -10597,7 +10710,7 @@ static void ggml_vk_check_results_1(ggml_tensor * tensor) { ggml_vk_print_graph_origin(tensor, done); } - if (avg_err > 0.05 || std::isnan(avg_err)) { + if (avg_err > 0.5 || std::isnan(avg_err)) { std::cerr << "ERROR: avg_err=" << avg_err << " in " << ggml_op_name(tensor->op) << " (check " << check_counter << ")" << std::endl; std::cerr << "tensor=" << tensor << " tensor->name=" << tensor->name << " tensor->type: " << ggml_type_name(tensor->type) << " ne0=" << tensor->ne[0] << " nb0=" << tensor->nb[0] << " ne1=" << tensor->ne[1] << " nb1=" << tensor->nb[1] << " ne2=" << tensor->ne[2] << " nb2=" << tensor->nb[2] << " ne3=" << tensor->ne[3] << " nb3=" << tensor->nb[3] << " offset=" << tensor->view_offs << std::endl; if (src0 != nullptr) { diff --git a/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp b/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp index 39184ef582355..b604c1881a5ea 100644 --- a/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp +++ b/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp @@ -1,6 +1,6 @@ #version 450 -#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require +#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require #include "dequant_head.comp" diff --git a/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp b/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp index 7859a1a60e27f..26163b167c7ed 100644 --- a/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +++ b/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp @@ -7,7 +7,7 @@ #extension GL_EXT_shader_explicit_arithmetic_types_float16 : require #endif #if defined(DATA_A_IQ1_M) -#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require +#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require #endif #if defined(DATA_A_BF16) && defined(COOPMAT) diff --git a/ggml/src/ggml.c b/ggml/src/ggml.c index 8a6546240f46f..fb0d379dc8d68 100644 --- a/ggml/src/ggml.c +++ b/ggml/src/ggml.c @@ -64,12 +64,17 @@ // precomputed f32 table for f16 (256 KB) (ggml-impl.h) float ggml_table_f32_f16[1 << 16]; -#if (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \ - (!defined(TARGET_OS_TV) && !defined(TARGET_OS_WATCH)) +#if defined(__linux__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + (defined(__APPLE__) && !TARGET_OS_TV && !TARGET_OS_WATCH) + #include #include #include #include +#if defined(__linux__) +#include +#endif #if defined(__ANDROID__) #include @@ -133,10 +138,36 @@ static void ggml_print_backtrace(void) { if (GGML_NO_BACKTRACE) { return; } - char attach[32]; - snprintf(attach, sizeof(attach), "attach %d", getpid()); - int pid = fork(); - if (pid == 0) { +#if defined(__linux__) + FILE * f = fopen("/proc/self/status", "r"); + size_t size = 0; + char * line = NULL; + ssize_t length = 0; + while ((length = getline(&line, &size, f)) > 0) { + if (!strncmp(line, "TracerPid:", sizeof("TracerPid:") - 1) && + (length != sizeof("TracerPid:\t0\n") - 1 || line[length - 2] != '0')) { + // Already being debugged, and the breakpoint is the later abort() + free(line); + fclose(f); + return; + } + } + free(line); + fclose(f); + int lock[2] = { -1, -1 }; + (void) !pipe(lock); // Don't start gdb until after PR_SET_PTRACER +#endif + const int parent_pid = getpid(); + const int child_pid = fork(); + if (child_pid < 0) { // error + return; + } else if (child_pid == 0) { // child + char attach[32]; + snprintf(attach, sizeof(attach), "attach %d", parent_pid); +#if defined(__linux__) + close(lock[1]); + (void) !read(lock[0], lock, 1); +#endif // try gdb execlp("gdb", "gdb", "--batch", "-ex", "set style enabled on", @@ -149,18 +180,18 @@ static void ggml_print_backtrace(void) { execlp("lldb", "lldb", "--batch", "-o", "bt", "-o", "quit", - "-p", attach, + "-p", &attach[sizeof("attach ") - 1], (char *) NULL); - exit(EXIT_FAILURE); - } else { - int wstatus; - waitpid(pid, &wstatus, 0); - if (WIFEXITED(wstatus)) { - if (WEXITSTATUS(wstatus) == EXIT_FAILURE) { - // gdb failed, fallback to backtrace_symbols - ggml_print_backtrace_symbols(); - } - } + // gdb failed, fallback to backtrace_symbols + ggml_print_backtrace_symbols(); + _Exit(0); + } else { // parent +#if defined(__linux__) + prctl(PR_SET_PTRACER, child_pid); + close(lock[1]); + close(lock[0]); +#endif + waitpid(child_pid, NULL, 0); } } #else @@ -1068,9 +1099,10 @@ static const char * GGML_UNARY_OP_NAME[GGML_UNARY_OP_COUNT] = { "HARDSWISH", "HARDSIGMOID", "EXP", + "GELU_ERF", }; -static_assert(GGML_UNARY_OP_COUNT == 14, "GGML_UNARY_OP_COUNT != 14"); +static_assert(GGML_UNARY_OP_COUNT == 15, "GGML_UNARY_OP_COUNT != 15"); static_assert(sizeof(struct ggml_object)%GGML_MEM_ALIGN == 0, "ggml_object size must be a multiple of GGML_MEM_ALIGN"); @@ -2280,6 +2312,26 @@ struct ggml_tensor * ggml_repeat( return result; } +struct ggml_tensor * ggml_repeat_4d( + struct ggml_context * ctx, + struct ggml_tensor * a, + int64_t ne0, int64_t ne1, int64_t ne2, int64_t ne3) { + const bool can_repeat = ggml_is_empty(a) || ( + (ne0 % a->ne[0] == 0) && + (ne1 % a->ne[1] == 0) && + (ne2 % a->ne[2] == 0) && + (ne3 % a->ne[3] == 0) + ); + GGML_ASSERT(can_repeat); + + struct ggml_tensor * result = ggml_new_tensor_4d(ctx, a->type, ne0, ne1, ne2, ne3); + + result->op = GGML_OP_REPEAT; + result->src[0] = a; + + return result; +} + // ggml_repeat_back struct ggml_tensor * ggml_repeat_back( @@ -2470,6 +2522,20 @@ struct ggml_tensor * ggml_gelu_inplace( return ggml_unary_inplace(ctx, a, GGML_UNARY_OP_GELU); } +// ggml_gelu_erf + +struct ggml_tensor * ggml_gelu_erf( + struct ggml_context * ctx, + struct ggml_tensor * a) { + return ggml_unary(ctx, a, GGML_UNARY_OP_GELU_ERF); +} + +struct ggml_tensor * ggml_gelu_erf_inplace( + struct ggml_context * ctx, + struct ggml_tensor * a) { + return ggml_unary_inplace(ctx, a, GGML_UNARY_OP_GELU_ERF); +} + // ggml_gelu_quick struct ggml_tensor * ggml_gelu_quick( diff --git a/gguf-py/gguf/constants.py b/gguf-py/gguf/constants.py index 21af0a9a2693f..3ee2b2064e1b4 100644 --- a/gguf-py/gguf/constants.py +++ b/gguf-py/gguf/constants.py @@ -177,6 +177,9 @@ class ConvNext: EMBEDDING_LENGTH = "{arch}.convnext.embedding_length" BLOCK_COUNT = "{arch}.convnext.block_count" + class Classifier: + OUTPUT_LABELS = "{arch}.classifier.output_labels" + class Tokenizer: MODEL = "tokenizer.ggml.model" PRE = "tokenizer.ggml.pre" @@ -219,10 +222,13 @@ class Adapter: TYPE = "adapter.type" LORA_ALPHA = "adapter.lora.alpha" - class ClipVision: + class Clip: PROJECTOR_TYPE = "clip.projector_type" HAS_VISION_ENCODER = "clip.has_vision_encoder" + HAS_AUDIO_ENCODER = "clip.has_audio_encoder" HAS_LLAVA_PROJECTOR = "clip.has_llava_projector" + + class ClipVision: IMAGE_SIZE = "clip.vision.image_size" PATCH_SIZE = "clip.vision.patch_size" EMBEDDING_LENGTH = "clip.vision.embedding_length" @@ -243,19 +249,33 @@ class Attention: class Projector: SCALE_FACTOR = "clip.vision.projector.scale_factor" + class ClipAudio: + NUM_MEL_BINS = "clip.audio.num_mel_bins" + EMBEDDING_LENGTH = "clip.audio.embedding_length" + FEED_FORWARD_LENGTH = "clip.audio.feed_forward_length" + PROJECTION_DIM = "clip.audio.projection_dim" + BLOCK_COUNT = "clip.audio.block_count" + + class Attention: + HEAD_COUNT = "clip.audio.attention.head_count" + LAYERNORM_EPS = "clip.audio.attention.layer_norm_epsilon" + + class Projector: + STACK_FACTOR = "clip.audio.projector.stack_factor" + # # recommended mapping of model tensor names for storage in gguf # class GGUFType: - MODEL = "model" - ADAPTER = "adapter" - CLIP_VISION = "clip-vision" + MODEL = "model" + ADAPTER = "adapter" + MMPROJ = "mmproj" # dummy, unused for now class MODEL_ARCH(IntEnum): - CLIP_VISION = auto() # dummy arch for clip.cpp + MMPROJ = auto() # dummy arch for clip.cpp LLAMA = auto() LLAMA4 = auto() DECI = auto() @@ -482,14 +502,15 @@ class MODEL_TENSOR(IntEnum): V_ENC_EMBD_CLS = auto() V_ENC_EMBD_PATCH = auto() V_ENC_EMBD_POS = auto() + V_ENC_INPUT_NORM = auto() V_ENC_ATTN_Q = auto() V_ENC_ATTN_Q_NORM = auto() V_ENC_ATTN_K = auto() V_ENC_ATTN_K_NORM = auto() V_ENC_ATTN_V = auto() - V_ENC_INPUT_NORM = auto() - V_ENC_OUTPUT = auto() - V_ENC_OUTPUT_NORM = auto() + V_ENC_ATTN_O = auto() + V_ENC_ATTN_O_NORM = auto() + V_ENC_POST_ATTN_NORM = auto() V_ENC_FFN_UP = auto() V_ENC_FFN_GATE = auto() V_ENC_FFN_DOWN = auto() @@ -513,10 +534,28 @@ class MODEL_TENSOR(IntEnum): V_RESMPL_QUERY = auto() # minicpmv V_TOK_EMBD_IMG_BREAK = auto() # pixtral V_MM_PATCH_MERGER = auto() # mistral small 3.1 + # audio (mtmd) + A_ENC_EMBD_POS = auto() + A_ENC_CONV1D = auto() + A_PRE_NORM = auto() + A_POST_NORM = auto() + A_ENC_ATTN_Q = auto() + A_ENC_ATTN_K = auto() + A_ENC_ATTN_V = auto() + A_ENC_INPUT_NORM = auto() + A_ENC_OUTPUT = auto() + A_ENC_OUTPUT_NORM = auto() + A_ENC_FFN_UP = auto() + A_ENC_FFN_GATE = auto() + A_ENC_FFN_DOWN = auto() + A_MMPROJ = auto() + A_MMPROJ_FC = auto() + A_MM_NORM_PRE = auto() + A_MM_NORM_MID = auto() MODEL_ARCH_NAMES: dict[MODEL_ARCH, str] = { - MODEL_ARCH.CLIP_VISION: "clip", # dummy arch for clip.cpp + MODEL_ARCH.MMPROJ: "clip", # dummy arch for clip.cpp MODEL_ARCH.LLAMA: "llama", MODEL_ARCH.LLAMA4: "llama4", MODEL_ARCH.DECI: "deci", @@ -749,8 +788,9 @@ class MODEL_TENSOR(IntEnum): MODEL_TENSOR.V_ENC_ATTN_K_NORM: "v.blk.{bid}.attn_k_norm", MODEL_TENSOR.V_ENC_ATTN_V: "v.blk.{bid}.attn_v", MODEL_TENSOR.V_ENC_INPUT_NORM: "v.blk.{bid}.ln1", - MODEL_TENSOR.V_ENC_OUTPUT: "v.blk.{bid}.attn_out", - MODEL_TENSOR.V_ENC_OUTPUT_NORM: "v.blk.{bid}.ln2", + MODEL_TENSOR.V_ENC_ATTN_O: "v.blk.{bid}.attn_out", + MODEL_TENSOR.V_ENC_ATTN_O_NORM: "v.blk.{bid}.attn_out_norm", + MODEL_TENSOR.V_ENC_POST_ATTN_NORM: "v.blk.{bid}.ln2", MODEL_TENSOR.V_ENC_FFN_UP: "v.blk.{bid}.ffn_up", MODEL_TENSOR.V_ENC_FFN_GATE: "v.blk.{bid}.ffn_gate", MODEL_TENSOR.V_ENC_FFN_DOWN: "v.blk.{bid}.ffn_down", @@ -774,10 +814,28 @@ class MODEL_TENSOR(IntEnum): MODEL_TENSOR.V_RESMPL_QUERY: "resampler.query", MODEL_TENSOR.V_TOK_EMBD_IMG_BREAK: "v.token_embd.img_break", # pixtral MODEL_TENSOR.V_MM_PATCH_MERGER: "mm.patch_merger", # mistral small 3.1 + # audio (mtmd) + MODEL_TENSOR.A_ENC_EMBD_POS: "a.position_embd", + MODEL_TENSOR.A_ENC_CONV1D: "a.conv1d.{bid}", + MODEL_TENSOR.A_PRE_NORM: "a.pre_ln", + MODEL_TENSOR.A_POST_NORM: "a.post_ln", + MODEL_TENSOR.A_ENC_ATTN_Q: "a.blk.{bid}.attn_q", + MODEL_TENSOR.A_ENC_ATTN_K: "a.blk.{bid}.attn_k", + MODEL_TENSOR.A_ENC_ATTN_V: "a.blk.{bid}.attn_v", + MODEL_TENSOR.A_ENC_INPUT_NORM: "a.blk.{bid}.ln1", + MODEL_TENSOR.A_ENC_OUTPUT: "a.blk.{bid}.attn_out", + MODEL_TENSOR.A_ENC_OUTPUT_NORM: "a.blk.{bid}.ln2", + MODEL_TENSOR.A_ENC_FFN_UP: "a.blk.{bid}.ffn_up", + MODEL_TENSOR.A_ENC_FFN_GATE: "a.blk.{bid}.ffn_gate", + MODEL_TENSOR.A_ENC_FFN_DOWN: "a.blk.{bid}.ffn_down", + MODEL_TENSOR.A_MMPROJ: "mm.a.mlp.{bid}", + MODEL_TENSOR.A_MMPROJ_FC: "mm.a.fc", + MODEL_TENSOR.A_MM_NORM_PRE: "mm.a.norm_pre", + MODEL_TENSOR.A_MM_NORM_MID: "mm.a.norm_mid", } MODEL_TENSORS: dict[MODEL_ARCH, list[MODEL_TENSOR]] = { - MODEL_ARCH.CLIP_VISION: [ + MODEL_ARCH.MMPROJ: [ MODEL_TENSOR.V_MMPROJ, MODEL_TENSOR.V_MMPROJ_FC, MODEL_TENSOR.V_MMPROJ_MLP, @@ -785,14 +843,15 @@ class MODEL_TENSOR(IntEnum): MODEL_TENSOR.V_ENC_EMBD_CLS, MODEL_TENSOR.V_ENC_EMBD_PATCH, MODEL_TENSOR.V_ENC_EMBD_POS, + MODEL_TENSOR.V_ENC_INPUT_NORM, MODEL_TENSOR.V_ENC_ATTN_Q, MODEL_TENSOR.V_ENC_ATTN_Q_NORM, MODEL_TENSOR.V_ENC_ATTN_K, MODEL_TENSOR.V_ENC_ATTN_K_NORM, MODEL_TENSOR.V_ENC_ATTN_V, - MODEL_TENSOR.V_ENC_INPUT_NORM, - MODEL_TENSOR.V_ENC_OUTPUT, - MODEL_TENSOR.V_ENC_OUTPUT_NORM, + MODEL_TENSOR.V_ENC_ATTN_O, + MODEL_TENSOR.V_ENC_ATTN_O_NORM, + MODEL_TENSOR.V_ENC_POST_ATTN_NORM, MODEL_TENSOR.V_ENC_FFN_UP, MODEL_TENSOR.V_ENC_FFN_GATE, MODEL_TENSOR.V_ENC_FFN_DOWN, @@ -816,6 +875,24 @@ class MODEL_TENSOR(IntEnum): MODEL_TENSOR.V_RESMPL_QUERY, MODEL_TENSOR.V_TOK_EMBD_IMG_BREAK, MODEL_TENSOR.V_MM_PATCH_MERGER, + # audio + MODEL_TENSOR.A_ENC_EMBD_POS, + MODEL_TENSOR.A_ENC_CONV1D, + MODEL_TENSOR.A_PRE_NORM, + MODEL_TENSOR.A_POST_NORM, + MODEL_TENSOR.A_ENC_ATTN_Q, + MODEL_TENSOR.A_ENC_ATTN_K, + MODEL_TENSOR.A_ENC_ATTN_V, + MODEL_TENSOR.A_ENC_INPUT_NORM, + MODEL_TENSOR.A_ENC_OUTPUT, + MODEL_TENSOR.A_ENC_OUTPUT_NORM, + MODEL_TENSOR.A_ENC_FFN_UP, + MODEL_TENSOR.A_ENC_FFN_GATE, + MODEL_TENSOR.A_ENC_FFN_DOWN, + MODEL_TENSOR.A_MMPROJ, + MODEL_TENSOR.A_MMPROJ_FC, + MODEL_TENSOR.A_MM_NORM_PRE, + MODEL_TENSOR.A_MM_NORM_MID, ], MODEL_ARCH.LLAMA: [ MODEL_TENSOR.TOKEN_EMBD, @@ -959,6 +1036,7 @@ class MODEL_TENSOR(IntEnum): MODEL_TENSOR.POS_EMBD, MODEL_TENSOR.OUTPUT_NORM, MODEL_TENSOR.ATTN_OUT_NORM, + MODEL_TENSOR.ATTN_QKV, MODEL_TENSOR.ATTN_Q, MODEL_TENSOR.ATTN_K, MODEL_TENSOR.ATTN_V, @@ -2180,9 +2258,13 @@ class VisionProjectorType: GEMMA3 = "gemma3" IDEFICS3 = "idefics3" PIXTRAL = "pixtral" + LLAMA4 = "llama4" QWEN2VL = "qwen2vl_merger" QWEN25VL = "qwen2.5vl_merger" + ULTRAVOX = "ultravox" INTERNVL = "internvl" + QWEN2A = "qwen2a" # audio + QWEN25O = "qwen2.5o" # omni # Items here are (block size, type size) diff --git a/gguf-py/gguf/gguf_reader.py b/gguf-py/gguf/gguf_reader.py index 5991cdb76beac..d87e8f72321b3 100644 --- a/gguf-py/gguf/gguf_reader.py +++ b/gguf-py/gguf/gguf_reader.py @@ -251,7 +251,7 @@ def _get_field_parts( offs += curr_size return offs - orig_offs, aparts, data_idxs, types # We can't deal with this one. - raise ValueError('Unknown/unhandled field type {gtype}') + raise ValueError(f'Unknown/unhandled field type {gtype}') def _get_tensor_info_field(self, orig_offs: int) -> ReaderField: offs = orig_offs diff --git a/gguf-py/gguf/gguf_writer.py b/gguf-py/gguf/gguf_writer.py index ff50d3de31287..de6e45ae827b9 100644 --- a/gguf-py/gguf/gguf_writer.py +++ b/gguf-py/gguf/gguf_writer.py @@ -49,6 +49,7 @@ class TensorInfo: class GGUFValue: value: Any type: GGUFValueType + sub_type: GGUFValueType | None = None class WriterState(Enum): @@ -238,7 +239,7 @@ def write_kv_data_to_file(self) -> None: for key, val in kv_data.items(): kv_bytes += self._pack_val(key, GGUFValueType.STRING, add_vtype=False) - kv_bytes += self._pack_val(val.value, val.type, add_vtype=True) + kv_bytes += self._pack_val(val.value, val.type, add_vtype=True, sub_type=val.sub_type) fout.write(kv_bytes) @@ -268,11 +269,11 @@ def write_ti_data_to_file(self) -> None: fout.flush() self.state = WriterState.TI_DATA - def add_key_value(self, key: str, val: Any, vtype: GGUFValueType) -> None: + def add_key_value(self, key: str, val: Any, vtype: GGUFValueType, sub_type: GGUFValueType | None = None) -> None: if any(key in kv_data for kv_data in self.kv_data): raise ValueError(f'Duplicated key name {key!r}') - self.kv_data[0][key] = GGUFValue(value=val, type=vtype) + self.kv_data[0][key] = GGUFValue(value=val, type=vtype, sub_type=sub_type) def add_uint8(self, key: str, val: int) -> None: self.add_key_value(key,val, GGUFValueType.UINT8) @@ -896,7 +897,7 @@ def add_add_space_prefix(self, value: bool) -> None: def add_remove_extra_whitespaces(self, value: bool) -> None: self.add_bool(Keys.Tokenizer.REMOVE_EXTRA_WS, value) - def add_precompiled_charsmap(self, charsmap: Sequence[bytes]) -> None: + def add_precompiled_charsmap(self, charsmap: bytes) -> None: self.add_array(Keys.Tokenizer.PRECOMPILED_CHARSMAP, charsmap) def add_chat_template(self, value: str | Sequence[Mapping[str, str]]) -> None: @@ -936,12 +937,18 @@ def add_eom_token_id(self, id: int) -> None: # for vision models + def add_clip_has_vision_encoder(self, value: bool) -> None: + self.add_bool(Keys.Clip.HAS_VISION_ENCODER, value) + + def add_clip_has_audio_encoder(self, value: bool) -> None: + self.add_bool(Keys.Clip.HAS_AUDIO_ENCODER, value) + + def add_clip_projector_type(self, value: str) -> None: + self.add_string(Keys.Clip.PROJECTOR_TYPE, value) + def add_vision_projection_dim(self, value: int) -> None: self.add_uint32(Keys.ClipVision.PROJECTION_DIM, value) - def add_vision_has_vision_encoder(self, value: bool) -> None: - self.add_bool(Keys.ClipVision.HAS_VISION_ENCODER, value) - def add_vision_patch_size(self, value: int) -> None: self.add_uint32(Keys.ClipVision.PATCH_SIZE, value) @@ -957,9 +964,6 @@ def add_vision_block_count(self, value: int) -> None: def add_vision_head_count(self, value: int) -> None: self.add_uint32(Keys.ClipVision.Attention.HEAD_COUNT, value) - def add_vision_projector_type(self, value: str) -> None: - self.add_string(Keys.ClipVision.PROJECTOR_TYPE, value) - def add_vision_attention_layernorm_eps(self, value: float) -> None: self.add_float32(Keys.ClipVision.Attention.LAYERNORM_EPS, value) @@ -987,13 +991,39 @@ def add_vision_projector_scale_factor(self, value: int) -> None: def add_vision_n_wa_pattern(self, value: int) -> None: self.add_uint32(Keys.ClipVision.N_WA_PATTERN, value) + # audio models + + def add_audio_projection_dim(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.PROJECTION_DIM, value) + + def add_audio_embedding_length(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.EMBEDDING_LENGTH, value) + + def add_audio_feed_forward_length(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.FEED_FORWARD_LENGTH, value) + + def add_audio_block_count(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.BLOCK_COUNT, value) + + def add_audio_head_count(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.Attention.HEAD_COUNT, value) + + def add_audio_attention_layernorm_eps(self, value: float) -> None: + self.add_float32(Keys.ClipAudio.Attention.LAYERNORM_EPS, value) + + def add_audio_num_mel_bins(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.NUM_MEL_BINS, value) + + def add_audio_stack_factor(self, value: int) -> None: + self.add_uint32(Keys.ClipAudio.Projector.STACK_FACTOR, value) + def _pack(self, fmt: str, value: Any, skip_pack_prefix: bool = False) -> bytes: pack_prefix = '' if not skip_pack_prefix: pack_prefix = '<' if self.endianess == GGUFEndian.LITTLE else '>' return struct.pack(f'{pack_prefix}{fmt}', value) - def _pack_val(self, val: Any, vtype: GGUFValueType, add_vtype: bool) -> bytes: + def _pack_val(self, val: Any, vtype: GGUFValueType, add_vtype: bool, sub_type: GGUFValueType | None = None) -> bytes: kv_data = bytearray() if add_vtype: @@ -1014,7 +1044,9 @@ def _pack_val(self, val: Any, vtype: GGUFValueType, add_vtype: bool) -> bytes: if len(val) == 0: raise ValueError("Invalid GGUF metadata array. Empty array") - if isinstance(val, bytes): + if sub_type is not None: + ltype = sub_type + elif isinstance(val, bytes): ltype = GGUFValueType.UINT8 else: ltype = GGUFValueType.get_type(val[0]) diff --git a/gguf-py/gguf/scripts/gguf_editor_gui.py b/gguf-py/gguf/scripts/gguf_editor_gui.py index 3d38b5cbabf8b..05f4db0f8cdc8 100755 --- a/gguf-py/gguf/scripts/gguf_editor_gui.py +++ b/gguf-py/gguf/scripts/gguf_editor_gui.py @@ -1521,19 +1521,21 @@ def save_file(self): continue # Apply changes if any + sub_type = None if field.name in self.metadata_changes: value_type, value = self.metadata_changes[field.name] if value_type == GGUFValueType.ARRAY: # Handle array values - element_type, array_values = value - writer.add_array(field.name, array_values) - else: - writer.add_key_value(field.name, value, value_type) + sub_type, value = value else: # Copy original value value = field.contents() - if value is not None and field.types: - writer.add_key_value(field.name, value, field.types[0]) + value_type = field.types[0] + if value_type == GGUFValueType.ARRAY: + sub_type = field.types[-1] + + if value is not None: + writer.add_key_value(field.name, value, value_type, sub_type=sub_type) # Add new metadata for key, (value_type, value) in self.metadata_changes.items(): @@ -1541,7 +1543,12 @@ def save_file(self): if self.reader.get_field(key) is not None: continue - writer.add_key_value(key, value, value_type) + sub_type = None + if value_type == GGUFValueType.ARRAY: + # Handle array values + sub_type, value = value + + writer.add_key_value(key, value, value_type, sub_type=sub_type) # Add tensors (including data) for tensor in self.reader.tensors: diff --git a/gguf-py/gguf/scripts/gguf_new_metadata.py b/gguf-py/gguf/scripts/gguf_new_metadata.py index 7aff6c9259a1f..63f2300348ed0 100755 --- a/gguf-py/gguf/scripts/gguf_new_metadata.py +++ b/gguf-py/gguf/scripts/gguf_new_metadata.py @@ -24,6 +24,7 @@ class MetadataDetails(NamedTuple): type: gguf.GGUFValueType value: Any description: str = '' + sub_type: gguf.GGUFValueType | None = None def get_field_data(reader: gguf.GGUFReader, key: str) -> Any: @@ -57,7 +58,9 @@ def copy_with_new_metadata(reader: gguf.GGUFReader, writer: gguf.GGUFWriter, new logger.debug(f'Removing {field.name}') continue - old_val = MetadataDetails(field.types[0], field.contents()) + val_type = field.types[0] + sub_type = field.types[-1] if val_type == gguf.GGUFValueType.ARRAY else None + old_val = MetadataDetails(val_type, field.contents(), sub_type=sub_type) val = new_metadata.get(field.name, old_val) if field.name in new_metadata: @@ -67,7 +70,7 @@ def copy_with_new_metadata(reader: gguf.GGUFReader, writer: gguf.GGUFWriter, new logger.debug(f'Copying {field.name}') if val.value is not None: - writer.add_key_value(field.name, val.value, val.type) + writer.add_key_value(field.name, val.value, val.type, sub_type=sub_type if val.sub_type is None else val.sub_type) if gguf.Keys.Tokenizer.CHAT_TEMPLATE in new_metadata: logger.debug('Adding chat template(s)') diff --git a/gguf-py/gguf/tensor_mapping.py b/gguf-py/gguf/tensor_mapping.py index dadb4fd94934e..93dd1d8028f3d 100644 --- a/gguf-py/gguf/tensor_mapping.py +++ b/gguf-py/gguf/tensor_mapping.py @@ -157,6 +157,7 @@ class TensorNameMap: "h.{bid}.attn.c_attn", # gpt2 "transformer.h.{bid}.mixer.Wqkv", # phi2 "encoder.layers.{bid}.attn.Wqkv", # nomic-bert + "encoder.layers.{bid}.mixer.Wqkv", # jina "model.layers.{bid}.self_attn.qkv_proj", # phi3 "encoder.layers.{bid}.self_attention.query_key_value", # chatglm "transformer.layers.{bid}.attn.qkv_proj", # openelm @@ -168,6 +169,7 @@ class TensorNameMap: "model.layers.{bid}.self_attn.q_proj_no_perm", # llama-custom "layers.{bid}.attention.wq", # llama-pth "encoder.layer.{bid}.attention.self.query", # bert + "transformer.layer.{bid}.attention.q_lin", # distillbert "transformer.h.{bid}.attn.q_proj", # gpt-j "model.layers.layers.{bid}.self_attn.q_proj", # plamo "model.layers.{bid}.attention.wq", # internlm2 @@ -182,6 +184,7 @@ class TensorNameMap: "model.layers.{bid}.self_attn.k_proj_no_perm", # llama-custom "layers.{bid}.attention.wk", # llama-pth "encoder.layer.{bid}.attention.self.key", # bert + "transformer.layer.{bid}.attention.k_lin", # distillbert "transformer.h.{bid}.attn.k_proj", # gpt-j "transformer.h.{bid}.attn.k", # refact "model.layers.layers.{bid}.self_attn.k_proj", # plamo @@ -196,6 +199,7 @@ class TensorNameMap: "model.layers.{bid}.self_attn.v_proj", # llama-hf nemotron olmoe olmo2 phimoe "layers.{bid}.attention.wv", # llama-pth "encoder.layer.{bid}.attention.self.value", # bert + "transformer.layer.{bid}.attention.v_lin", # distillbert "transformer.h.{bid}.attn.v_proj", # gpt-j "transformer.h.{bid}.attn.v", # refact "model.layers.layers.{bid}.self_attn.v_proj", # plamo @@ -216,6 +220,7 @@ class TensorNameMap: "model.layers.{bid}.self_attn.linear_attn", # deci "layers.{bid}.attention.wo", # llama-pth "encoder.layer.{bid}.attention.output.dense", # bert + "transformer.layer.{bid}.attention.out_lin", # distillbert "transformer.h.{bid}.attn.out_proj", # gpt-j "language_model.encoder.layers.{bid}.self_attention.dense", # persimmon "model.layers.{bid}.self_attn.dense", # persimmon @@ -224,6 +229,7 @@ class TensorNameMap: "model.layers.layers.{bid}.self_attn.o_proj", # plamo "model.layers.{bid}.attention.wo", # internlm2 "encoder.layers.{bid}.attn.out_proj", # nomic-bert + "encoder.layers.{bid}.mixer.out_proj", # jina "transformer.decoder_layer.{bid}.multi_head_attention.linear", # Grok "transformer.blocks.{bid}.norm_attn_norm.attn.out_proj", # dbrx "encoder.layers.{bid}.self_attention.dense", # chatglm @@ -235,6 +241,7 @@ class TensorNameMap: # Attention output norm MODEL_TENSOR.ATTN_OUT_NORM: ( "encoder.layer.{bid}.attention.output.LayerNorm", # bert + "transformer.layer.{bid}.sa_layer_norm", # distillbert "encoder.layers.{bid}.norm1", # nomic-bert "transformer.decoder_layer.{bid}.rms_norm_1", # Grok "transformer.blocks.{bid}.norm_attn_norm.norm_2", # dbrx @@ -311,6 +318,7 @@ class TensorNameMap: "model.layers.{bid}.mlp.up_proj", # llama-hf refact nemotron olmo2 "layers.{bid}.feed_forward.w3", # llama-pth "encoder.layer.{bid}.intermediate.dense", # bert + "transformer.layer.{bid}.ffn.lin1", # distillbert "transformer.h.{bid}.mlp.fc_in", # gpt-j "transformer.h.{bid}.mlp.linear_3", # refact "language_model.encoder.layers.{bid}.mlp.dense_h_to_4h", # persimmon @@ -394,6 +402,7 @@ class TensorNameMap: "model.layers.{bid}.mlp.down_proj", # llama-hf nemotron olmo2 "layers.{bid}.feed_forward.w2", # llama-pth "encoder.layer.{bid}.output.dense", # bert + "transformer.layer.{bid}.ffn.lin2", # distillbert "transformer.h.{bid}.mlp.fc_out", # gpt-j "language_model.encoder.layers.{bid}.mlp.dense_4h_to_h", # persimmon "model.layers.{bid}.mlp.dense_4h_to_h", # persimmon @@ -455,6 +464,7 @@ class TensorNameMap: MODEL_TENSOR.LAYER_OUT_NORM: ( "encoder.layer.{bid}.output.LayerNorm", # bert + "transformer.layer.{bid}.output_layer_norm", # distillbert "encoder.layers.{bid}.norm2", # nomic-bert "transformer.decoder_layer.{bid}.rms_norm_3", # Grok "encoder.layer.{bid}.mlp.layernorm", # jina-bert-v2 @@ -825,6 +835,7 @@ class TensorNameMap: MODEL_TENSOR.CLS: ( "classifier", # jina "classifier.dense", # roberta + "pre_classifier", # distillbert ), MODEL_TENSOR.CLS_OUT: ( @@ -906,6 +917,7 @@ class TensorNameMap: MODEL_TENSOR.V_MMPROJ_MLP: ( "model.mm_projector.mlp.mlp.{bid}", + "vision_model.vision_adapter.mlp.fc{bid}", # llama 4 "mlp1.{bid}", # InternVL ), @@ -915,6 +927,7 @@ class TensorNameMap: MODEL_TENSOR.V_ENC_EMBD_CLS: ( "vision_tower.vision_model.embeddings.class_embedding", + "vision_model.class_embedding", # llama 4 ), MODEL_TENSOR.V_ENC_EMBD_PATCH: ( @@ -922,6 +935,7 @@ class TensorNameMap: "vpm.embeddings.patch_embedding", "model.vision_model.embeddings.patch_embedding", # SmolVLM "vision_tower.patch_conv", # pixtral + "vision_model.patch_embedding.linear", # llama 4 "visual.patch_embed.proj", # qwen2vl ), @@ -929,12 +943,14 @@ class TensorNameMap: "vision_tower.vision_model.embeddings.position_embedding", "vpm.embeddings.position_embedding", "model.vision_model.embeddings.position_embedding", # SmolVLM + "vision_model.positional_embedding_vlm", # llama 4 ), MODEL_TENSOR.V_ENC_ATTN_Q: ( "vision_tower.vision_model.encoder.layers.{bid}.self_attn.q_proj", "vpm.encoder.layers.{bid}.self_attn.q_proj", "model.vision_model.encoder.layers.{bid}.self_attn.q_proj", # SmolVLM + "vision_model.model.layers.{bid}.self_attn.q_proj", # llama4 "vision_tower.transformer.layers.{bid}.attention.q_proj", # pixtral "visual.blocks.{bid}.attn.q", # qwen2vl, generated ), @@ -947,6 +963,7 @@ class TensorNameMap: "vision_tower.vision_model.encoder.layers.{bid}.self_attn.k_proj", "vpm.encoder.layers.{bid}.self_attn.k_proj", "model.vision_model.encoder.layers.{bid}.self_attn.k_proj", # SmolVLM + "vision_model.model.layers.{bid}.self_attn.k_proj", # llama4 "vision_tower.transformer.layers.{bid}.attention.k_proj", # pixtral "visual.blocks.{bid}.attn.k", # qwen2vl, generated ), @@ -959,6 +976,7 @@ class TensorNameMap: "vision_tower.vision_model.encoder.layers.{bid}.self_attn.v_proj", "vpm.encoder.layers.{bid}.self_attn.v_proj", "model.vision_model.encoder.layers.{bid}.self_attn.v_proj", # SmolVLM + "vision_model.model.layers.{bid}.self_attn.v_proj", # llama4 "vision_tower.transformer.layers.{bid}.attention.v_proj", # pixtral "visual.blocks.{bid}.attn.v", # qwen2vl, generated ), @@ -969,23 +987,26 @@ class TensorNameMap: "vpm.encoder.layers.{bid}.layer_norm1", "model.vision_model.encoder.layers.{bid}.layer_norm1", # SmolVLM "vision_tower.transformer.layers.{bid}.attention_norm", # pixtral + "vision_model.model.layers.{bid}.input_layernorm", # llama4 "visual.blocks.{bid}.norm1", # qwen2vl ), - MODEL_TENSOR.V_ENC_OUTPUT: ( + MODEL_TENSOR.V_ENC_ATTN_O: ( "vision_tower.vision_model.encoder.layers.{bid}.self_attn.out_proj", "vision_tower.vision_model.encoder.layers.{bid}.attn.proj", # InternVL "vpm.encoder.layers.{bid}.self_attn.out_proj", "model.vision_model.encoder.layers.{bid}.self_attn.out_proj", # SmolVLM + "vision_model.model.layers.{bid}.self_attn.o_proj", # llama4 "vision_tower.transformer.layers.{bid}.attention.o_proj", # pixtral "visual.blocks.{bid}.attn.proj", # qwen2vl ), - MODEL_TENSOR.V_ENC_OUTPUT_NORM: ( + MODEL_TENSOR.V_ENC_POST_ATTN_NORM: ( "vision_tower.vision_model.encoder.layers.{bid}.layer_norm2", "vision_tower.vision_model.encoder.layers.{bid}.norm2", # InternVL "vpm.encoder.layers.{bid}.layer_norm2", "model.vision_model.encoder.layers.{bid}.layer_norm2", # SmolVLM + "vision_model.model.layers.{bid}.post_attention_layernorm", # llama4 "vision_tower.transformer.layers.{bid}.ffn_norm", # pixtral "visual.blocks.{bid}.norm2", # qwen2vl ), @@ -995,6 +1016,7 @@ class TensorNameMap: "vpm.encoder.layers.{bid}.mlp.fc1", "model.vision_model.encoder.layers.{bid}.mlp.fc1", # SmolVLM, gemma3 "vision_tower.transformer.layers.{bid}.feed_forward.up_proj", # pixtral + "vision_model.model.layers.{bid}.mlp.fc1", # llama4 "visual.blocks.{bid}.mlp.fc1", # qwen2vl "visual.blocks.{bid}.mlp.up_proj", # qwen2.5vl ), @@ -1009,6 +1031,7 @@ class TensorNameMap: "vpm.encoder.layers.{bid}.mlp.fc2", "model.vision_model.encoder.layers.{bid}.mlp.fc2", # SmolVLM, gemma3 "vision_tower.transformer.layers.{bid}.feed_forward.down_proj", # pixtral + "vision_model.model.layers.{bid}.mlp.fc2", # llama4 "visual.blocks.{bid}.mlp.fc2", # qwen2vl "visual.blocks.{bid}.mlp.down_proj", # qwen2.5vl ), @@ -1024,11 +1047,13 @@ class TensorNameMap: MODEL_TENSOR.V_PRE_NORM: ( "vision_tower.vision_model.pre_layrnorm", "vision_tower.ln_pre", # pixtral + "vision_model.layernorm_pre", # llama4 ), MODEL_TENSOR.V_POST_NORM: ( "vision_tower.vision_model.post_layernorm", "model.vision_model.post_layernorm", # SmolVLM + "vision_model.layernorm_post", # llama4 "visual.merger.ln_q", # qwen2vl ), @@ -1095,6 +1120,77 @@ class TensorNameMap: MODEL_TENSOR.V_MM_PATCH_MERGER: ( "multi_modal_projector.patch_merger.merging_layer", # mistral small 3.1 ), + + # audio (mtmd) + + MODEL_TENSOR.A_ENC_EMBD_POS: ( + "audio_tower.embed_positions", # ultravox + ), + + MODEL_TENSOR.A_ENC_CONV1D: ( + "audio_tower.conv{bid}", # ultravox + ), + + MODEL_TENSOR.A_PRE_NORM: (), + + MODEL_TENSOR.A_POST_NORM: ( + "audio_tower.layer_norm", # ultravox + "audio_tower.ln_post", # qwen2omni + ), + + MODEL_TENSOR.A_ENC_ATTN_Q: ( + "audio_tower.layers.{bid}.self_attn.q_proj", # ultravox + ), + + MODEL_TENSOR.A_ENC_ATTN_K: ( + "audio_tower.layers.{bid}.self_attn.k_proj", # ultravox + ), + + MODEL_TENSOR.A_ENC_ATTN_V: ( + "audio_tower.layers.{bid}.self_attn.v_proj", # ultravox + ), + + MODEL_TENSOR.A_ENC_INPUT_NORM: ( + "audio_tower.layers.{bid}.self_attn_layer_norm", # ultravox + ), + + MODEL_TENSOR.A_ENC_OUTPUT: ( + "audio_tower.layers.{bid}.self_attn.out_proj", # ultravox + ), + + MODEL_TENSOR.A_ENC_OUTPUT_NORM: ( + "audio_tower.layers.{bid}.final_layer_norm", # ultravox + ), + + MODEL_TENSOR.A_ENC_FFN_UP: ( + "audio_tower.layers.{bid}.fc1", # ultravox + ), + + MODEL_TENSOR.A_ENC_FFN_GATE: (), + + MODEL_TENSOR.A_ENC_FFN_DOWN: ( + "audio_tower.layers.{bid}.fc2", # ultravox + ), + + # note: some tensors below has "audio." pseudo-prefix, to prevent conflicts with vision tensors + # this prefix is added in the conversion code in modify_tensors() + + MODEL_TENSOR.A_MMPROJ: ( + "audio.multi_modal_projector.linear_{bid}", # ultravox + ), + + MODEL_TENSOR.A_MMPROJ_FC: ( + "audio.multi_modal_projector.linear", # qwen2audio + "audio_tower.proj", # qwen2omni + ), + + MODEL_TENSOR.A_MM_NORM_PRE: ( + "audio.multi_modal_projector.ln_pre", # ultravox + ), + + MODEL_TENSOR.A_MM_NORM_MID: ( + "audio.multi_modal_projector.ln_mid", # ultravox + ), } # architecture-specific block mappings diff --git a/gguf-py/gguf/utility.py b/gguf-py/gguf/utility.py index e5251aef8c832..00adcbc937398 100644 --- a/gguf-py/gguf/utility.py +++ b/gguf-py/gguf/utility.py @@ -231,7 +231,7 @@ def get_data_by_range(cls, url: str, start: int, size: int = -1) -> bytes: response.raise_for_status() # Get raw byte data - return response.content[:size] + return response.content[slice(size if size > -1 else None)] @classmethod def check_file_exist(cls, url: str) -> bool: diff --git a/gguf-py/pyproject.toml b/gguf-py/pyproject.toml index bb9b86ace7515..f11351cba1767 100644 --- a/gguf-py/pyproject.toml +++ b/gguf-py/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gguf" -version = "0.16.3" +version = "0.17.0" description = "Read and write ML models in GGUF for GGML" authors = ["GGML "] packages = [ diff --git a/include/llama.h b/include/llama.h index 99e5fba244fcc..da0f652cfd63a 100644 --- a/include/llama.h +++ b/include/llama.h @@ -259,9 +259,9 @@ extern "C" { llama_token * token; float * embd; llama_pos * pos; - int32_t * n_seq_id; - llama_seq_id ** seq_id; - int8_t * logits; // TODO: rename this to "output" + int32_t * n_seq_id; // TODO: remove, should belong to only 1 sequence + llama_seq_id ** seq_id; // TODO: become llama_seq_id * seq_id; + int8_t * logits; // TODO: rename this to "output" } llama_batch; enum llama_model_kv_override_type { @@ -361,10 +361,13 @@ extern "C" { // Keep the booleans together and at the end of the struct to avoid misalignment during copy-by-value. bool embeddings; // if true, extract embeddings (together with logits) - bool offload_kqv; // whether to offload the KQV ops (including the KV cache) to GPU - bool flash_attn; // whether to use flash attention [EXPERIMENTAL] - bool no_perf; // whether to measure performance timings - bool op_offload; // whether to offload host tensor operations to device + bool offload_kqv; // offload the KQV ops (including the KV cache) to GPU + bool flash_attn; // use flash attention [EXPERIMENTAL] + bool no_perf; // measure performance timings + bool op_offload; // offload host tensor operations to device + bool swa_full; // use full-size SWA cache (https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055) + // NOTE: setting to false when n_seq_max > 1 can cause bad performance in some cases + // ref: https://github.com/ggml-org/llama.cpp/pull/13845#issuecomment-2924800573 }; // model quantization parameters @@ -470,6 +473,7 @@ extern "C" { LLAMA_API int64_t llama_time_us(void); LLAMA_API size_t llama_max_devices(void); + LLAMA_API size_t llama_max_parallel_sequences(void); LLAMA_API bool llama_supports_mmap (void); LLAMA_API bool llama_supports_mlock (void); @@ -500,6 +504,7 @@ extern "C" { LLAMA_API int32_t llama_model_n_layer (const struct llama_model * model); LLAMA_API int32_t llama_model_n_head (const struct llama_model * model); LLAMA_API int32_t llama_model_n_head_kv (const struct llama_model * model); + LLAMA_API int32_t llama_model_n_swa (const struct llama_model * model); // Get the model's RoPE frequency scaling factor LLAMA_API float llama_model_rope_freq_scale_train(const struct llama_model * model); @@ -607,71 +612,14 @@ extern "C" { // KV cache // - // TODO: start using struct llama_kv_cache - - // Information associated with an individual cell in the KV cache view. - struct llama_kv_cache_view_cell { - // The position for this cell. Takes KV cache shifts into account. - // May be negative if the cell is not populated. - llama_pos pos; - }; - - // An updateable view of the KV cache. - struct llama_kv_cache_view { - // Number of KV cache cells. This will be the same as the context size. - int32_t n_cells; - - // Maximum number of sequences that can exist in a cell. It's not an error - // if there are more sequences in a cell than this value, however they will - // not be visible in the view cells_sequences. - int32_t n_seq_max; - - // Number of tokens in the cache. For example, if there are two populated - // cells, the first with 1 sequence id in it and the second with 2 sequence - // ids then you'll have 3 tokens. - int32_t token_count; - - // Number of populated cache cells. - int32_t used_cells; - - // Maximum contiguous empty slots in the cache. - int32_t max_contiguous; - - // Index to the start of the max_contiguous slot range. Can be negative - // when cache is full. - int32_t max_contiguous_idx; - - // Information for an individual cell. - struct llama_kv_cache_view_cell * cells; - - // The sequences for each cell. There will be n_seq_max items per cell. - llama_seq_id * cells_sequences; - }; - - // Create an empty KV cache view. (use only for debugging purposes) - LLAMA_API struct llama_kv_cache_view llama_kv_cache_view_init(const struct llama_context * ctx, int32_t n_seq_max); - - // Free a KV cache view. (use only for debugging purposes) - LLAMA_API void llama_kv_cache_view_free(struct llama_kv_cache_view * view); - - // Update the KV cache view structure with the current state of the KV cache. (use only for debugging purposes) - // TODO: change signature to llama_kv_cache_view_update(struct llama_kv_cache_view * view, const struct llama_context * ctx) - LLAMA_API void llama_kv_cache_view_update(const struct llama_context * ctx, struct llama_kv_cache_view * view); - - /// - // Returns the number of tokens in the KV cache (slow, use only for debug) // If a KV cell has multiple sequences assigned to it, it will be counted multiple times - LLAMA_API int32_t llama_kv_self_n_tokens(const struct llama_context * ctx); - - DEPRECATED(LLAMA_API int32_t llama_get_kv_cache_token_count(const struct llama_context * ctx), - "use llama_kv_self_n_tokens instead"); + DEPRECATED(LLAMA_API int32_t llama_kv_self_n_tokens(const struct llama_context * ctx), + "Use llama_kv_self_seq_pos_max() and llama_kv_self_seq_pos_min() instead (https://github.com/ggml-org/llama.cpp/issues/13793)"); // Returns the number of used KV cells (i.e. have at least one sequence assigned to them) - LLAMA_API int32_t llama_kv_self_used_cells(const struct llama_context * ctx); - - DEPRECATED(LLAMA_API int32_t llama_get_kv_cache_used_cells(const struct llama_context * ctx), - "use llama_kv_self_used_cells instead"); + DEPRECATED(LLAMA_API int32_t llama_kv_self_used_cells(const struct llama_context * ctx), + "Use llama_kv_self_seq_pos_max() and llama_kv_self_seq_pos_min() instead (https://github.com/ggml-org/llama.cpp/issues/13793)"); // Clear the KV cache - both cell info is erased and KV data is zeroed LLAMA_API void llama_kv_self_clear( @@ -707,7 +655,6 @@ extern "C" { // Adds relative position "delta" to all tokens that belong to the specified sequence and have positions in [p0, p1) // If the KV cache is RoPEd, the KV data is updated accordingly: // - lazily on next llama_decode() - // - explicitly with llama_kv_self_update() // p0 < 0 : [0, p1] // p1 < 0 : [p0, inf) LLAMA_API void llama_kv_self_seq_add( @@ -720,7 +667,6 @@ extern "C" { // Integer division of the positions by factor of `d > 1` // If the KV cache is RoPEd, the KV data is updated accordingly: // - lazily on next llama_decode() - // - explicitly with llama_kv_self_update() // p0 < 0 : [0, p1] // p1 < 0 : [p0, inf) LLAMA_API void llama_kv_self_seq_div( @@ -730,77 +676,33 @@ extern "C" { llama_pos p1, int d); + // Returns the smallest position present in the KV cache for the specified sequence + // This is typically non-zero only for SWA caches + // Note that all positions in the range [pos_min, pos_max] are guaranteed to be present in the KV cache + // Return -1 if the sequence is empty + LLAMA_API llama_pos llama_kv_self_seq_pos_min( + struct llama_context * ctx, + llama_seq_id seq_id); + // Returns the largest position present in the KV cache for the specified sequence + // Note that all positions in the range [pos_min, pos_max] are guaranteed to be present in the KV cache + // Return -1 if the sequence is empty LLAMA_API llama_pos llama_kv_self_seq_pos_max( struct llama_context * ctx, - llama_seq_id seq_id); + llama_seq_id seq_id); // Defragment the KV cache // This will be applied: // - lazily on next llama_decode() - // - explicitly with llama_kv_self_update() - LLAMA_API void llama_kv_self_defrag(struct llama_context * ctx); + LLAMA_API DEPRECATED(void llama_kv_self_defrag(struct llama_context * ctx), + "simply remove this call, the context will automatically decide when to do a defragmentation based on 'defrag_thold'"); // Check if the context supports KV cache shifting LLAMA_API bool llama_kv_self_can_shift(const struct llama_context * ctx); // Apply the KV cache updates (such as K-shifts, defragmentation, etc.) - LLAMA_API void llama_kv_self_update(struct llama_context * ctx); - - DEPRECATED(LLAMA_API void llama_kv_cache_clear( - struct llama_context * ctx), - "use llama_kv_self_clear instead"); - - DEPRECATED(LLAMA_API bool llama_kv_cache_seq_rm( - struct llama_context * ctx, - llama_seq_id seq_id, - llama_pos p0, - llama_pos p1), - "use llama_kv_self_seq_rm instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_seq_cp( - struct llama_context * ctx, - llama_seq_id seq_id_src, - llama_seq_id seq_id_dst, - llama_pos p0, - llama_pos p1), - "use llama_kv_self_seq_cp instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_seq_keep( - struct llama_context * ctx, - llama_seq_id seq_id), - "use llama_kv_self_seq_keep instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_seq_add( - struct llama_context * ctx, - llama_seq_id seq_id, - llama_pos p0, - llama_pos p1, - llama_pos delta), - "use llama_kv_self_seq_add instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_seq_div( - struct llama_context * ctx, - llama_seq_id seq_id, - llama_pos p0, - llama_pos p1, - int d), - "use llama_kv_self_seq_div instead"); - - DEPRECATED(LLAMA_API llama_pos llama_kv_cache_seq_pos_max( - struct llama_context * ctx, - llama_seq_id seq_id), - "use llama_kv_self_seq_pos_max instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_defrag(struct llama_context * ctx), - "use llama_kv_self_defrag instead"); - - DEPRECATED(LLAMA_API bool llama_kv_cache_can_shift(const struct llama_context * ctx), - "use llama_kv_self_can_shift instead"); - - DEPRECATED(LLAMA_API void llama_kv_cache_update(struct llama_context * ctx), - "use llama_kv_self_update instead"); - + LLAMA_API DEPRECATED(void llama_kv_self_update(struct llama_context * ctx), + "simply remove this call, updates are applied lazily on the next llama_decode()"); // // State / sessions @@ -943,9 +845,12 @@ extern "C" { // Requires KV cache. // For encode-decoder contexts, processes the batch using the decoder. // Positive return values does not mean a fatal error, but rather a warning. - // 0 - success - // 1 - could not find a KV slot for the batch (try reducing the size of the batch or increase the context) - // < 0 - error. the KV cache state is restored to the state before this call + // Upon non-zero return values, the KV cache state is restored to the state before this call + // 0 - success + // 1 - could not find a KV slot for the batch (try reducing the size of the batch or increase the context) + // 2 - aborted + // -1 - invalid input batch + // < -1 - error LLAMA_API int32_t llama_decode( struct llama_context * ctx, struct llama_batch batch); diff --git a/models/ggml-vocab-bert-bge.gguf.inp b/models/ggml-vocab-bert-bge.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-bert-bge.gguf.inp +++ b/models/ggml-vocab-bert-bge.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-bert-bge.gguf.out b/models/ggml-vocab-bert-bge.gguf.out index a62566ce75676..b1c49672fadad 100644 --- a/models/ggml-vocab-bert-bge.gguf.out +++ b/models/ggml-vocab-bert-bge.gguf.out @@ -1,5 +1,5 @@ 29464 2094 1018 1092 2706 - 11865 17875 + 9706 7959 2140 diff --git a/models/ggml-vocab-chameleon.gguf.inp b/models/ggml-vocab-chameleon.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-chameleon.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-chameleon.gguf.out b/models/ggml-vocab-chameleon.gguf.out deleted file mode 100644 index 7c5413fee0adf..0000000000000 --- a/models/ggml-vocab-chameleon.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 17245 16604 16403 16604 33583 18355 - 16421 51153 - - 16604 - 16650 - 16650 16604 - 16581 - 16582 - 16582 16582 - 16582 16582 16582 - 16581 16582 - 31596 17394 - 34926 17394 - 31596 18671 - 34926 18671 - 34926 18671 16384 - 31596 16395 17394 16384 - 34926 16395 17394 16384 - 16811 16704 20410 16483 16631 16397 52854 - 16470 16399 16403 16407 16604 16406 35764 38185 51595 22592 26639 - 29479 23955 17012 20103 25527 27670 17408 19005 21473 24774 - 54254 42231 48084 29409 16617 61889 29409 16608 21954 16628 21954 16499 58445 29409 16607 58445 21954 16479 42231 21954 16611 21954 16607 21954 16633 21954 16611 29409 16607 21954 16615 - 52351 16604 16391 25825 16392 23686 16498 39161 18885 16618 16488 30853 16604 16391 54124 17153 25134 16656 18476 26169 16895 16392 62193 16611 16604 16391 24664 17153 57169 16721 16872 17073 17304 28729 16392 - 31596 - 34926 - 16650 31596 - 16650 34926 - 16696 31596 - 16696 31596 16582 16696 31596 - 16604 16391 - 16582 16604 16412 - 16390 22623 - 31596 16395 16712 16390 16828 16384 17674 16769 16732 23686 16607 16604 16414 24427 16623 41809 16495 28999 36469 45292 30197 16400 16402 16400 16403 16400 16404 16400 43969 65211 16636 - 16384 16384 16384 16384 16384 16384 - 16402 - 16402 16402 - 16402 16402 16402 - 16402 16402 16402 16402 - 16402 16402 16402 16402 16402 - 16402 16402 16402 16402 16402 16402 - 16402 16402 16402 16402 16402 16402 16402 - 16402 16402 16402 16402 16402 16402 16402 16402 - 16402 16402 16402 16402 16402 16402 16402 16402 16402 - 16418 19038 16639 16448 24315 33727 16467 - 18765 17981 - 16582 16604 16582 16582 16604 16582 16582 16582 16604 16581 16604 16581 16581 16604 16581 16582 16650 16582 16650 16604 16582 16696 16582 16696 16604 16582 52351 16604 16391 25825 16392 23686 16498 39161 18885 16618 16488 30853 16604 16391 54124 17153 25134 16656 18476 26169 16895 16392 62193 16611 20410 16483 16631 18885 16483 16631 16604 16402 16604 16402 16402 16604 16402 16402 16402 16604 16402 16402 16402 16402 16604 16402 16402 16402 16402 16402 16604 16402 16402 16402 16402 16402 16402 16604 16402 16402 16402 16402 16402 16402 16402 16604 16402 16402 16402 16402 16402 16402 16402 16402 16604 16402 16397 16402 16604 16402 16397 16397 16402 16604 16402 16397 16397 16397 16402 16604 54254 42231 48084 29409 16617 61889 29409 16608 21954 16628 21954 16499 58445 29409 16607 58445 21954 16479 42231 21954 16611 27683 16607 16604 16414 24427 16623 41809 16495 28999 36469 45292 30197 16400 16402 16400 16403 16400 16404 16400 43969 65211 16636 16604 16396 16396 16396 16396 16396 16396 16412 16412 16412 16412 16412 16412 16412 27268 23955 17012 20103 25527 27670 17408 19005 21473 24774 16604 16390 16390 16390 16390 16390 16390 16447 16447 16447 16447 16447 16447 16447 16385 16385 16385 16385 16397 16397 16397 16397 16397 16397 16384 16384 16384 16384 16384 16384 16414 16414 16414 16414 16414 16414 16687 16390 16690 16992 16604 16390 61797 16733 16390 16466 16986 16395 16604 16390 17879 16732 17811 16414 16604 16390 16428 16804 17811 16687 16390 16683 17190 16728 16395 16604 16390 16419 16732 16945 16991 25251 16414 17119 16390 38127 16641 16390 16459 16427 diff --git a/models/ggml-vocab-command-r.gguf.inp b/models/ggml-vocab-command-r.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-command-r.gguf.inp +++ b/models/ggml-vocab-command-r.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-command-r.gguf.out b/models/ggml-vocab-command-r.gguf.out index 3f6b418888740..0e3af72eb1c23 100644 --- a/models/ggml-vocab-command-r.gguf.out +++ b/models/ggml-vocab-command-r.gguf.out @@ -1,5 +1,5 @@ 2536 228 27 228 22957 6983 - 45 193433 + 90711 87 20910 228 1667 diff --git a/models/ggml-vocab-deepseek-coder.gguf.inp b/models/ggml-vocab-deepseek-coder.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-deepseek-coder.gguf.inp +++ b/models/ggml-vocab-deepseek-coder.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-deepseek-coder.gguf.out b/models/ggml-vocab-deepseek-coder.gguf.out index 52c4111a18d73..ef6bc5b8a3776 100644 --- a/models/ggml-vocab-deepseek-coder.gguf.out +++ b/models/ggml-vocab-deepseek-coder.gguf.out @@ -1,5 +1,5 @@ 1050 207 19 207 19192 4217 - 37 32009 71 6247 + 125 213 26862 282 207 243 diff --git a/models/ggml-vocab-deepseek-llm.gguf.inp b/models/ggml-vocab-deepseek-llm.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-deepseek-llm.gguf.inp +++ b/models/ggml-vocab-deepseek-llm.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-deepseek-llm.gguf.out b/models/ggml-vocab-deepseek-llm.gguf.out index 0191b7a115582..f9d49c9afe703 100644 --- a/models/ggml-vocab-deepseek-llm.gguf.out +++ b/models/ggml-vocab-deepseek-llm.gguf.out @@ -1,5 +1,5 @@ 1052 207 19 207 19109 4223 - 37 100014 71 6245 + 82077 26723 282 207 243 diff --git a/models/ggml-vocab-deepseek-r1-qwen.gguf.inp b/models/ggml-vocab-deepseek-r1-qwen.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-deepseek-r1-qwen.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-deepseek-r1-qwen.gguf.out b/models/ggml-vocab-deepseek-r1-qwen.gguf.out deleted file mode 100644 index 18b4b45cd152f..0000000000000 --- a/models/ggml-vocab-deepseek-r1-qwen.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 1122 220 19 220 26062 3951 - 37 50753 261 - - 220 - 256 - 262 - 197 - 198 - 271 - 1406 - 1572 - 9707 1879 - 21927 1879 - 9707 4337 - 21927 4337 - 21927 4337 0 - 9707 11 1879 0 - 21927 11 1879 0 - 419 374 11162 99 247 13 10821 - 86 15 19 23 220 22 83 1963 41808 11472 2940 16739 - 78762 14144 1456 13073 63471 33594 3038 133178 79012 - 146394 97529 241 44258 233 146568 44258 224 147603 20879 115 146280 44258 223 146280 147272 97529 227 147805 148301 147270 44258 223 146848 - 145836 320 8252 8 26525 114 378 235 149921 30543 320 35673 99066 97534 8 25521 227 320 3243 42365 429 702 1181 1828 3950 8 - 9707 - 21927 - 220 21927 - 256 21927 - 262 21927 - 262 21927 198 262 21927 - 320 - 198 284 - 6 11385 - 9707 11 379 64848 0 2585 525 498 26525 223 937 104100 18493 22377 99257 16 18 16 19 16 20 16 35727 21216 - 17085 2928 - 18 - 18 18 - 18 18 18 - 18 18 18 18 - 18 18 18 18 18 - 18 18 18 18 18 18 - 18 18 18 18 18 18 18 - 18 18 18 18 18 18 18 18 - 18 18 18 18 18 18 18 18 18 - 34 90063 128324 - 2560 2347 - 198 4710 14731 65497 7847 1572 2303 78672 10947 145836 320 8252 8 26525 114 378 235 149921 30543 320 35673 99066 97534 8 25521 227 11162 99 247 149955 220 18 220 18 18 220 18 18 18 220 18 18 18 18 220 18 18 18 18 18 220 18 18 18 18 18 18 220 18 18 18 18 18 18 18 220 18 18 18 18 18 18 18 18 220 18 13 18 220 18 496 18 220 18 1112 18 220 146394 97529 241 44258 233 146568 44258 224 147603 20879 115 146280 44258 223 146280 147272 97529 227 144534 937 104100 18493 22377 99257 16 18 16 19 16 20 16 35727 21216 55460 53237 18658 14144 1456 13073 63471 33594 3038 133178 79012 3355 4605 4605 13874 13874 73594 3014 3014 28149 17085 2928 26610 7646 358 3003 1012 364 83 813 566 594 1052 11 364 787 498 2704 30 364 44 537 2704 358 3278 1281 432 11 364 35 498 1075 1045 15243 30 1205 6 42612 264 63866 43 diff --git a/models/ggml-vocab-falcon.gguf.inp b/models/ggml-vocab-falcon.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-falcon.gguf.inp +++ b/models/ggml-vocab-falcon.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-falcon.gguf.out b/models/ggml-vocab-falcon.gguf.out index 64a48d97f71f4..6319de60e2412 100644 --- a/models/ggml-vocab-falcon.gguf.out +++ b/models/ggml-vocab-falcon.gguf.out @@ -1,5 +1,5 @@ 878 204 31 3068 133 2137 - 28611 132 30042 + 34502 18614 286 204 258 diff --git a/models/ggml-vocab-gpt-2.gguf.inp b/models/ggml-vocab-gpt-2.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-gpt-2.gguf.inp +++ b/models/ggml-vocab-gpt-2.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-gpt-2.gguf.out b/models/ggml-vocab-gpt-2.gguf.out index 17a13bdfc3d93..6464ded3d2767 100644 --- a/models/ggml-vocab-gpt-2.gguf.out +++ b/models/ggml-vocab-gpt-2.gguf.out @@ -1,5 +1,5 @@ 798 604 25208 1933 - 37 9116 71 11751 + 127 226 79 69 417 220 220 220 diff --git a/models/ggml-vocab-gpt-4o.gguf.inp b/models/ggml-vocab-gpt-4o.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-gpt-4o.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-gpt-4o.gguf.out b/models/ggml-vocab-gpt-4o.gguf.out deleted file mode 100644 index 478df726fa9ba..0000000000000 --- a/models/ggml-vocab-gpt-4o.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 1165 220 19 220 27124 5503 - 37 19194 259 - - 220 - 256 - 271 - 197 - 198 - 279 - 2499 - 2775 - 13225 2375 - 32949 2375 - 13225 5922 - 32949 5922 - 32949 5922 0 - 13225 11 2375 0 - 32949 11 2375 0 - 495 382 9552 99 247 13 17159 - 86 45404 220 22 10191 2852 22924 4750 6916 - 3907 53641 1235 185386 8118 - 11400 107516 15867 20804 22851 134178 77431 32010 104312 37984 16329 27751 89335 - 112927 222 350 14559 8 22861 114 2524 64364 104 15148 350 76466 166700 121942 780 8 91349 350 7393 74471 484 853 1617 2316 6602 8 - 13225 - 32949 - 220 32949 - 256 32949 - 271 32949 - 271 32949 198 271 32949 - 350 - 198 314 - 6 6837 - 13225 11 342 70653 0 3253 553 481 22861 223 1423 7522 18165 2178 34058 22369 16412 32999 16 867 8208 - 147475 - 18 - 2546 - 15517 - 15517 18 - 15517 2546 - 15517 15517 - 15517 15517 18 - 15517 15517 2546 - 15517 15517 15517 - 34 60213 53904 - 2960 3098 - 126470 25980 160432 16609 2775 4066 172261 19432 112927 222 350 14559 8 22861 114 2524 64364 104 15148 350 76466 166700 121942 780 8 91349 9552 99 247 4103 99 247 220 18 220 2546 220 15517 220 15517 18 220 15517 2546 220 15517 15517 220 15517 15517 18 220 15517 15517 2546 220 18 13 18 220 18 485 18 220 18 1008 18 44735 107516 15867 20804 22851 134178 77431 32010 104312 156437 1423 7522 18165 2178 34058 22369 16412 32999 16 867 8208 105024 106657 1967 53641 1235 185386 8118 22434 39336 26178 26178 168394 194663 27271 147475 25883 6961 9790 1339 461 83 1280 19016 1354 11 461 1099 481 3239 30 461 44 625 3239 17291 1520 480 11 461 35 481 1299 1236 17966 30 1416 6 27493 261 54602 43 diff --git a/models/ggml-vocab-llama-bpe.gguf.inp b/models/ggml-vocab-llama-bpe.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-llama-bpe.gguf.inp +++ b/models/ggml-vocab-llama-bpe.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-llama-bpe.gguf.out b/models/ggml-vocab-llama-bpe.gguf.out index 4b35cf93f7133..a77376625a2a0 100644 --- a/models/ggml-vocab-llama-bpe.gguf.out +++ b/models/ggml-vocab-llama-bpe.gguf.out @@ -1,5 +1,5 @@ 1142 220 19 220 27154 4038 - 37 51853 261 + 88075 16276 301 220 256 diff --git a/models/ggml-vocab-llama-spm.gguf.inp b/models/ggml-vocab-llama-spm.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-llama-spm.gguf.inp +++ b/models/ggml-vocab-llama-spm.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-llama-spm.gguf.out b/models/ggml-vocab-llama-spm.gguf.out index 93aacf8bae4bf..2a71a6ef86efa 100644 --- a/models/ggml-vocab-llama-spm.gguf.out +++ b/models/ggml-vocab-llama-spm.gguf.out @@ -1,5 +1,5 @@ 474 287 29871 29946 29871 30226 7378 - 383 4000 261 + 11585 7810 295 259 1678 diff --git a/models/ggml-vocab-llama4.gguf.inp b/models/ggml-vocab-llama4.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-llama4.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-llama4.gguf.out b/models/ggml-vocab-llama4.gguf.out deleted file mode 100644 index 7ca46ce597b85..0000000000000 --- a/models/ggml-vocab-llama4.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 1190 220 32 220 18215 7112 - 50 16800 258 - - 220 - 256 - 277 - 197 - 198 - 368 - 2946 - 3271 - 19873 3817 - 39715 3817 - 19873 7353 - 39715 7353 - 39715 7353 13 - 19873 24 3817 13 - 39715 24 3817 13 - 544 373 9522 112 247 26 36315 - 99 39923 220 35 9607 21498 21470 3679 9433 - 1595 7653 633 79829 34051 1636 - 8755 102595 115960 21125 148305 96819 102816 39048 14105 22528 160234 - 114590 222 330 14879 21 51358 127 12817 93293 117 24204 330 68239 881 120327 170428 21 89101 330 7384 88230 511 947 1492 3742 7233 21 - 19873 - 39715 - 220 39715 - 256 39715 - 277 39715 - 277 39715 198 277 39715 - 330 - 198 319 - 19 7359 - 19873 24 386 87799 13 2403 583 650 51358 223 1663 155736 1522 42056 7544 13336 28785 29 4412 20645 - 17931 4959 - 31 - 1922 - 12325 - 12325 31 - 12325 1922 - 12325 12325 - 12325 12325 31 - 12325 12325 1922 - 12325 12325 12325 - 47 19811 12077 - 3260 3579 - 198 7283 51499 191231 20192 3271 3322 9287 2143 17860 114590 222 330 14879 21 51358 127 12817 93293 117 24204 330 68239 881 120327 170428 21 89101 9522 112 247 172394 247 220 31 220 1922 220 12325 220 12325 31 220 12325 1922 220 12325 12325 220 12325 12325 31 220 12325 12325 1922 220 31 26 31 220 31 396 31 220 31 1043 31 117131 102595 115960 21125 148305 96819 102816 80883 223 1663 155736 1522 42056 7544 13336 28785 29 4412 20645 79745 150278 117079 633 79829 34051 1636 25611 41990 109428 1488 91054 24072 17931 4959 29795 9296 16517 1806 481 96 1386 36633 1609 24 481 1109 650 5074 43 481 57 702 5074 27088 2170 536 24 481 48 650 1933 1696 30262 43 1665 19 32818 262 27236 56 diff --git a/models/ggml-vocab-mpt.gguf.inp b/models/ggml-vocab-mpt.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-mpt.gguf.inp +++ b/models/ggml-vocab-mpt.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-mpt.gguf.out b/models/ggml-vocab-mpt.gguf.out index 372c751bf77da..ca62669ad0945 100644 --- a/models/ggml-vocab-mpt.gguf.out +++ b/models/ggml-vocab-mpt.gguf.out @@ -1,5 +1,5 @@ 728 577 24142 2607 - 39 26288 6554 + 37515 18569 293 209 50276 diff --git a/models/ggml-vocab-nomic-bert-moe.gguf b/models/ggml-vocab-nomic-bert-moe.gguf new file mode 100644 index 0000000000000..b6f4d9441113b Binary files /dev/null and b/models/ggml-vocab-nomic-bert-moe.gguf differ diff --git a/models/ggml-vocab-phi-3.gguf.inp b/models/ggml-vocab-phi-3.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-phi-3.gguf.inp +++ b/models/ggml-vocab-phi-3.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-phi-3.gguf.out b/models/ggml-vocab-phi-3.gguf.out index 93aacf8bae4bf..2a71a6ef86efa 100644 --- a/models/ggml-vocab-phi-3.gguf.out +++ b/models/ggml-vocab-phi-3.gguf.out @@ -1,5 +1,5 @@ 474 287 29871 29946 29871 30226 7378 - 383 4000 261 + 11585 7810 295 259 1678 diff --git a/models/ggml-vocab-pixtral.gguf.inp b/models/ggml-vocab-pixtral.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-pixtral.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-pixtral.gguf.out b/models/ggml-vocab-pixtral.gguf.out deleted file mode 100644 index 53309d1bc9ac7..0000000000000 --- a/models/ggml-vocab-pixtral.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 2014 1032 1052 1032 28504 6972 - 1070 7088 1258 - - 1032 - 1256 - 1293 - 1009 - 1010 - 1267 - 4688 - 1009 1010 - 22177 4304 - 45383 4304 - 22177 5325 - 45383 5325 - 45383 5325 1033 - 22177 1044 4304 1033 - 45383 1044 4304 1033 - 1593 1395 119685 1166 1153 1046 51228 - 1119 1048 1052 1056 1032 1055 17391 23216 30203 7785 17279 - 3337 30757 1902 4200 63073 3671 - 1225 1158 1128 1225 1158 1182 1225 1158 1147 1225 1159 1139 1225 1158 1143 1225 1159 1130 1225 1158 1150 1225 1158 1183 1225 1158 1159 1225 21359 1225 1158 1159 1225 1158 1162 1225 1158 1182 1225 1158 1133 1225 1158 1129 1225 1158 1155 1225 1158 1133 1225 21359 1225 1158 1137 - 1240 1159 1154 1128 1319 13052 1041 119685 1152 1182 29568 1240 1159 1140 1171 1239 1184 1143 1319 88181 1873 3659 1275 56421 1621 1041 126241 1133 1319 11234 1873 26303 1455 1934 2246 3754 10835 1041 - 22177 - 45383 - 1032 45383 - 1256 45383 - 1293 45383 - 1293 45383 1010 1293 45383 - 1319 - 1010 1376 - 1039 4033 - 22177 1044 1404 48054 1033 3075 1584 1636 119685 1152 1129 3082 26060 2998 63614 82278 1049 1051 1049 1052 1049 1053 1049 6434 6749 - 7290 7290 7290 - 1051 - 1051 1051 - 1051 1051 1051 - 1051 1051 1051 1051 - 1051 1051 1051 1051 1051 - 1051 1051 1051 1051 1051 1051 - 1051 1051 1051 1051 1051 1051 1051 - 1051 1051 1051 1051 1051 1051 1051 1051 - 1051 1051 1051 1051 1051 1051 1051 1051 1051 - 1067 59503 28783 - 3724 4058 - 1010 1032 1267 1032 4688 1032 17152 1458 29356 1010 1256 1010 1293 1010 1260 1010 1652 1010 1240 1159 1154 1128 1319 13052 1041 119685 1152 1182 29568 1240 1159 1140 1171 1239 1184 1143 1319 88181 1873 3659 1275 56421 1621 1041 126241 1133 119685 1166 1153 1240 1159 1166 1153 1032 1051 1032 1051 1051 1032 1051 1051 1051 1032 1051 1051 1051 1051 1032 1051 1051 1051 1051 1051 1032 1051 1051 1051 1051 1051 1051 1032 1051 1051 1051 1051 1051 1051 1051 1032 1051 1051 1051 1051 1051 1051 1051 1051 1032 1051 1046 1051 1032 1051 1791 1051 1032 1051 2880 1051 71881 1158 1128 1225 1158 1182 1225 1158 1147 1225 1159 1139 1225 1158 1143 1225 1159 1130 1225 1158 1150 1225 1158 1183 1225 1158 1159 1225 21359 1225 1158 1159 1225 1158 1162 1225 1158 1182 1225 1158 1133 1240 1159 1152 1129 3082 26060 2998 63614 82278 1049 1051 1049 1052 1049 1053 1049 6434 6749 45577 1045 6626 43555 2843 30757 1902 4200 63073 3671 14931 20040 20040 1657 1657 1975 14135 14135 83923 7290 7290 7290 45509 45509 45509 1362 6483 2151 1576 1116 2189 1514 1681 2156 1044 1576 3609 1636 5257 1063 1576 1077 1605 5257 1362 7534 3180 1494 1044 1576 1068 1636 2479 2269 26883 1063 2837 1039 45654 1261 54297 1076 diff --git a/models/ggml-vocab-qwen2.gguf.inp b/models/ggml-vocab-qwen2.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-qwen2.gguf.inp +++ b/models/ggml-vocab-qwen2.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-qwen2.gguf.out b/models/ggml-vocab-qwen2.gguf.out index 18b4b45cd152f..595d59a44963c 100644 --- a/models/ggml-vocab-qwen2.gguf.out +++ b/models/ggml-vocab-qwen2.gguf.out @@ -1,5 +1,5 @@ 1122 220 19 220 26062 3951 - 37 50753 261 + 86975 15897 301 220 256 diff --git a/models/ggml-vocab-refact.gguf.inp b/models/ggml-vocab-refact.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-refact.gguf.inp +++ b/models/ggml-vocab-refact.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-refact.gguf.out b/models/ggml-vocab-refact.gguf.out index 63d8305c3f1f3..f13dda52ce41e 100644 --- a/models/ggml-vocab-refact.gguf.out +++ b/models/ggml-vocab-refact.gguf.out @@ -1,5 +1,5 @@ 4833 225 38 225 143 140 17723 - 56 2006 3935 265 + 144 231 7132 342 225 261 diff --git a/models/ggml-vocab-roberta-bpe.gguf.inp b/models/ggml-vocab-roberta-bpe.gguf.inp deleted file mode 100644 index 9baf7d77ae6b5..0000000000000 --- a/models/ggml-vocab-roberta-bpe.gguf.inp +++ /dev/null @@ -1,112 +0,0 @@ -ied 4 ½ months -__ggml_vocab_test__ -Führer -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - -__ggml_vocab_test__ - - -__ggml_vocab_test__ - - - -__ggml_vocab_test__ - - - - -__ggml_vocab_test__ - - -__ggml_vocab_test__ -Hello world -__ggml_vocab_test__ - Hello world -__ggml_vocab_test__ -Hello World -__ggml_vocab_test__ - Hello World -__ggml_vocab_test__ - Hello World! -__ggml_vocab_test__ -Hello, world! -__ggml_vocab_test__ - Hello, world! -__ggml_vocab_test__ - this is 🦙.cpp -__ggml_vocab_test__ -w048 7tuijk dsdfhu -__ggml_vocab_test__ -нещо на Български -__ggml_vocab_test__ -កាន់តែពិសេសអាចខលចេញ -__ggml_vocab_test__ -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ (only emoji that has its own token) -__ggml_vocab_test__ -Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello -__ggml_vocab_test__ - Hello - Hello -__ggml_vocab_test__ - ( -__ggml_vocab_test__ - - = -__ggml_vocab_test__ -' era -__ggml_vocab_test__ -Hello, y'all! How are you 😁 ?我想在apple工作1314151天~ -__ggml_vocab_test__ -!!!!!! -__ggml_vocab_test__ -3 -__ggml_vocab_test__ -33 -__ggml_vocab_test__ -333 -__ggml_vocab_test__ -3333 -__ggml_vocab_test__ -33333 -__ggml_vocab_test__ -333333 -__ggml_vocab_test__ -3333333 -__ggml_vocab_test__ -33333333 -__ggml_vocab_test__ -333333333 -__ggml_vocab_test__ -Cửa Việt -__ggml_vocab_test__ - discards -__ggml_vocab_test__ - - - - - - - - - - - -🚀 (normal) 😶‍🌫️ (multiple emojis concatenated) ✅ 🦙🦙 3 33 333 3333 33333 333333 3333333 33333333 3.3 3..3 3...3 កាន់តែពិសេសអាច😁 ?我想在apple工作1314151天~ ------======= нещо на Български ''''''```````""""......!!!!!!?????? I've been 'told he's there, 'RE you sure? 'M not sure I'll make it, 'D you like some tea? We'Ve a'lL -__ggml_vocab_test__ diff --git a/models/ggml-vocab-roberta-bpe.gguf.out b/models/ggml-vocab-roberta-bpe.gguf.out deleted file mode 100644 index f181ac3dcc5bc..0000000000000 --- a/models/ggml-vocab-roberta-bpe.gguf.out +++ /dev/null @@ -1,46 +0,0 @@ - 2550 204 18430 377 - 597 2768 298 8564 - - 1437 - 1437 1437 - 1437 1437 1437 - 50117 - 50118 - 50140 - 50140 50118 - 50117 50118 - 31414 232 - 20920 232 - 31414 623 - 20920 623 - 20920 623 328 - 31414 6 232 328 - 20920 6 232 328 - 42 16 8103 18164 27 4 49317 - 605 40976 262 10109 18474 385 29 36807 6455 - 36765 25482 22063 23171 34251 18697 10809 26161 18697 3602 22063 27969 40966 25417 15264 26161 24269 36709 41171 35328 - 1376 17772 7471 1376 17772 19002 1376 17772 9085 1376 4333 13859 1376 17772 9357 1376 4333 9264 1376 17772 25448 1376 17772 18400 1376 17772 4333 1376 4333 10172 1376 17772 4333 1376 17772 7258 1376 17772 19002 1376 17772 5782 1376 17772 10172 1376 17772 3726 1376 17772 5782 1376 4333 10172 1376 17772 23171 - 6569 15113 7471 36 21113 43 17841 19002 17 8384 6569 14285 4958 12605 36 34654 2841 4203 354 10146 26511 1070 43 36174 5782 36 8338 21554 14 34 63 308 19233 43 - 31414 - 20920 - 1437 20920 - 1437 1437 20920 - 1437 1437 1437 20920 - 1437 1437 1437 20920 50118 1437 1437 1437 20920 - 36 - 50118 5457 - 108 3567 - 31414 6 1423 108 1250 328 1336 32 47 17841 10172 17487 47876 3602 48617 15264 46537 11423 27326 48494 8210 49233 1558 1570 27761 49429 43251 10809 17772 - 32376 12846 - 246 - 3103 - 25631 - 46152 - 3103 25631 - 46152 3103 - 46152 25631 - 46152 46152 - 46152 3103 25631 - 347 1376 2023 12410 102 16376 1376 2023 6382 90 - 9553 5954 - 50118 1437 50140 1437 50140 50118 1437 50117 1437 50117 50117 1437 50117 50118 1437 1437 50118 1437 1437 1437 50118 1437 1437 1437 1437 50118 1437 1437 1437 1437 1437 50118 6569 15113 7471 36 21113 43 17841 19002 17 8384 6569 14285 4958 12605 36 34654 2841 4203 354 10146 26511 1070 43 36174 5782 8103 18164 27 6569 18164 27 155 2357 30242 155 25631 30242 3103 30242 25631 30242 46152 30242 3103 25631 155 4 246 155 7586 246 155 734 246 25974 17772 7471 1376 17772 19002 1376 17772 9085 1376 4333 13859 1376 17772 9357 1376 4333 9264 1376 17772 25448 1376 17772 18400 1376 17772 4333 1376 4333 10172 1376 17772 4333 1376 17772 7258 1376 17772 19002 1376 17772 5782 18636 10172 17487 47876 3602 48617 15264 46537 11423 27326 48494 8210 49233 1558 1570 27761 49429 43251 10809 17772 36738 48332 47463 18697 10809 25482 22063 23171 34251 18697 10809 26161 18697 3602 22063 27969 40966 25417 15264 26161 24269 36709 41171 35328 128 49690 108 49972 49519 12905 48149 48149 43796 32376 12846 27282 28749 38 348 57 128 41042 37 18 89 6 128 4629 47 686 116 128 448 45 686 38 581 146 24 6 128 495 47 101 103 6845 116 166 108 30660 10 108 462 574 diff --git a/models/ggml-vocab-starcoder.gguf.inp b/models/ggml-vocab-starcoder.gguf.inp index 9baf7d77ae6b5..86b934e4020fb 100644 --- a/models/ggml-vocab-starcoder.gguf.inp +++ b/models/ggml-vocab-starcoder.gguf.inp @@ -1,6 +1,6 @@ ied 4 ½ months __ggml_vocab_test__ -Führer +Äpfel __ggml_vocab_test__ __ggml_vocab_test__ diff --git a/models/ggml-vocab-starcoder.gguf.out b/models/ggml-vocab-starcoder.gguf.out index 87e2465d363e4..4698e2c3c81ad 100644 --- a/models/ggml-vocab-starcoder.gguf.out +++ b/models/ggml-vocab-starcoder.gguf.out @@ -1,5 +1,5 @@ 4850 244 57 244 162 159 17722 - 75 2022 3943 284 + 163 250 7146 361 244 280 diff --git a/models/templates/Qwen-QwQ-32B.jinja b/models/templates/Qwen-QwQ-32B.jinja new file mode 100644 index 0000000000000..d475f7068730e --- /dev/null +++ b/models/templates/Qwen-QwQ-32B.jinja @@ -0,0 +1,62 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0]['role'] == 'system' %} + {{- messages[0]['content'] }} + {%- else %} + {{- '' }} + {%- endif %} + {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0]['role'] == 'system' %} + {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- for message in messages %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" and not message.tool_calls %} + {%- set content = message.content %} + {%- if not loop.last %} + {%- set content = message.content.split('')[-1].lstrip('\n') %} + {%- endif %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set content = message.content %} + {%- if not loop.last %} + {%- set content = message.content.split('')[-1].lstrip('\n') %} + {%- endif %} + {{- '<|im_start|>' + message.role }} + {%- if message.content %} + {{- '\n' + content }} + {%- endif %} + {%- for tool_call in message.tool_calls %} + {%- if tool_call.function is defined %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {{- tool_call.arguments | tojson }} + {{- '}\n' }} + {%- endfor %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- message.content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n\n' }} +{%- endif %} diff --git a/models/templates/Qwen-Qwen3-0.6B.jinja b/models/templates/Qwen-Qwen3-0.6B.jinja new file mode 100644 index 0000000000000..699ff8df401fe --- /dev/null +++ b/models/templates/Qwen-Qwen3-0.6B.jinja @@ -0,0 +1,85 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set content = message.content %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is defined and message.reasoning_content is not none %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in message.content %} + {%- set content = message.content.split('')[-1].lstrip('\n') %} + {%- set reasoning_content = message.content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- message.content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/models/templates/README.md b/models/templates/README.md index e4fd104fc9fe6..35b6386dd0649 100644 --- a/models/templates/README.md +++ b/models/templates/README.md @@ -19,4 +19,6 @@ These templates can be updated with the following commands: ./scripts/get_chat_template.py NousResearch/Hermes-2-Pro-Llama-3-8B tool_use > models/templates/NousResearch-Hermes-2-Pro-Llama-3-8B-tool_use.jinja ./scripts/get_chat_template.py NousResearch/Hermes-3-Llama-3.1-8B tool_use > models/templates/NousResearch-Hermes-3-Llama-3.1-8B-tool_use.jinja ./scripts/get_chat_template.py Qwen/Qwen2.5-7B-Instruct > models/templates/Qwen-Qwen2.5-7B-Instruct.jinja +./scripts/get_chat_template.py Qwen/QwQ-32B > models/templates/Qwen-QwQ-32B.jinja +./scripts/get_chat_template.py Qwen/Qwen3-0.6B > models/templates/Qwen-Qwen3-0.6B.jinja ``` \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.h new file mode 100755 index 0000000000000..c8e297a6a4474 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.h @@ -0,0 +1,1412 @@ +/*----------------------------------------------------------------------------- + Copyright (c) 2019-2020-2022,2024 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------------*/ + +#ifndef HAP_COMPUTE_RES_H_ +#define HAP_COMPUTE_RES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup types Macros and structures + * @{ + */ + +/** Error code for unsupported features. */ +#define HAP_COMPUTE_RES_NOT_SUPPORTED 0x80000404 +/** Maximum thread identifiers supported */ +#define HAP_COMPUTE_RES_MAX_NUM_THREADS 16 + +/** + * @file HAP_compute_res.h + * @brief Header file with APIs to allocate compute resources. + */ + +/** + * Structure containing attributes for compute resources. + */ +typedef struct { + unsigned long long attributes[8]; /**< Attribute array. */ +} compute_res_attr_t; + +/** + * Structure containing a VTCM page size and the number of pages with that size. + */ +typedef struct { + unsigned int page_size; /**< Page size in bytes. */ + unsigned int num_pages; /**< Number of pages of size page_size. */ +} compute_res_vtcm_page_def_t; + +/** + * Structure describing the VTCM memory pages. + */ +typedef struct { + unsigned int block_size; /**< Block size in bytes */ + unsigned int page_list_len; /**< Number of valid elements in page_list array */ + compute_res_vtcm_page_def_t page_list[8]; /**< Array of pages. */ +} compute_res_vtcm_page_t; + +/** + * enum of HMX lock tyes + */ +typedef enum { + HAP_COMPUTE_RES_HMX_NON_SHARED = 0, /**< No sharing of HMX across threads */ + HAP_COMPUTE_RES_HMX_SHARED = 1, /**< To share HMX across threads */ +} compute_res_hmx_type_t; + +/** + * enum of capabilities supported by capability query API + */ +typedef enum { + HAP_COMPUTE_RES_PREEMPTION_CAPABILITY = 1, /**< Preemption capability */ +} compute_res_capability_id; + +/** + * Masks returned by preemption capability query + */ +#define HAP_COMPUTE_RES_COOPERATIVE_PREEMPTION 1 +/**< Mask indicating support for cooperative preemption framework using + * capabilities query. The cooperative preemption framework involves applications + * registering a release callback for accepting yield requests from a high priority + * allocator. + */ +#define HAP_COMPUTE_RES_AUTONOMOUS_PREEMPTION 2 +/**< Mask indicating support for autonomous/optimized preemption framework using + * capabilities query. HMX resource management is moved out of #HAP_compute_res_acquire()/ + * #HAP_compute_res_acquire_cached(), instead applications use #HAP_compute_res_hmx_lock3()/ + * #HAP_compute_res_hmx_unlock3() to lock/unlock HMX resource directly from the threads + * using HMX. Applications shall implement HMX critical section using hmx_mutex object + * returned by #HAP_compute_res_hmx_lock3() around non-preemptable HMX sections. + */ +#define HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION 4 +/**< Mask indicating support for thread identifiers based autonomous/optimized + * preemption framework. This feature is a subset of HAP_COMPUTE_RES_AUTONOMOUS_PREEMPTION. + * In this feature, applications register the threads that + * will be working on the allocated compute resources with the resource manager. + * The compute resource manager, as part of autonomous preemption, suspends the + * threads associated with the low priority context when a high priority thread + * requests for these resources. + */ + + +/** + * enum of commands for providing thread ids to the resource manager + */ +typedef enum { + HAP_COMPUTE_RES_THREADS_OVERRIDE = 1, + /**< Command ID to override the thread list registered with a context */ + HAP_COMPUTE_RES_THREADS_APPEND = 2, + /**< Command ID to append to an existing thread list associated with + * the context + */ + HAP_COMPUTE_RES_THREADS_REMOVE = 3, + /**< Command ID to remove a thread from an existing thread list associated + * with the context + */ +} compute_res_threads_cmd_id; + +/** + * Structure holding HMX critical section parameters + */ +typedef struct { + void *mutex; + /**< Mutex to be used for entering/exiting HMX critical section + * via lock and unlock functions + */ + void (*lock)(void *mutex); + /**< Lock function to be called for entering HMX critical section using + * mutex as argument + */ + void (*unlock)(void *mutex); + /**< Unlock function to be called for exiting HMX critical section using + * mutex as argument + */ +} compute_res_hmx_mutex_t; + +/** + * Structure for querying preemption data + */ +typedef struct { + unsigned int num_preemptions; + /**< Number of preemptions on the acquired context */ + unsigned long long preempted_duration; + /**< Total duration the context remained preempted in terms of 19.2MHz ticks */ + unsigned long long preemption_overhead; + /**< Total preemption overhead in terms of 19.2MHz ticks */ +} compute_res_preempt_data_t; + +/** + * @} + */ + +/** + * @cond DEV + */ +int __attribute__((weak)) compute_resource_attr_init( + compute_res_attr_t* attr); + +int __attribute__((weak)) compute_resource_attr_set_serialize( + compute_res_attr_t* attr, + unsigned char b_enable); + +int __attribute__((weak)) compute_resource_attr_set_hmx_param( + compute_res_attr_t* attr, + unsigned char b_enable); + +int __attribute__((weak)) compute_resource_attr_set_vtcm_param( + compute_res_attr_t* attr, + unsigned int vtcm_size, + unsigned char b_single_page); + +int __attribute__((weak)) compute_resource_attr_set_vtcm_param_v2( + compute_res_attr_t* attr, + unsigned int vtcm_size, + unsigned int min_page_size, + unsigned int min_vtcm_size); + +int __attribute__((weak)) compute_resource_attr_set_app_type( + compute_res_attr_t* attr, + unsigned int application_id); + +int __attribute__((weak)) compute_resource_attr_set_cache_mode( + compute_res_attr_t* attr, + unsigned char b_enable); + +int __attribute__((weak)) compute_resource_attr_set_release_callback( + compute_res_attr_t* attr, + int (*release_callback)( + unsigned int context_id, + void* client_context), + void* client_context); + +void* __attribute__((weak)) compute_resource_attr_get_vtcm_ptr( + compute_res_attr_t* attr); + +int __attribute__((weak)) compute_resource_attr_get_vtcm_ptr_v2( + compute_res_attr_t* attr, + void** vtcm_ptr, + unsigned int* vtcm_size); + +int __attribute__((weak)) compute_resource_query_VTCM( + unsigned int application_id, + unsigned int* total_block_size, + compute_res_vtcm_page_t* total_block_layout, + unsigned int* avail_block_size, + compute_res_vtcm_page_t* avail_block_layout); + +unsigned int __attribute__((weak)) compute_resource_acquire( + compute_res_attr_t* attr, + unsigned int timeout_us); + +int __attribute__((weak)) compute_resource_release( + unsigned int context_id); + +int __attribute__((weak)) compute_resource_acquire_cached( + unsigned int context_id, + unsigned int timeout_us); + +int __attribute__((weak)) compute_resource_release_cached( + unsigned int context_id); + +int __attribute__((weak)) compute_resource_hmx_lock( + unsigned int context_id); + +int __attribute__((weak)) compute_resource_hmx_unlock( + unsigned int context_id); + +int __attribute__((weak)) compute_resource_check_release_request( + unsigned int context_id); + +int __attribute__((weak)) compute_resource_hmx_lock2( + unsigned int context_id, + compute_res_hmx_type_t type); + +int __attribute__((weak)) compute_resource_hmx_unlock2( + unsigned int context_id, + compute_res_hmx_type_t type); + +int __attribute__((weak)) compute_resource_update_priority( + unsigned int context_id, + unsigned short priority); + +int __attribute__((weak)) crm_hmx_lock3(unsigned int context_id, + compute_res_hmx_type_t type, + compute_res_hmx_mutex_t *mutex, + unsigned int timeout_us); + +int __attribute__((weak)) crm_hmx_unlock3(unsigned int context_id, + compute_res_hmx_type_t type, + compute_res_hmx_mutex_t *mutex); + +int __attribute__ ((weak)) crm_attr_set_vtcm_backup( + compute_res_attr_t* attr, + void *buffer, + unsigned int buffer_size); + +int __attribute__ ((weak)) crm_attr_set_threads( + compute_res_attr_t* attr, + unsigned int *threads, + unsigned int num_threads); + +int __attribute__ ((weak)) crm_attr_set_vtcm_clear_on_release( + compute_res_attr_t* attr, + unsigned char enable); + +int __attribute__ ((weak)) crm_cached_set_threads(compute_res_threads_cmd_id command, + unsigned int context_id, + unsigned int *threads, + unsigned int num_threads); + +int __attribute__((weak)) crm_query_capability(compute_res_capability_id capability_id, + unsigned int* data); + +int __attribute__((weak)) crm_get_preempt_data(unsigned int context_id, + compute_res_preempt_data_t *data); + +int __attribute__((weak)) crm_tid_preemption_lock(void); + +int __attribute__((weak)) crm_tid_preemption_unlock(void); +/** + * @endcond + */ + +/** + * @defgroup attributes Manage attributes + * Manage parameters affecting the requested shared resources + * @{ + */ + +/** + * Initializes the attribute structure for a resource request. + * + * The user must call this function before setting any specific resource property + * via other helper functions. + * + * @param[in] attr Pointer to compute resource attribute structure, + * #compute_res_attr_t. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED if unsupported. + */ +static inline int HAP_compute_res_attr_init(compute_res_attr_t* attr) +{ + if (compute_resource_attr_init) + return compute_resource_attr_init(attr); + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets or clears the serialization option in the request resource structure. + * + * Serialization allows participating use cases to run with mutually exclusive + * access to the entire cDSP which helps, for example, in avoiding cache + * thrashing while trying to run simultaneously on different hardware threads. + * Participating use cases issue blocking acquires on the serialization + * resource when ready to run, and each runs in turn when it is granted that + * resource. + * + * Acquiring the serialization resource only ensures + * mutual exclusion from other cooperating use cases that also block on + * acquisition of that resource, it does not guarantee exclusion from + * concurrent use cases that do not request the serialization + * resource. + * + * @param[in] attr Pointer to the compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] b_serialize 1 (TRUE) to participate in serialization. \n + * 0 (FALSE) otherwise. + * + * @return + * 0 upon success \n + * Nonzero upon failure. + */ +static inline int HAP_compute_res_attr_set_serialize( + compute_res_attr_t* attr, + unsigned char b_serialize) +{ + if (compute_resource_attr_set_serialize) + { + return compute_resource_attr_set_serialize(attr, + b_serialize); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets VTCM request parameters in the provided resource attribute structure. + * + * The user calls this function to request the specified VTCM size in the acquire call. + * These VTCM request attributes are reset to 0 (no VTCM request) in the + * resource attribute structure by HAP_compute_res_attr_init(). + * + * @param[in] attr Pointer to compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] vtcm_size Size of the VTCM request in bytes; + 0 if VTCM allocation is not required. + * @param[in] b_single_page 1 - Requested VTCM size to be allocated in a + * single page. \n + * 0 - No page requirement (allocation can spread + * across multiple pages. VTCM manager + * always attempts the best fit). + * + * @return + * 0 upon success. \n + * Non-zero upon failure. + */ +static inline int HAP_compute_res_attr_set_vtcm_param( + compute_res_attr_t* attr, + unsigned int vtcm_size, + unsigned char b_single_page) +{ + if (compute_resource_attr_set_vtcm_param) + { + return compute_resource_attr_set_vtcm_param(attr, + vtcm_size, + b_single_page); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Reads the VTCM memory pointer from the given attribute structure. + * + * On a successful VTCM resource request placed via #HAP_compute_res_acquire() + * using HAP_compute_res_attr_set_vtcm_param(), a user can invoke this helper + * function to retrieve the allocated VTCM address by passing the same attribute + * structure used in the respective HAP_compute_res_acquire() call. + * + * @param[in] attr Pointer to compute the resource attribute structure + * #compute_res_attr_t. + * + * @return + * Void pointer to the allocated VTCM section. \n + * 0 signifies no allocation. + */ +static inline void* HAP_compute_res_attr_get_vtcm_ptr(compute_res_attr_t* attr) +{ + if (compute_resource_attr_get_vtcm_ptr) + { + return compute_resource_attr_get_vtcm_ptr(attr); + } + + return 0; +} + +/** + * Sets an extended set of VTCM request parameters in the attribute structure, + * specifically VTCM Size, the minimum required page size, and the minimum + * required VTCM size. + * + * This function cannot be used with HAP_compute_res_attr_set_vtcm_param(). + * Call this function after HAP_compute_res_attr_init(). + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute the resource attribute structure, + * #compute_res_attr_t. + * @param[in] vtcm_size Size of the VTCM request in bytes. 0 if VTCM allocation + * is NOT required. + * @param[in] min_page_size Minimum page size required in bytes. Valid pages include + * 4 KB, 16 KB, 64 KB, 256 KB, 1 MB, 4 MB, 16 MB. Setting 0 + * will select best possible fit (least page mappings) + * @param[in] min_vtcm_size Minimum VTCM size in bytes, if the specified size + * (vtcm_size) is not available. 0 means the + * size is an absolute requirement. + * + * @return + * 0 for success. \n + * Non-zero for failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_vtcm_param_v2( + compute_res_attr_t* attr, + unsigned int vtcm_size, + unsigned int min_page_size, + unsigned int min_vtcm_size) +{ + if (compute_resource_attr_set_vtcm_param_v2) + { + return compute_resource_attr_set_vtcm_param_v2(attr, + vtcm_size, + min_page_size, + min_vtcm_size); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets VTCM backup buffer in the provided attribute structure. + * + * Compute resource manager uses the provided buffer to backup VTCM allocated + * to the user during preemption of the associated request/context. The backup + * buffer provided should be able to accomodate all of the requested VTCM size. + * VTCM backup buffer is essential for preemption to work on architectures + * supporting HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION (use + * HAP_compute_res_query_capability() to query preemption model supported) + * + * Call this function after HAP_compute_res_attr_init(). + * + * @param[in] attr Pointer to the compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] buffer Pointer to the backup buffer in main memory (DDR). To be + * used by the compute resource manager for saving/restoring + * user allocated VTCM region during preemption. + * @param[in] buffer_size Size of the backup buffer in main memory (DDR) pointed + * to by the #buffer argument. The provided buffer should + * be sufficiently sized to accommodate user requested + * VTCM size. Align the buffer to 128B for better performance. + * + * @return + * 0 for success. \n + * Non-zero for failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_vtcm_backup( + compute_res_attr_t* attr, + void *buffer, + unsigned int buffer_size) +{ + if (crm_attr_set_vtcm_backup) + { + return crm_attr_set_vtcm_backup(attr, buffer, buffer_size); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Updates provided attribute structure with user-provided thread id array. + * + * On architectures supporting HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION, + * Compute resource manager requires users to register the threads that will be + * using the compute resources requested via #HAP_compute_res_acquire(). + * + * Call this function after HAP_compute_res_attr_init(). + * + * @param[in] attr Pointer to the compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] threads Pointer to an array of QuRT thread identifiers associated + * with the resource request. This array should be valid + * till #HAP_compute_res_acquire() is called on the prepared + * attribute. + * @param[in] num_threads Number of QuRT thread identifiers in the provided + * threads array #threads. A maximum of + * HAP_COMPUTE_RES_MAX_NUM_THREADS + * number of threads can be provided. + * + * @return + * 0 for success. \n + * Non-zero for failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_threads( + compute_res_attr_t* attr, + unsigned int *threads, + unsigned int num_threads) +{ + if (crm_attr_set_threads) + { + return crm_attr_set_threads(attr, threads, num_threads); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Updates thread id array for the associated cached context. + * + * Compute resource manager uses the QuRT thread identifiers provided by the + * user during preemption of the associated context. For cached + * allocations, the thread identifiers can either be provided at the time + * of HAP_compute_res_acquire() call using #HAP_compute_res_attr_set_threads(), + * or using this API with the context_id returned by a successful + * #HAP_compute_res_acquire() call when the cached attribute is set via + * #HAP_compute_res_attr_set_cache_mode(). + * The API has to be called before HAP_compute_res_acquire_cached() call. + * + * @param[in] command specifies a command from compute_res_threads_cmd_id: + * HAP_COMPUTE_RES_THREADS_OVERRIDE : To provide a new + * set of threads. + * HAP_COMPUTE_RES_THREADS_APPEND : To append to previously + * provided list of threads. + * HAP_COMPUTE_RES_THREADS_REMOVE : To remove given threads + * from previoulsy provided + * list of threads. + * @param[in] context_id Context ID returned by HAP_compute_res_acquire(). + * @param[in] threads Pointer to an array of QuRT thread identifiers associated + * with the resource request. + * @param[in] num_threads Number of QuRT thread identifiers in the provided + * threads array #threads. A maximum of + * HAP_COMPUTE_RES_MAX_NUM_THREADS + * number of threads can be provided. + * + * @return + * 0 for success. \n + * Non-zero for failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_cached_set_threads(compute_res_threads_cmd_id command, + unsigned int context_id, + unsigned int *threads, + unsigned int num_threads) +{ + if (crm_cached_set_threads) + { + return crm_cached_set_threads(command, context_id, threads, num_threads); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets VTCM clear on release option in the provided attribute structure. + * + * The compute resource manager by default initializes the VTCM memory to 0 + * when VTCM is released by the caller either at the time of release or when + * it's allocated to another process. For performance considerations (also + * considering security implications if any), client can intimate the compute + * resource manager not to clear out (zero-initialize) the allocated VTCM + * on release. + * + * Call this function after HAP_compute_res_attr_init(). + * + * @param[in] attr Pointer to the compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] enable 1 - zero-initialize VTCM memory after release (default) + * 0 - Do not zero-initialize VTCM memory after release. + * @return + * 0 for success. \n + * Non-zero for failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_vtcm_clear_on_release( + compute_res_attr_t* attr, + unsigned char enable) +{ + if (crm_attr_set_vtcm_clear_on_release) + { + return crm_attr_set_vtcm_clear_on_release(attr, enable); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * On a successful VTCM resource request placed via + * HAP_compute_res_acquire() or HAP_compute_res_acquire_cached() using + * HAP_compute_res_attr_set_vtcm_param_v2(), users invoke this helper function + * to retrieve the allocated VTCM address and size by passing the same + * attribute structure used in the respective acquire call. + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute the resource attribute structure + * #compute_res_attr_t. + * @param[out] vtcm_ptr Assigned VTCM address; NULL for no allocation. + * @param[out] vtcm_size Size of the allocated VTCM memory from the assigned pointer. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_get_vtcm_ptr_v2( + compute_res_attr_t* attr, + void** vtcm_ptr, + unsigned int* vtcm_size) +{ + if (compute_resource_attr_get_vtcm_ptr_v2) + { + return compute_resource_attr_get_vtcm_ptr_v2(attr, + vtcm_ptr, + vtcm_size); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * On chipsets with HMX, sets/resets the HMX request parameter in the attribute + * structure for acquiring the HMX resource. + * + * Call this function after HAP_compute_res_attr_init(). + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute the resource attribute structure, + * #compute_res_attr_t. + * @param[in] b_enable 0 - do not request HMX resource (resets option). \n + * 1 - request HMX resource (sets option). + * @return + * 0 upon success. \n + * Nonzero upon failure. + */ +static inline int HAP_compute_res_attr_set_hmx_param( + compute_res_attr_t* attr, + unsigned char b_enable) +{ + if (compute_resource_attr_set_hmx_param) + { + return compute_resource_attr_set_hmx_param(attr, + b_enable); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets or resets cacheable mode in the attribute structure. + * + * A cacheable request allows users to allocate and release based on the + * context ID of the request. On a successful cacheable request via + * HAP_compute_res_acquire(), users get the same VTCM address and + * size across calls of HAP_compute_res_acquire_cached() and + * HAP_compute_res_release_cached() until the context is explicitly + * released via HAP_compute_res_release(). + * + * After a successful cacheable request via HAP_compute_res_acquire(), + * users can get the assigned VTCM pointer (if requested) by passing + * the attribute structure to HAP_compute_res_attr_get_vtcm_ptr() + * for v1 and HAP_compute_res_attr_get_vtcm_ptr_v2() for v2, + * and they must call HAP_compute_res_acquire_cached() before using the + * assigned resources. + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute resource attribute structure, + * #compute_res_attr_t. + * @param[in] b_enable 0 - Do not request cacheable mode (resets option). \n + * 1 - Request cacheable mode (sets option). + * + * @return + * 0 upon success. \n + * Nonzero upon failure.\n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_cache_mode( + compute_res_attr_t* attr, + unsigned char b_enable) +{ + if (compute_resource_attr_set_cache_mode) + { + return compute_resource_attr_set_cache_mode(attr, + b_enable); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets the application ID parameter in the resource structure used to + * select the appropriate VTCM partition. + * + * If this application ID parameter is not explicitly set, the default partition is selected. + * The default application ID (0) is set when the attribute structure is initialized. + * Application IDs are defined in the kernel device tree configuration. + * If the given ID is not specified in the tree, the primary VTCM partition is selected. + * + * Call this function after HAP_compute_res_attr_init(). + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute the resource attribute structure + * #compute_res_attr_t. + * @param[in] application_id Application ID used to specify the VTCM partition. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. + */ +static inline int HAP_compute_res_attr_set_app_type( + compute_res_attr_t* attr, + unsigned int application_id) +{ + if (compute_resource_attr_set_app_type) + { + return compute_resource_attr_set_app_type(attr, + application_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + + +/** +* @defgroup query VTCM query API +* @{ +*/ + +/** + * Returns the total and available VTCM sizes and page layouts + * for the given application type. + * + * Supported starting with Lahaina. + * + * @param[in] application_id Application ID used to specify the VTCM partition. + * @param[out] total_block_size Total VTCM size assigned for this application type. + * @param[out] total_block_layout Total VTCM size (total_block_size) + * represented in pages. + * @param[out] avail_block_size Largest contiguous memory chunk available in + VTCM for this application type. + * @param[out] avail_block_layout Available block size (avail_block_size) + * represented in pages. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_query_VTCM( + unsigned int application_id, + unsigned int* total_block_size, + compute_res_vtcm_page_t* total_block_layout, + unsigned int* avail_block_size, + compute_res_vtcm_page_t* avail_block_layout) +{ + if (compute_resource_query_VTCM) + { + return compute_resource_query_VTCM(application_id, + total_block_size, + total_block_layout, + avail_block_size, + avail_block_layout); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + +/** + * @defgroup acquire_release Acquire and release + * Manage the process of resource acquisition and release + * @{ + */ + +/** + * Checks the release request status for the provided context. + * When a context is acquired by providing a release callback, the callback + * can be invoked by the compute resource manager when a high priority client + * is waiting for the resource(s). If a client defers a release request waiting + * for an outstanding work item, this API can be used to check if a release is + * still required before releasing the context once the work is done. + * + * Note: It is not mandatory to call this API once a release request via + * the registered callback is received. The context can be released and reacquired + * if necessary. This API can be useful to avoid a release and reacquire in cases + * where the high priority client times out and is no longer waiting for the + * resource(s). + * + * Supported starting with Lahaina. + * + * @param[in] context_id Context ID returned by HAP_compute_res_acquire call(). + * + * @return + * 0 if the provided context need not be released. \n + * Nonzero up on failure or if the context needs to be released. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. \n + */ +static inline int HAP_compute_res_check_release_request( + unsigned int context_id) +{ + if (compute_resource_check_release_request) + { + return compute_resource_check_release_request(context_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Accepts a prepared attribute structure (attr) and returns a context ID + * for a successful request within the provided timeout (microseconds). + * + * @param[in] attr Pointer to compute the resource attribute structure + * #compute_res_attr_t. + * @param[in] timeout_us Timeout in microseconds; 0 specifies no timeout + * i.e., requests with unavailable resources + * immediately return failure. If nonzero, should + * be at least 200. + * + * @return + * Nonzero context ID upon success. \n + * 0 upon failure (i.e., unable to acquire requested resource + * in a given timeout duration). + */ +static inline unsigned int HAP_compute_res_acquire( + compute_res_attr_t* attr, + unsigned int timeout_us) +{ + if (compute_resource_acquire) + { + return compute_resource_acquire(attr, timeout_us); + } + + return 0; +} + +/** + * Releases all the resources linked to the given context ID. + * + * Call this function with the context_id returned by a successful + * HAP_compute_res_acquire call(). + * + * @param[in] context_id Context ID returned by HAP_compute_res_acquire call(). + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_release(unsigned int context_id) +{ + if (compute_resource_release) + { + return compute_resource_release(context_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Acquires or reacquires the resources pointed to the context_id returned by + * a successful HAP_compute_res_acquire() call. If VTCM resource was requested, + * the VTCM address, size, and page configuration remain the same. + * + * Supported from Lahaina. + * + * @param[in] context_id Context ID returned by HAP_compute_res_acquire(). + * @param[in] timeout_us Timeout in microseconds; 0 specifies no timeout + * i.e., requests with unavailable resources + * immediately return failure. If nonzero, should + * be at least 200. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_acquire_cached( + unsigned int context_id, + unsigned int timeout_us) +{ + if (compute_resource_acquire_cached) + { + return compute_resource_acquire_cached(context_id, timeout_us); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Releases all the resources pointed to by the context_id acquired + * by a successful HAP_compute_res_acquire_cached() call, while allowing the + * user to reacquire the same resources via HAP_compute_res_acquire_cached() + * in the future until the context is released via HAP_compute_res_release(). + * + * Supported starting with Lahaina. + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_release_cached(unsigned int context_id) +{ + if (compute_resource_release_cached) + { + return compute_resource_release_cached(context_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Sets the release callback function in the attribute structure. + + * The compute resource manager calls the release_callback function when any of the + * resources reserved by the specified context are required by a higher priority + * client. Clients act on the release request by explicitly calling the release + * function HAP_compute_res_release() or HAP_compute_res_release_cached() + * to release all acquired resources of the given context_id. + * + * Client-provided context (client_context) is passed to the release callback. On + * receiving a release request via the provided callback, clients should call the + * release function within 5 milliseconds. The release_callback function + * should not have any blocking wait. + * + * Call this function after HAP_compute_res_attr_init(). + * + * Supported starting with Lahaina. + * + * @param[in] attr Pointer to compute the resource attribute structure, + * #compute_res_attr_t. + * @param[in] release_callback Function pointer to the registered callback to + receive the release request. + * @param[in] client_context User-provided client context. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_attr_set_release_callback( + compute_res_attr_t* attr, + int (*release_callback)( + unsigned int context_id, + void* client_context), + void* client_context) +{ + if (compute_resource_attr_set_release_callback) + { + return compute_resource_attr_set_release_callback(attr, + release_callback, + client_context); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Updates the priority of an allocated context reflecting the caller's + * thread priority. + * The compute resource manager uses the callers thread priority as the resource + * priority when acquired (HAP_compute_res_acquire() / + * HAP_compute_res_acquire_cached()). If the thread priority of the caller is + * changed after acquiring the resource, caller should intimate the compute + * resource manager of a priority change by invoking this API. Failing to do + * so will result in resource manager assuming an incorrect priority for + * the allocated resource which may result in unwanted release requests. + * For a cached allocation, this API should be called after a successful + * HAP_compute_res_acquire_cached() call. + * + * Supported on latest chipsets(released after Palima). + * + * @param[in] context_id Context ID returned by HAP_compute_res_acquire().. + * @param[in] priority 0 - The compute resource manager would use the caller + * thread priority + * 1..255 - priority value in terms of QuRT thread priority. + * Priority ceiling will be applied for unprivileged + * processes. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_update_priority(unsigned int context_id, + unsigned short priority) +{ + if (compute_resource_update_priority) + { + return compute_resource_update_priority(context_id, priority); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + +/** + * @defgroup Critical section for autonomous thread id preemption + * + * API to enter and exit critical section to prevent autonomous thread identifiers + * based preemption (HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION) from + * resource manager when acquiring global mutexes (used + * in I/O, standard library functions like printf, user implemented + * serialization etc.) + * + * @{ + */ + +/** + * API to enter critical section to prevent autonomous thread identifiers + * based preemption (HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION) from + * resource manager when acquiring global mutexes (used + * in I/O, standard library functions like printf, user implemented + * serialization etc.) + * + * On architectures supporting HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION, + * holding global mutexes can lead to deadlocks within the preempted task's + * user process. The critical section exposed by this API should be implemented + * by users around I/O, logging or any standard libraries/user implementations + * which acquires global mutexes. + * + * Implementation uses a per-process global mutex, callers of this API will + * be serialized across threads within the caller user process on NSP. + * + * NOTE: The critical section implementation should only be done when, + * - HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION is supported + * - Applications with different priorities co-exist in a single user process + * exposing the risk of deadlock between a running and preempted + * application. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + * + */ + +static inline int HAP_compute_res_tid_preemption_lock(void) +{ + if (crm_tid_preemption_lock) + { + return crm_tid_preemption_lock(); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Releases the critical section acquired by #HAP_compute_res_tid_preemption_lock(). + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ + +static inline int HAP_compute_res_tid_preemption_unlock(void) +{ + if (crm_tid_preemption_unlock) + { + return crm_tid_preemption_unlock(); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + +/** + * @defgroup Capability query and profiling data + * API to query capabilities of the compute resource manager and to get + * profiling data associated with a context. + * + * @{ + */ + +/** + * Queries compute resource manager capabilities listed under + * compute_res_capability_id enum. + * + * @param[in] capability_id Identifier from compute_res_capability_id corresponding + * to the compute resource manager capability. + * @param[out] data Pointer to an unsigned int data. On success, the memory + * is updated with the data associated with the queried capability. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_query_capability(compute_res_capability_id capability_id, + unsigned int* data) +{ + if (crm_query_capability) + { + return crm_query_capability(capability_id, data); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * On implementations supporting HAP_COMPUTE_RES_AUTONOMOUS_PREEMPTION, + * this API returns preemption statistics associated with the context_id + * acquired via HAP_compute_res_acquire(). + * + * This API needs to be called before the associated context is released via + * HAP_compute_res_release() call, data returned is invalid otherwise. + * + * @param[in] context_id Context ID returned by HAP_compute_res_acquire(). + * @param[out] Pointer to compute_res_preempt_data_t. + * On success, the preemption-related statistics are updated in + * the provided structure. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_get_preempt_data(unsigned int context_id, + compute_res_preempt_data_t* data) +{ + if (crm_get_preempt_data) + { + return crm_get_preempt_data(context_id, data); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + + +/** + * @defgroup HMX HMX lock and unlock + * Manage HMX lock once HMX has been acquired + * + * @{ + */ + +/** + * Locks the HMX unit to the current thread and prepares the thread to + * execute HMX instructions. The client must have already acquired the + * HMX resource with HAP_compute_res_acquire() or HAP_compute_res_acquire_cached(), + * and context_id must refer to the corresponding resource manager context. + * + * Before executing HMX instructions, a client must call this function from + * the same software thread used for HMX processing. Only the calling thread + * with a valid HMX lock may execute HMX instructions. + * + * Supported starting with Lahaina. + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_lock(unsigned int context_id) +{ + if (compute_resource_hmx_lock) + { + return compute_resource_hmx_lock(context_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * Unlocks the HMX unit from the calling thread. The HMX unit can then be + * locked to another thread or released with HAP_compute_res_release(). + * + * This function must be called from the same thread as the previous + * HMX_compute_res_hmx_lock() call. + * + * Supported starting with Lahaina. + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_unlock(unsigned int context_id) +{ + if (compute_resource_hmx_unlock) + { + return compute_resource_hmx_unlock(context_id); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * This function is an extension to HAP_compute_res_hmx_lock() with an additional + * option to lock HMX across multiple participating threads within a user process + * and timeshare the HMX resource (only one thread should be using HMX at a time). + * + * Supported on latest chipsets(released after Palima). + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * @param[in] tye HAP_COMPUTE_RES_HMX_NON_SHARED + * Analogous to #HAP_compute_res_hmx_lock() + * HAP_COMPUTE_RES_HMX_SHARED + * Threads within a process can lock and timeshare the same HMX + * resource. When using this option, it is caller's responsibility + * to timeshare HMX (only one thread should use HMX at a time) + * among participating threads using HAP_COMPUTE_RES_HMX_SHARED + * option from the same process. + * Note that the sharing of HMX is allowed between the threads of + * the same user process. A single Context ID (context_id) should be + * used across the participating threads in a user process. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_lock2(unsigned int context_id, + compute_res_hmx_type_t type) +{ + if (compute_resource_hmx_lock2) + { + return compute_resource_hmx_lock2(context_id, type); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * To be used in conjunction with HAP_compute_res_hmx_lock2() to release a successfully + * locked HMX unit. + * 'type' provided should match with the type provided to a successful + * HAP_compute_res_hmx_lock2() call from this thread. + * + * Supported on latest chipsets(released after Palima). + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * + * @param[in] type Should be the same paramter used to lock HMX + * via #HAP_compute_res_hmx_lock2() + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_unlock2(unsigned int context_id, + compute_res_hmx_type_t type) +{ + if (compute_resource_hmx_unlock2) + { + return compute_resource_hmx_unlock2(context_id, type); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + +/** + * @defgroup HMX HMX lock and unlock + * Manage HMX on architectures supporting HAP_COMPUTE_RES_AUTONOMOUS_PREEMPTION + * + * @{ + */ + +/** + * On architectures supporting HAP_COMPUTE_RES_AUTONOMOUS_PREEMPTION preemption, + * this funciton locks the HMX unit to the current thread and prepares the thread to + * execute HMX instructions. The client must have already acquired the + * VTCM using HAP_compute_res_acquire() or HAP_compute_res_acquire_cached(), + * and context_id must refer to the corresponding resource manager context. + * + * Before executing HMX instructions, a client must call this function from + * the same software thread used for HMX processing. Only the calling thread + * with a valid HMX lock may execute HMX instructions. + * + * The calling thread shall acquire lock on HMX mutex before executing HMX + * instructions and release the lock when program reaches to a point where the + * acquired HMX unit can be re-assigned to a higher priority waiter (in case of + * multiple clients contending for HMX resource) without affecting + * functionality. For entering HMX critical section, user shall call + * hmx_mutex->lock(hmx_mutex->mutex). For exiting the HMX critical section, user + * shall call hmx_mutex->unlock(hmx_mutex->mutex) + * autonomous preemption will wait for applications to release the HMX critical section + * before preempting HMX from the allocator. + * + * @param[in] context_id Context ID returned by + * #HAP_compute_res_acquire(). + * @param[in] type HAP_COMPUTE_RES_HMX_NON_SHARED + * Analogous to #HAP_compute_res_hmx_lock() + * HAP_COMPUTE_RES_HMX_SHARED + * Threads within a process can lock and timeshare the same HMX + * resource. When using this option, it is caller's responsibility + * to timeshare HMX (only one thread should use HMX at a time) + * among participating threads using HAP_COMPUTE_RES_HMX_SHARED + * option from the same process. + * Note that the sharing of HMX is allowed between the threads of + * the same user process. A single Context ID (context_id) should be + * used across the participating threads in a user process. + * @param[out] hmx_mutex Pointer to structure of type compute_res_hmx_mutex_t. + * On Success, the structure is updated with mutex, lock + * and unlock parameters. + * @param[in] timeout_us Timeout in microseconds; 0 specifies no timeout + * i.e., requests with unavailable resources + * immediately return failure. If nonzero, should + * be at least 200. + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_lock3(unsigned int context_id, + compute_res_hmx_type_t type, + compute_res_hmx_mutex_t *hmx_mutex, + unsigned int timeout_us) +{ + if (crm_hmx_lock3) + { + return crm_hmx_lock3(context_id, type, hmx_mutex, timeout_us); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * To be used in conjunction with HAP_compute_res_hmx_lock3() to release a + * successfully locked HMX unit. + * 'type' provided should match with the type provided to a successful + * #HAP_compute_res_hmx_lock3() call from this thread. + * + * @param[in] context_id Context ID returned for a successful VTCM acquisition by + * #HAP_compute_res_acquire(). + * + * @param[in] type Should be the same parameter used to lock HMX + * via #HAP_compute_res_hmx_lock3() + * + * @param[in] hmx_mutex Should be the same parameter used to lock HMX via + * #HAP_compute_res_hmx_lock3() + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * HAP_COMPUTE_RES_NOT_SUPPORTED when not supported. + */ +static inline int HAP_compute_res_hmx_unlock3(unsigned int context_id, + compute_res_hmx_type_t type, + compute_res_hmx_mutex_t *hmx_mutex) +{ + if (crm_hmx_unlock3) + { + return crm_hmx_unlock3(context_id, type, hmx_mutex); + } + + return HAP_COMPUTE_RES_NOT_SUPPORTED; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif //HAP_COMPUTE_RES_H_ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.md new file mode 100755 index 0000000000000..3b550bf9ed20c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_compute_res.md @@ -0,0 +1,635 @@ +# Compute resource manager framework + +The cDSP has several shared resources such as L2 cache, HVX, HMX (where available), VTCM, hardware threads, and memory +buses. The compute resource manager framework exposes in @b HAP_compute_res.h a set of APIs for managing, requesting +and releasing some of these resources. + +## Legacy HAP_vtcm_mgr API + +VTCM allocation APIs exposed under [VTCM Manager](../../doxygen/HAP_vtcm_mgr/index.html) are being deprecated, we +recommend using the compute resource APIs for VTCM management and allocation. The compute resource manager provides +options to: + +* Query defined VTCM on an architecture and VTCM usage. +* Cached mode: Release and reacquire the same VTCM virtual address, size and page configuration. +* Cooperative preemption: Register release callbacks, which might be invoked when a high-priority client needs a resource +used by a lower-priority client. +* ThreadID based autonomous preemption: Register threads that work on the compute resources with resource manager, these +threads will be suspended by the resource manager when a high priority client requests. Clients also provide a backup buffer +for VTCM, used by the resource manager to save and restore VTCM context during preemption. +* Query supported preemption model (cooperative, ThreadID based autonomous preemption etc.) + +## Serialization + +The resource manager also offers a virtualized serialization resource to aid concurrencies in which constituent use cases +are to run with mutually exclusive access to the entire cDSP, for example, to avoid cache thrashing with each other. +Participating use cases issue blocking acquires on the serialization resource when ready to run, and each use case runs +in turn when it is granted that resource. Acquiring the serialization resource only ensures mutual exclusion from other +cooperating use cases that also block on acquisition of that resource; it does not guarantee exclusion from concurrent +use cases that do not block on the serialization resource. + +## Cached mode + +Clients requesting for VTCM are provided with a pointer (virtual address) to VTCM on success. The pointer to VTCM can +change once it's released (HAP_compute_res_release()) and re-acquired (HAP_compute_res_acquire()). Clients requiring a +constant VTCM pointer through out a session can use the cached mode. Cached mode can be enabled by setting cached attribute +using HAP_compute_res_attr_set_cache_mode() when acquiring (HAP_compute_res_acquire()) the resource. When cached attribute +is set while acquiring the resource, clients are expected to call HAP_compute_res_acquire_cached() with the context ID +returned by HAP_compute_res_acquire() before accessing the resource. + +This mode is useful for periodic applications where VTCM pointer needs to remain the same at every execution while allocating +and releasing the resource periodically: +* HAP_compute_res_acquire() with cached attribute set is called for allocating VTCM during initialization. +* HAP_compute_res_acquire_cached() and HAP_compute_res_release_cached() called before and after every execution. +* HAP_compute_res_release() is called during de-initialization. + +From v73 architecture, cached mode also provides clients with an option to have an overlapping mapping from within a process. + +### overmapping / overlapping page mapping + +Applications working on HMX may require all of the requested VTCM to be in a single page mapping in MMU. When overmapping / +overlapping page mapping feature is supported, the HMX applications requesting for a page size covering entire VTCM with +a smaller VTCM size can allow other applications running from the same user process to allocate remaining VTCM size when +cached mode is used. + +For example, on an architecture supporting 8MB of VTCM, HMX application (APP1) requesting for 6MB of VTCM with a minimum of +8MB page in cached mode can allow another application (APP2) to acquire remaining 2MB of VTCM with a maximum page size of +1MB. + +![screenshot](../../images/CRM_VTCM_overmapping_example.png) + +Note: +* Only cached allocations requesting for VTCM page size covering entire VTCM defined for that architecture but with a +smaller VTCM size request will result in overmapping condition. For example, on architecture with 8MB VTCM, a cached/ +non-cached request for 3MB VTCM with 4MB page size will get a 4MB allocation (3MB wrapped to the page size). +* Multiple cached/non-cached allocations from within the same process (as overmapping client) can use the left over space +in VTCM as long as their requests can be accomodated in that space. For example, a 2MB size request with single page/ +4MB page size cannot coexist concurrently with a cached 6MB request with 8MB page size. +* Multiple overmapping clients cannot coexist concurrently. For example, a 4MB size with 8MB page request cannot coexist +concurrently with another 4MB sized request with 8MB page. + +## VTCM window feature +Starting with v79, the NSP has a VTCM window hardware feature, which can be used to prevent a thread from accessing a specific VTCM region. The compute resource manager utilizes this feature as an additional access control layer on top of the page mappings per process. +### Use case: +* Defined VTCM memory: 8MB +* Process 1: VTCM memory request 6MB, single page mapping +* Process 2: VTCM memory request 2MB + +In this use case, 6MB of VTCM to be mapped in a single page requires all of 8MB VTCM to be allocated. The difference between architectures with or without the VTCM window feature is in how the remaining 2 MB of VTCM allocated but unused by process 1 may be used by another process. + +### Q6 architecture < V79 (Where VTCM window feature not available) +As the entire 8MB of defined VTCM is mapped to the user process, the allocating user process, process 1, has access to the 2MB free space as well. The 2MB is marked free for other allocations from the same user process and not available for requests from other user processes. + +![screenshot](../../images/hap_compute_res_mgr_no_vtcm_window.png) + +Process 2 cannot use the 2MB of free space while process 1 still holds its allocation. + +### Q6 architecture >= V79 (Where VTCM window feature available) +The compure resource manager restricts the allocating user process, process 1, to access only 6MB of allocated space using `VTCM window` hardware feature. This allows other user processes to access this 2MB region. In this use case, process 1 has neither read nor write access to the remaining 2 MB of VTCM. + +![screenshot](../../images/hap_compute_res_mgr_vtcm_window.png) + +### VTCM window - restrictions +`VTCM window` can be useful to restrict threads within a process to desired VTCM regions. `VTCM window` should be a single contiguous memory region within the VTCM space: gaps inbetween allocations cannot be free for allocation from other user processes. For example, in the below scenario, the `VTCM window` cannot be used to allow other processes to allocate the 1MB of unallocated free space: it is only available for allocation from process 1. + +![screenshot](../../images/hap_compute_res_mgr_vtcm_window_restrictions.png) + +## Cooperative preemption framework + +The resource manager offers cooperative preemption framework where in clients can register a release callback when +requesting for compute resources using HAP_compute_res_attr_set_release_callback(). When a higher-priority client requests +a resource already in use by a lower-priority client, the lower-priority client will be notified by the callback to suspend +its work and release the resource. + +## Autonomous preemption framework (threadId based) + +On supported architecutres (can be queried using HAP_compute_res_query_capability()), the resource manager implements +an autonomous based preemption framework where clients register thread IDs associated with a resource request and provide +VTCM backup buffer when VTCM is being requested. As part of preempting a context, the resource manager waits for HMX critical section +when HMX is in used, suspends registered threads and saves VTCM in provided backup buffer. When the resource becomes available +the resource manager resumes suspended threads after restoring VTCM and reattaching HMX (if previously assigned). + +HMX under this preemption scheme is handled differently in comparison to the cooperative preemption framework. +In cooperative preemption framework, HMX as a resource is acquired first and then locked using HAP_compute_res_hmx_lock()/lock2() while +in autonomous preemption framework, HMX is directly locked via HAP_compute_res_hmx_lock3() using the context returned by +a successful VTCM allocation done using HAP_compute_res_acquire() call. As the resource manager can preempt a low +priority client, HMX applications need to implement HMX critical section using the mutex structure returned by a successful +HAP_compute_res_HMX_lock3() API. + +## Usage examples + +### Cached VTCM request - cooperative preemption + +@code +int release_callback(unsigned int context, void *state) +{ + if (!context || !state) return FAILURE; + /* + * Got release request, set release required in state variable + */ + application_state_t* local_state = (application_state_t *)state; + if (local_state->context != context) return FAILURE; + local_state->release_request = TRUE; + return 0; +} + +void initialization_routine() +{ + compute_res_attr_t attr; + unsigned int context; + unsigned int vtcm_size = 8 * 1024 * 1024; //8MB of VTCM + void *p_vtcm = NULL; + unsigned int result_vtcm_size = 0; + /* + * Initialize the attribute structure + */ + if (0 != HAP_compute_res_attr_init(&attr)) + return; + /* + * Query VTCM defined in the architecture and set our request VTCM size + * to the defined one (request for entire VTCM size) + */ + if (0 != HAP_compute_res_query_VTCM(0, &vtcm_size, NULL, NULL, NULL)) + return; + /* + * Set VTCM params: + * Requesting for entire VTCM size, minimum page size set to VTCM size, + * minimum required VTCM size is set to the same as VTCM size + */ + if (0 != HAP_compute_res_attr_set_vtcm_param_v2(&attr, vtcm_size, vtcm_size, vtcm_size)) + return; + /* + * Set cached mode + */ + if (0 != HAP_compute_res_attr_set_cache_mode(&attr, 1)) + return; + /* + * Set release callback + */ + if (0 != HAP_compute_res_attr_set_release_callback(&attr, &release_callback, (void *)state)) + return; + /* + * Acquire a context with the prepared attribute structure + */ + if (0 == (context = HAP_compute_res_acquire(&attr, 0))) + return; + /* + * Get VTCM pointer + */ + if (0 != HAP_compute_res_attr_get_vtcm_ptr_v2(&attr, &p_vtcm, &result_vtcm_size)) + { + HAP_compute_res_release(context); + return; + } + state->context = context; + /* + * Setup algorithm using p_vtcm and result_vtcm_size + */ + return; + } + +int yield(unsigned int context) +{ + /* + * Synchronize with workers to make sure all accesses to VTCM are complete + * Backup VTCM if required + * Release context and reacquire + */ + if (0 == HAP_compute_res_check_release_request(context)) + return FAILURE; + if (0 == HAP_compute_res_release_cached(context)) + return FAILURE; + if (0 == HAP_compute_res_acquire_cached(context, )) + return FAILURE; + /* + * Restore VTCM and continue remaining work + */ + return 0; +} + +void execution_loop() + /* + * Acquire the cached resource + */ + if (0 != HAP_compute_res_acquire_cached(context, )) + return; + /* + * Work items + */ + for (i = 0; i < WORK_ITEMS; i++) + { + /* + * Check if cooperative preemption requested for a release + * param set in release_callback + */ + if (state->release_request) + { + if (0 != yield(context)) + return; + } + //Execute work item + } + /* + * Release the cached resource + */ + if (0 != HAP_compute_res_release_cached(context)) + return; +} +@endcode + +### Cached VTCM request - autonomous threadID based preemption + +@code +int release_callback(unsigned int context, void *state) +{ + if (!context || !state) return FAILURE; + /* + * Got release request, set release required in state variable + */ + application_state_t* local_state = (application_state_t *)state; + if (local_state->context != context) return FAILURE; + local_state->release_request = TRUE; + return 0; +} + +int check_autonomous_threads_compute_res_capability() +{ + unsinged int capability = 0; + + if (0 != HAP_compute_res_query_capability(HAP_COMPUTE_RES_PREEMPTION_CAPABILITY, &capability)) + return FAILURE; + if (capability & HAP_COMPUTE_RES_THREADS_FOR_AUTONOMOUS_PREEMPTION) + return 0; + else + return FAILURE; +} + +void initialization_routine() +{ + compute_res_attr_t attr; + unsigned int context; + unsigned int vtcm_size = 8 * 1024 * 1024; //8MB of VTCM + void *p_vtcm = NULL, *p_vtcm_backup = NULL; + unsigned int result_vtcm_size = 0; + unsigned int thread_id = NULL; + /* + * Initialize the attribute structure + */ + if (0 != HAP_compute_res_attr_init(&attr)) + return; + /* + * Query VTCM defined in the architecture and set our request VTCM size + * to the defined one (request for entire VTCM size) + */ + if (0 != HAP_compute_res_query_VTCM(0, &vtcm_size, NULL, NULL, NULL)) + return; + /* + * Set VTCM params: + * Requesting for entire VTCM size, minimum page size set to VTCM size, + * minimum required VTCM size is set to the same as VTCM size + */ + if (0 != HAP_compute_res_attr_set_vtcm_param_v2(&attr, vtcm_size, vtcm_size, vtcm_size)) + return; + /* + * Set cached mode + */ + if (0 != HAP_compute_res_attr_set_cache_mode(&attr, 1)) + return; + /* + * Check threads based autonomous preemption support and register threads + */ + if (0 == check_autonomous_threads_compute_res_capability()) + { + /* + * Allocate backup buffer for VTCM to be registered with the resource + * manager + */ + p_vtcm_backup = malloc(vtcm_size); + /* + * Register VTCM backup buffer + */ + if (0 != HAP_compute_res_attr_set_vtcm_backup(&attr, p_vtcm_backup, vtcm_size)) + { + free(p_vtcm_backup); + return; + } + /* + * Register threads that will be working on the requested VTCM buffer + */ + thread_id = qurt_thread_get_id(); + if (0 != HAP_compute_res_attr_set_threads(&attr, &thread_id, 1)) + { + free(p_vtcm_backup); + return; + } + } else { + /* + * Falling back to cooperative preemption when autonomous preemption + * is not supported + */ + if (0 != HAP_compute_res_attr_set_release_callback(&attr, &release_callback, (void *)state)) + return; + } + /* + * Acquire a context with the prepared attribute structure + */ + if (0 == (context = HAP_compute_res_acquire(&attr, 0))) + return; + /* + * Get VTCM pointer + */ + if (0 != HAP_compute_res_attr_get_vtcm_ptr_v2(&attr, &p_vtcm, &result_vtcm_size)) + { + HAP_compute_res_release(context); + return; + } + state->context = context; + /* + * Setup algorithm using p_vtcm and result_vtcm_size + */ + return; + } + +int yield(unsigned int context) +{ + /* + * Synchronize with workers to make sure all accesses to VTCM are complete + * Backup VTCM if required + * Release context and reacquire + */ + if (0 == HAP_compute_res_check_release_request(context)) + return FAILURE; + if (0 == HAP_compute_res_release_cached(context)) + return FAILURE; + if (0 == HAP_compute_res_acquire_cached(context, )) + return FAILURE; + /* + * Restore VTCM and continue remaining work + */ + return 0; +} + +void execution_loop() + /* + * Acquire the cached resource + */ + if (0 != HAP_compute_res_acquire_cached(context, )) + return; + /* + * Work items + */ + for (i = 0; i < WORK_ITEMS; i++) + { + /* + * Check if cooperative preemption requested for a release + * param set in release_callback + */ + if (state->release_request) + { + if (0 != yield(context)) + return; + } + //Execute work item + } + /* + * Release the cached resource + */ + if (0 != HAP_compute_res_release_cached(context)) + return; +} +@endcode + +### Serialized VTCM acquisition + +This example shows two threads requesting VTCM and both participating in serialization by invoking HAP_compute_res_attr_set_serialize(). + +@code + /* + * PROCESS/THREAD 1 + */ + compute_res_attr_t res_info; + unsigned int context_id = 0; + void *p_vtcm = NULL; + /* + * Initialize the attribute structure + */ + if (0 != HAP_compute_res_attr_init(&res_info) ) + return; + /* + * Set serialization option + */ + if (0 != HAP_compute_res_attr_set_serialize(&res_info, 1) ) + return; + /* + * Set VTCM request parameters - 256KB single page + */ + if (0 != HAP_compute_res_attr_set_vtcm_param(&res_info, + (256 * 1024), + 1) ) + return; + /* + * Call acquire with a timeout of 10 milliseconds. + */ + if (0 != (context_id = HAP_compute_res_acquire(&res_info, 10000) ) ) + { + /* + * Successfully requested for serialization and acquired VTCM. + * The serialization request from PROCESS/THREAD 2 waits + * until the resource is released here. + */ + p_vtcm = HAP_compute_res_attr_get_vtcm_ptr(&res_info); + if (0 == p_vtcm) + { + /* + * VTCM allocation failed, should not reach here as the acquire + * returned with valid context ID. + */ + HAP_compute_res_release(context_id); + return; + } + //Do my work in process/thread 1 + /* + * Done. Release the resource now using the acquired context ID. + * This releases both the serialization request and VTCM allocation. + */ + HAP_compute_res_release(context_id); + p_vtcm = NULL; + } else { + /* + * Unsuccessful allocation. Timeout would have triggered. + * Implement a fallback or fail gracefully. + */ + } + + ... + + /* + * PROCESS/THREAD 2 + */ + compute_res_attr_t res_info; + unsigned int context_id = 0; + /* + * Initialize the attribute structure. + */ + if (0 != HAP_compute_res_attr_init(&res_info) ) + return; + /* + * Set serialization option. + */ + if (0 != HAP_compute_res_attr_set_serialize(&res_info, 1) ) + return; + /* + * Call acquire with a timeout of 10 milliseconds. + */ + if (0 != (context_id = HAP_compute_res_acquire(&res_info, 10000) ) ) + { + /* + * Successfully requested for serialization. + * The serialization request from PROCESS/THREAD 1 waits + * until the resource is released here even when the PROCESS/THREAD 1s + * request for VTCM can be served. + */ + //Do my work in process/thread 2 + /* + * Done. Release the resource now using the acquired context ID. + */ + HAP_compute_res_release(context_id); + } else { + /* + * Unsuccessful allocation. Timeout would have triggered. + * Implement a fallback or fail gracefully. + */ + } +@endcode + +### Non-serialized VTCM acquisition + +This example shows two threads requesting VTCM alone without a serialization option. + +If the total size requested by both threads exceeds the size of VTCM that is available, only one thread gets +access to VTCM while the other thread waits. In this case, the threads are serializing their workload +implicitly. + +If enough VTCM memory is available to meet the requests of both threads, both threads acquire VTCM upon request +and can end up executing in parallel. + +@code + /* + * PROCESS/THREAD 1 + */ + compute_res_attr_t res_info; + unsigned int context_id = 0; + void *p_vtcm = NULL; + /* + * Initialize the attribute structure. + */ + if (0 != HAP_compute_res_attr_init(&res_info) ) + return; + + /* By not calling HAP_compute_res_attr_set_serialize, we enable thread 1 to acquire VTCM + * as long as enough memory is available + */ + + /* + * Set VTCM request parameters - 256 KB single page + */ + if (0 != HAP_compute_res_attr_set_vtcm_param(&res_info, + (256 * 1024), + 1) ) + return; + /* + * Call acquire with a timeout of 10 milliseconds. + */ + if (0 != (context_id = HAP_compute_res_acquire(&res_info, 10000) ) ) + { + /* + * Successfully acquired VTCM. + * The VTCM request from PROCESS/THREAD 2 waits if enough + * VTCM is not left to serve the request until the resource is released + * here. + */ + p_vtcm = HAP_compute_res_attr_get_vtcm_ptr(&res_info); + if (0 == p_vtcm) + { + /* + * VTCM allocation failed, should not reach this point as the acquire + * returned with valid context ID. + */ + HAP_compute_res_release(context_id); + return; + } + //Do my work in process/thread 1 + /* + * Done. Release the resource now using the acquired context ID. + * This releases the VTCM allocation. + */ + HAP_compute_res_release(context_id); + p_vtcm = NULL; + } else { + /* + * Unsuccessful allocation. Timeout would have triggered. + * Implement a fallback or fail gracefully. + */ + } + + ... + + /* + * PROCESS/THREAD 2 + */ + compute_res_attr_t res_info; + unsigned int context_id = 0; + void *p_vtcm = NULL; + /* + * Initialize the attribute structure + */ + if (0 != HAP_compute_res_attr_init(&res_info) ) + return; + + /* By not calling HAP_compute_res_attr_set_serialize, we enable thread 2 to acquire VTCM + * as long as enough memory is available + */ + + /* + * Set VTCM request parameters - 256 KB single page. + */ + if (0 != HAP_compute_res_attr_set_vtcm_param(&res_info, + (256 * 1024), + 1) ) + return; + /* + * Call acquire with a timeout of 10 milliseconds. + */ + if (0 != (context_id = HAP_compute_res_acquire(&res_info, 10000) ) ) + { + /* + * Successfully acquired VTCM. + * The VTCM request from PROCESS/THREAD 1 waits if enough + * VTCM is not left to serve the request until the resource is released + * here. + */ + p_vtcm = HAP_compute_res_attr_get_vtcm_ptr(&res_info); + if (0 == p_vtcm) + { + /* + * VTCM allocation failed, should not reach this point as the acquire + * returned with valid context ID. + */ + HAP_compute_res_release(context_id); + return; + } + //Do work in PROCESS/THREAD 2 + /* + * Done. Release the resource now using the acquired context ID. + * This releases the VTCM allocation. + */ + HAP_compute_res_release(context_id); + p_vtcm = NULL; + } else { + /* + * Unsuccessful allocation. Timeout would have triggered. + * Implement a fallback or fail gracefully. + */ + } +@endcode + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.h new file mode 100755 index 0000000000000..34159800c5227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.h @@ -0,0 +1,332 @@ +/*----------------------------------------------------------------------------- + Copyright (c) 2021, 2022 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------------*/ + +#ifndef HAP_DCVS_H_ +#define HAP_DCVS_H_ + +/** + * @file HAP_dcvs.h + * @brief Header file for DCVS APIs. + */ + +#include "AEEStdErr.h" +#include "HAP_power.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perf modes to specify core/bus clock frequency level within + * target voltage corner for HAP DCVS V3 interface. + */ +typedef enum { + HAP_DCVS_CLK_PERF_HIGH, /**< To select max frequency at target voltage corner. */ + HAP_DCVS_CLK_PERF_LOW, /**< To select min frequency at target voltage corner. */ +} HAP_dcvs_clk_perf_mode_t; + +/** + * @cond DEV + */ +int __attribute__((weak)) sysmon_set_dcvs_v3_duty_cycle( + void* context, + uint32 max_active_time, + uint32 periodicity); + +int __attribute__((weak)) sysmon_set_dcvs_v3_duty_cycle_params( + HAP_power_request_t* request, + uint32 max_active_time, + uint32 periodicity); + +int __attribute__((weak)) sysmon_set_dcvs_v3_core_perf_mode( + HAP_power_request_t* request, + HAP_dcvs_clk_perf_mode_t perf_mode); + +int __attribute__((weak)) sysmon_set_dcvs_v3_bus_perf_mode( + HAP_power_request_t* request, + HAP_dcvs_clk_perf_mode_t perf_mode); + +int __attribute__((weak)) sysmon_set_dcvs_v3_protected_bus_corners( + HAP_power_request_t* request, + unsigned char enable_protected_corners); + +int __attribute__((weak)) sysmon_set_ddr_perf_mode( + HAP_power_request_t *request, + unsigned int perf_mode); +/** + * @endcond + */ + +/** + * @defgroup helperapi Helper APIs for DCVS Duty Cycle + * @{ + */ + +/** + * Method to enable DCVS Duty Cycle. + * + * Calls HAP_power_set API with the provided context and selects + * DCVS duty cycle mode via HAP_power_set_DCVS_v3 request type. + * + * @param[in] context User context - power client identifier to be used in + * HAP_power_set call. + * + * @param[in] max_active_time Max active time allowed per frame in ms + * (optional, can pass 0 if don’t want to specify). + * DCVS selects appropriate operating levels to + * keep the activity time within the provided + * maximum allowed time. + * + * @param[in] periodicity Frame time in ms (optional, can pass 0 if + * don’t want to specify periodicity). For example, + * periodicity = 100 (milli-seconds) for a + * 10 FPS activity. DCVS uses this as a hint while + * predicting activity. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ +static inline int HAP_set_dcvs_v3_duty_cycle( + void* context, + uint32 max_active_time, + uint32 periodicity) +{ + if (sysmon_set_dcvs_v3_duty_cycle) + return sysmon_set_dcvs_v3_duty_cycle( + context, + max_active_time, + periodicity); + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * Method to set duty cycle threshold params (periodicity and activity time hints) + * in the request structure intended for HAP_power_set for request type set to + * HAP_power_set_DCVS_v3. + * + * Sets the max_active_time and periodicity fields under dcvs_v3 payload of given + * request structure. + * + * Note: Request type should be set to HAP_power_set_DCVS_v3. + * + * @param[in] request Pointer to request structure. + * + * @param[in] max_active_time Max active time allowed per frame in ms. + * DCVS selects appropriate operating levels to + * keep the activity time within the provided + * maximum allowed time. + * + * @param[in] periodicity Frame time in ms (optional, can pass 0 if + * don’t want to specify periodicity). For example, + * periodicity = 100 (milli-seconds) for a + * 10 FPS activity. DCVS uses this as a hint while + * predicting activity. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ +static inline int HAP_set_dcvs_v3_duty_cycle_params( + HAP_power_request_t* request, + uint32 max_active_time, + uint32 periodicity) +{ + if (sysmon_set_dcvs_v3_duty_cycle_params) + { + return sysmon_set_dcvs_v3_duty_cycle_params( + request, + max_active_time, + periodicity); + } + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * @} + */ + +/** + * @defgroup enable_protected_corner_api Helper API for protected bus corners + * + * @{ + */ +/** + * On chipsets supporting bus corners above HAP_DCVS_VCORNER_TURBO_PLUS, to optimize residency at these corners, + * target corner requests for bus are capped to HAP_DCVS_VCORNER_TURBO_PLUS by default. + * Any request beyond HAP_DCVS_VCORNER_TURBO_PLUS (including HAP_DCVS_VCORNER_MAX) will be wrapped to HAP_DCVS_VCORNER_TURBO_PLUS. + * + * This API enables clients of HAP_power_set to override this protection when voting explicitly for bus corners + * above HAP_DCVS_VCORNER_TURBO_PLUS in necessary use cases. + * + * Note: + * API is supported starting with V79 QDSP6 architecture, AEE_EVERSIONNOTSUPPORT error (can be safely ignored) is returned by the API when not supported. + * + * Request type should be set to HAP_power_set_DCVS_v3. + * + * @param[in] request Pointer to HAP_power_request_t structure with request type set to HAP_power_set_DCVS_v3. + * @param[in] enable_protected_corners 1 - to consider bus corner requests above HAP_DCVS_VCORNER_TURBO_PLUS + * 0 (default) - to cap bus corner requests to HAP_DCVS_VCORNER_TURBO_PLUS + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ + +static inline int HAP_set_dcvs_v3_protected_bus_corners( + HAP_power_request_t* request, + unsigned char enable_protected_corners) +{ + if (sysmon_set_dcvs_v3_protected_bus_corners) + { + return sysmon_set_dcvs_v3_protected_bus_corners(request, + enable_protected_corners); + } + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * @} + */ +/** + * @defgroup enable_ddr_perf_mode_api Helper API to enable DDR perf mode + * + * @{ + */ +/** + * This API enables clients of HAP_power_set to vote for DDR performance mode. + * + * Note: + * API is supported starting with V79 QDSP6 architecture, AEE_EVERSIONNOTSUPPORT error (can be safely ignored) is returned by the API when not supported. + * + * Note: Request type should be set to HAP_power_set_DCVS_v3. + * + * @param[in] request Pointer to HAP_power_request_t structure with request type set to HAP_power_set_DCVS_v3 + * + * @param[in] perf_mode 1 - to enable DDR performance mode + * 0 - to disable the DDR performance mode + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ +static inline int HAP_set_ddr_perf_mode( + HAP_power_request_t *request, + unsigned int perf_mode) +{ + if (sysmon_set_ddr_perf_mode) + { + return sysmon_set_ddr_perf_mode(request, perf_mode); + } + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * @} + */ + +/** + * @defgroup clk_perfmode_api APIs to specify core/bus clock frequency level within target voltage corner + * + * @{ + */ + +/** + * Method to specify core clock frequency level corresponding to the + * target corner request in the request structure intended for + * HAP_power_set for request type set to HAP_power_set_DCVS_v3. + * + * By default, the highest core clock frequency available at the requested + * target_corner is selected. Using this API, user can select either the + * highest (HAP_DCVS_CLK_PERF_HIGH) or the lowest (HAP_DCVS_CLK_PERF_LOW) + * core clock frequency at any given target_corner. If there is only one + * core clock frequency available at the requested target_corner, both the + * high and low settings will select the same. + * + * Note: Request type should be set to HAP_power_set_DCVS_v3. + * + * Supported on latest chipsets(released after Palima). + * + * @param[in] request Pointer to request structure. + * + * @param[in] perf_mode Perf mode to specify core clock frequency level + * within target voltage corner. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ +static inline int HAP_set_dcvs_v3_core_perf_mode( + HAP_power_request_t* request, + HAP_dcvs_clk_perf_mode_t perf_mode) +{ + if (sysmon_set_dcvs_v3_core_perf_mode) + { + return sysmon_set_dcvs_v3_core_perf_mode( + request, + perf_mode); + } + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * Method to specify bus clock frequency level corresponding to the + * target corner request in the request structure intended for + * HAP_power_set for request type set to HAP_power_set_DCVS_v3. + * + * By default, the highest bus clock frequency available at the requested + * target_corner is selected. Using this API, user can select either the + * highest (HAP_DCVS_CLK_PERF_HIGH) or the lowest (HAP_DCVS_CLK_PERF_LOW) + * bus clock frequency at any given target_corner. If there is only one + * bus clock frequency available at the requested target_corner, both the + * high and low settings will select the same. + * + * Note: Request type should be set to HAP_power_set_DCVS_v3. + * + * Supported on latest chipsets(released after Palima). + * + * @param[in] request Pointer to request structure. + * + * @param[in] perf_mode Perf mode to specify bus clock frequency level + * within target voltage corner. + * + * @return + * 0 upon success. \n + * Nonzero upon failure. \n + * AEE_EVERSIONNOTSUPPORT if unsupported. + */ +static inline int HAP_set_dcvs_v3_bus_perf_mode( + HAP_power_request_t* request, + HAP_dcvs_clk_perf_mode_t perf_mode) +{ + if (sysmon_set_dcvs_v3_bus_perf_mode) + { + return sysmon_set_dcvs_v3_bus_perf_mode( + request, + perf_mode); + } + + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif //HAP_DCVS_H_ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.md new file mode 100755 index 0000000000000..e957258e4e664 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_dcvs.md @@ -0,0 +1,146 @@ +# DCVS Helper APIs + +DCVS Duty Cycle Helper APIs with usage examples. + +## DCVS Duty Cycle Helper APIs + +Header file: @b HAP_dcvs.h + +## Usage examples + +### HAP_set_dcvs_v3_duty_cycle + +This is the most straightforward and therefore the recommended simplified API to enable DCVS Duty Cycle. + +The user has to pass the context (power client identifier to be used in a HAP_power_set call) to this API. +The function calls into HAP_power_set API with the provided context and selects DCVS duty cycle mode via `HAP_power_set_DCVS_v3` request type. +The user optionally can provide max_active_time and periodicity. The DCVS algorithm selects appropriate operating levels to keep the activity time within the provided +maximum allowed time and uses periodicity as a hint while predicting activity. + +The user does not need to specify any clock corners. Instead, the DCVS algorithm will select the appropriate clock corner with the best performance-power tradeoff that keeps the active time under the maximum value provided by the user for a given period. + +The example below demonstrates the usage of HAP_set_dcvs_v3_duty_cycle API. + +@code + /* + * Enabling DCVS Duty Cycle with 10ms max_active_time and 33ms periodicity + */ + HAP_set_dcvs_v3_duty_cycle(context, 10, 33); +@endcode + +Here DCVS Duty cycle starts with NOM as active corner and LOW SVS (SVS2) corner for idle cycle. Then, if the DCVS algorithm observes an active time longer than 10 ms (the user-defined max active time), it will increase the clock to the next level, NOM PLUS, to try bringing the active time under 10ms. + +![screenshot](../../images/HAP_set_dcvs_v3_duty_cycle.png) + +### HAP_set_dcvs_v3_duty_cycle_params + +This API is useful in setting the max_active_time and periodicity in an existing DCVS request structure. + +The user can set the DCVS params as per application requirement in DCVS request structure with request type set to `HAP_power_set_DCVS_v3` and pass it as an argument to this function. + +This API allows the user to set the maximum active time and period values used by the DCVS algorithm. After invoking this function, the user will have to call HAP_power_set() using the same request structure. + +@code + HAP_power_request_t request; + request.type = HAP_power_set_DCVS_v3; + /* + * Selecting Duty Cycle mode with DCVS enabled + */ + request.dcvs_v3.set_dcvs_enable = TRUE; + request.dcvs_v3.dcvs_enable = TRUE; + request.dcvs_v3.dcvs_option = HAP_DCVS_V2_DUTY_CYCLE_MODE; + /* + * Setting TURBO PLUS as Max corner, NOM PLUS as Target corner + * and LOW SVS as Min corner + */ + request.dcvs_v3.set_core_params = TRUE; + request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_SVS2; + request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; + request.dcvs_v3.core_params.target_corner = HAP_DCVS_VCORNER_NOM_PLUS; + request.dcvs_v3.set_bus_params = TRUE; + request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_SVS2; + request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; + request.dcvs_v3.bus_params.target_corner = HAP_DCVS_VCORNER_NOM_PLUS; + /* + * Setting 20ms max_active_time and 33ms periodicity + */ + HAP_set_dcvs_v3_duty_cycle_params(&request, 20, 33); + HAP_power_set(context, &request); +@endcode + +Here DCVS duty cycle apply LOW SVS (SVS2) for idle cycle and active cycle corner in the range of Max to Target (TURBO PLUS to NOM PLUS) to maintain the user given max_active_time (20ms). + +![screenshot](../../images/HAP_set_dcvs_v3_duty_cycle_params.png) + +### HAP_set_dcvs_v3_core_perf_mode + +This API helps to select core clock frequency level within target voltage corner. + +By default, the highest core clock frequency available at the requested target corner is selected. Using this API, the user can select either the highest (`HAP_DCVS_CLK_PERF_HIGH`) or the lowest (`HAP_DCVS_CLK_PERF_LOW`) core clock frequency at any given target corner. If there is only one core clock frequency available at the requested target corner, both the +high and low settings will select the same. + +The user can set the DCVS params as per application requirement in DCVS request structure with request type set to `HAP_power_set_DCVS_v3` and pass the same as an arguement to this function along with perf_mode arguement which specifies the core clock frequency level (`HAP_DCVS_CLK_PERF_HIGH/HAP_DCVS_CLK_PERF_LOW`). + +This API sets the user provided perf_mode for core clock in the given request structure. After invoking this function, the user will have to call HAP_power_set() using the same request structure. + +@code + HAP_power_request_t request; + request.type = HAP_power_set_DCVS_v3; + /* + * Setting TURBO as Max corner, NOM as Target corner + * and LOW SVS as Min corner for core clock + */ + request.dcvs_v3.set_core_params = TRUE; + request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_SVS2; + request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO; + request.dcvs_v3.core_params.target_corner = HAP_DCVS_VCORNER_NOM; + /* + * Setting perf_mode as HAP_DCVS_CLK_PERF_LOW + */ + HAP_set_dcvs_v3_core_perf_mode(&request, HAP_DCVS_CLK_PERF_LOW); + HAP_power_set(context, &request); +@endcode + +Here DCVS will vote for minimum available core clock frequency at NOM target corner. + +### HAP_set_dcvs_v3_bus_perf_mode + +This API helps to select bus clock frequency level within target voltage corner. + +By default, the highest bus clock frequency available at the requested target corner is selected. Using this API, the user can select either the highest (`HAP_DCVS_CLK_PERF_HIGH`) or the lowest (`HAP_DCVS_CLK_PERF_LOW`) bus clock frequency at any given target corner. If there is only one bus clock frequency available at the requested target corner, both the high and +low settings will select the same. + +The user can set the DCVS params as per application requirement in DCVS request structure with request type set to `HAP_power_set_DCVS_v3` and pass the same as an arguement to this function along with perf_mode arguement which specifies the bus clock frequency level (`HAP_DCVS_CLK_PERF_HIGH/HAP_DCVS_CLK_PERF_LOW`). + +This API sets the user provided perf_mode for bus clock in the given request structure. After invoking this function, the user will have to call HAP_power_set() using the same request structure. + +@code + HAP_power_request_t request; + request.type = HAP_power_set_DCVS_v3; + /* + * Setting TURBO PLUS as Max corner, TURBO as Target corner + * and LOW SVS as Min corner for bus clock + */ + request.dcvs_v3.set_bus_params = TRUE; + request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_SVS2; + request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; + request.dcvs_v3.bus_params.target_corner = HAP_DCVS_VCORNER_TURBO; + /* + * Setting perf_mode as HAP_DCVS_CLK_PERF_LOW + */ + HAP_set_dcvs_v3_bus_perf_mode(&request, HAP_DCVS_CLK_PERF_LOW); + HAP_power_set(context, &request); +@endcode + +Here DCVS will vote for minimum available bus clock frequency at TURBO target corner. + +### HAP_set_dcvs_v3_protected_bus_corners + +On chipsets supporting bus corners above `HAP_DCVS_VCORNER_TURBO_PLUS`, to optimize residency at these corners, target corner requests for bus are capped to `HAP_DCVS_VCORNER_TURBO_PLUS` by default. +Any request beyond `HAP_DCVS_VCORNER_TURBO_PLUS` (including `HAP_DCVS_VCORNER_MAX`) will be set to `HAP_DCVS_VCORNER_TURBO_PLUS`. + +This API enables clients of HAP_power_set to override this protection when voting explicitly for bus corners above `HAP_DCVS_VCORNER_TURBO_PLUS` in necessary use cases. + +Note: +This API is supported starting with V79 QDSP6 architecture, `AEE_EVERSIONNOTSUPPORT` error (can be safely ignored) is returned by the API when not supported. +Request type should be set to `HAP_power_set_DCVS_v3`. diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_debug.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_debug.h new file mode 100755 index 0000000000000..aeed83ffcac27 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_debug.h @@ -0,0 +1,81 @@ +#ifndef HAP_DEBUG_H +#define HAP_DEBUG_H +/*============================================================================== + Copyright (c) 2012-2013 Qualcomm Technologies, Inc. + All rights reserved. Qualcomm Proprietary and Confidential. +==============================================================================*/ + +#include "AEEStdDef.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAP_LEVEL_LOW 0 +#define HAP_LEVEL_MEDIUM 1 +#define HAP_LEVEL_HIGH 2 +#define HAP_LEVEL_ERROR 3 +#define HAP_LEVEL_FATAL 4 + +#define HAP_LEVEL_RUNTIME (1 << 5) + +//Add a weak reference so shared objects work with older images +#pragma weak HAP_debug_v2 + +//Add a weak reference for enabling FARF in autogen stub files +#pragma weak HAP_debug + +//Add a weak reference so runtime FARFs are ignored on older images +#pragma weak HAP_debug_runtime + +/************************************************************************** + These HAP_debug* functions are not meant to be called directly. + Please use the FARF() macros to call them instead +**************************************************************************/ +void HAP_debug_v2(int level, const char* file, int line, const char* format, ...); +void HAP_debug_runtime(int level, const char* file, int line, const char* format, ...); +int HAP_setFARFRuntimeLoggingParams(unsigned int mask, const char* files[], + unsigned short numberOfFiles); + +// Keep these around to support older shared objects and older images +void HAP_debug(const char *msg, int level, const char *filename, int line); + +static __inline void _HAP_debug_v2(int level, const char* file, int line, + const char* format, ...){ + char buf[256]; + va_list args; + va_start(args, format); + vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + HAP_debug(buf, level, file, line); +} + +/*! +This function is called to log an accumlated log entry. If logging is +enabled for the entry by the external device, then the entry is copied +into the diag allocation manager and commited. + + [in] log_code_type ID of the event to be reported + [in] *data data points to the log which is to be submitted + [in] dataLen The length of the data to be logged. + +Returns + TRUE if log is submitted successfully into diag buffers + FALSE if there is no space left in the buffers. + +*/ +boolean HAP_log_data_packet(unsigned short log_code_type, unsigned int dataLen, + byte* data); + +#define HAP_DEBUG_TRACEME 0 + +long HAP_debug_ptrace(int req, unsigned int pid, void* addr, void* data); + +#ifdef __cplusplus +} +#endif + +#endif // HAP_DEBUG_H + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.h new file mode 100755 index 0000000000000..4039d7822b331 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.h @@ -0,0 +1,98 @@ +/*----------------------------------------------------------------------- + Copyright (c) 2022 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------*/ + +/** + * @file HAP_etm_config.h + * @brief Header file with APIs to enable/disable etm tracing + */ + +#include "AEEStdErr.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @cond DEV + */ + +int __attribute__((weak)) __HAP_user_etm_enable(void); +int __attribute__((weak)) __HAP_user_etm_disable(void); + +/** + * @endcond + */ + + +/** @defgroup helperapi Helper APIs to enable/disable etm trace. + * API for users to enable or disable ETM tracing. + * The HAP user ETM API provides user capability to start/stop + * ETM tracing in a user module to cover a desired portion of + * execution. This API is disabled by default and will return + * an error when in that mode. To enable it, use + * --hap_etm_enable option of sysMonApp etmTrace service as + * mentioned in the sample command for default subsystem CDSP below: + * ``` + * adb shell /data/local/tmp/sysMonApp etmTrace --command etm --hap_etm_enable 1 + * ``` + * ETM enablement requires setting up coresight driver on HLOS + * and configuring appropriate ETM trace type on Q6 subsystem. + * ETM configurations set via sysMonApp etmTrace option + * like etm tracing mode (cycle accurate PC tracing etc., + * sample command on CDSP below) + * ``` + * adb shell /data/local/tmp/sysMonApp etmTrace --command etm --etmType ca_pc + * ``` + * are preserved across HAP user etm enable and disable calls. + * The API is only for debug purpose and shouldn't be used in + * production environments. + * @{ + */ + +/** + * Requests ETM tracing to be enabled + * + * Call this function from the DSP user process to start ETM + * tracing. To stop the tracing, call @ref HAP_user_etm_disable(). + * Supported on latest chipsets(released after Palima). + * @param None + * @return 0 upon success, other values upon failure. + */ +static inline int HAP_user_etm_enable(void) { + if(__HAP_user_etm_enable) + return __HAP_user_etm_enable(); + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * Requests ETM tracing to be disabled + * + * Call this function from the DSP user process to stop any active + * ETM tracing. API returns error if there is no active ETM trace + * enable call, e.g., if @ref HAP_user_etm_disable() is called + * first without any active @ref HAP_user_etm_enable() being + * present. The enable and disable requests are reference counted + * in the driver. Nested calls are supported, e.g. + * if @ref HAP_user_etm_enable() is called twice, two calls + * to the disable API @ref HAP_user_etm_disable() will be needed + * to disable the tracing. + * Supported on latest chipsets(released after Palima). + * @param None + * @return 0 upon success, other values upon failure. + */ +static inline int HAP_user_etm_disable(void) { + if(__HAP_user_etm_disable) + return __HAP_user_etm_disable(); + return AEE_EVERSIONNOTSUPPORT; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.md new file mode 100755 index 0000000000000..debf8e3ccc999 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_etm_config.md @@ -0,0 +1,38 @@ +# ETM Trace enable/disable APIs + +The HAP ETM framework exposes a set of APIs to enable/disable +ETM tracing in a user module to trace a region of interest +provided ETM tracing is configured. + +For configuring ETM tracing, refer to "profile on device" section +of Profiling example in base SDK. + +After ETM tracing is configured, the API requires setting the +'--hap_etm_enable' flag via sysMonApp etmTrace option as below: +``` +adb shell /data/local/tmp/sysMonApp etmTrace --command etm --hap_etm_enable 1 +``` + +After ETM trace collection, this flag should be reset with the +command: +``` +adb shell /data/local/tmp/sysMonApp etmTrace --command etm --hap_etm_enable 0 +``` + +Call to the APIs are ignored in the following cases: +* ETM tracing is not configured. +* The '--hap_etm_enable' flag is set to 0. + +***NOTE:*** The APIs work only on debug enabled device. +A test device or debug device, (Mobile Test Platform) MTP +or (Qualcomm Reference Design) QRD, is a device on which +the debug fuse is present. This fuse is not present on +production devices. + +## Supported chipsets + +Beyond Palima + +## Framework APIs + +Header file: @b HAP_etm_config.h \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.h new file mode 100755 index 0000000000000..8f5d3ba9aa38c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.h @@ -0,0 +1,264 @@ +/*============================================================================== + Copyright (c) 2012-2013, 2020 Qualcomm Technologies, Inc. + All rights reserved. Qualcomm Proprietary and Confidential. +==============================================================================*/ + +#ifndef HAP_FARF_H +#define HAP_FARF_H + +/** + * @file HAP_farf.h + * @brief FARF API + */ + +#include "AEEStdDef.h" +#include "HAP_debug.h" + +/** + *\def FARF() + * FARF is used to log debug messages from DSP + * + * `Compile time logging options:` + * + * Logging is controlled via conditional compilation. + * The FARF level allows the user to selectively enable or disable certain types + * of messages according to their priority level. + * The following levels are supported and listed in increasing priority: + * + * LOW + * + * MEDIUM + * + * HIGH + * + * ERROR + * + * FATAL + * + * ALWAYS + * + * A FARF level should be defined to 1 for FARF macros to be compiled + * in. For example: + * + * @code + * #define FARF_LOW 1 + * #include "HAP_farf.h" + * + * FARF(LOW, "something happened: %s", (const char*)string); + * + * @endcode + * + * FARF_LOW, FARF_MEDIM, FARF_HIGH are defined to 0 and FARF_ERROR, + * FARF_FATAL, FARF_ALWAYS are defined to 1 by default. + * + * If FARF_LOW is defined to 0, as it is by default, the above + * FARF string will not be compiled in, if it is defined to 1 it + * will be compiled in. + * + * If both HIGH and LOW messages are used but only FARF_LOW is defined + * as shown in below example then only LOW message will be compiled in and sent to DIAG. + * + * @code + * #define FARF_LOW 1 + * #include "HAP_farf.h" + * + * FARF(LOW, "LOW message"); + * FARF(HIGH, "HIGH message"); // This message will not be compiled in + * + * @endcode + * + * Messages logged with ALWAYS level are always compiled in and logged. + * + * When building the Debug variant or builds defining _DEBUG the + * following FARF levels will be enabled: + * + * HIGH + * + * ERROR + * + * FATAL + * + * `Run time logging options:` + * + * In order to enable run-time logging (logging that can be enabled / disabled + * at run-time), the FARF_RUNTIME_* macros should be used. + * + * Log messages sent with these macros are compiled in by default. However by + * these messages WILL NOT be logged by default. In order to enable logging, + * the FASTRPC process will need to either call the + * HAP_SetFARFRuntimeLoggingParams() API, or by adding a ``.farf + * file to the HLOS file system with the appropriate contents. + * + * @code + * + * #include "HAP_farf.h" + * FARF(RUNTIME_HIGH, "something happened: %s", (const char*)string); + * + * @endcode + * + * @param[in] x the FARF level defined to either 0 to disable compilation or 1 to enable. + * @param[in] ... the format string and arguments. + */ +#define FARF(x, ...) _FARF_PASTE(_FARF_,_FARF_VAL(FARF_##x))(x, ##__VA_ARGS__) + + +/** +* @defgroup static_FARF Compile-time macros +* +* Set these compile time macros to 1 to enable logging at that +* level. Setting them to 0 will cause them to be COMPILED out. +* +* Usage Example: +* @code +* +* #define FARF_HIGH 1 +* FARF(HIGH,"Log message"); +* +* @endcode + +* The ALWAYS macro will cause log messages to be ALWAYS compiled in. +* @code +* +* FARF(ALWAYS,"Log message") +* +* @endcode +* +* Defining _DEBUG macro turns on ALWAYS, HIGH, ERROR, FATAL +*/ +/* @{ */ + +#ifdef _DEBUG +#ifndef FARF_HIGH +#define FARF_HIGH 1 +#endif +#endif + +/** + * The FARF_ALWAYS macro causes log messages to be ALWAYS compiled in + */ +#ifndef FARF_ALWAYS +#define FARF_ALWAYS 1 +#endif + +/** + * The FARF_LOW macro causes log messages to be compiled in when FARF_LOW is defined to 1 +*/ +#ifndef FARF_LOW +#define FARF_LOW 0 +#endif + +/** +* The FARF_MEDIUM macro causes log messages to be compiled in when FARF_MEDIUM is defined to 1 +*/ +#ifndef FARF_MEDIUM +#define FARF_MEDIUM 0 +#endif + +/** +* The FARF_HIGH macro causes log messages to be compiled in when FARF_HIGH is defined to 1 +*/ +#ifndef FARF_HIGH +#define FARF_HIGH 0 +#endif + +/** +* The FARF_ERROR macro causes log messages to be compiled in when FARF_ERROR is defined to 1 +*/ +#ifndef FARF_ERROR +#define FARF_ERROR 1 +#endif + +/** +* The FARF_FATAL macro causes log messages to be compiled in when FARF_FATAL is defined to 1 +*/ +#ifndef FARF_FATAL +#define FARF_FATAL 1 +#endif + +//! @cond Doxygen_Suppress +#define FARF_ALWAYS_LEVEL HAP_LEVEL_HIGH +#define FARF_LOW_LEVEL HAP_LEVEL_LOW +#define FARF_MEDIUM_LEVEL HAP_LEVEL_MEDIUM +#define FARF_HIGH_LEVEL HAP_LEVEL_HIGH +#define FARF_ERROR_LEVEL HAP_LEVEL_ERROR +#define FARF_FATAL_LEVEL HAP_LEVEL_FATAL +//! @endcond + +/* @} */ + + +/** +* @defgroup Runtime_FARF Runtime macros +* +* Runtime FARF macros can be enabled at runtime. +* They are turned OFF by default. +* +* Usage Example: +* @code +* +* FARF(RUNTIME_HIGH,"Log message"); +* +* @endcode +*/ +/* @{ */ +//! @cond Doxygen_Suppress +#ifndef FARF_RUNTIME_LOW +#define FARF_RUNTIME_LOW 1 +#endif +#define FARF_RUNTIME_LOW_LEVEL (HAP_LEVEL_RUNTIME | HAP_LEVEL_LOW) + +#ifndef FARF_RUNTIME_MEDIUM +#define FARF_RUNTIME_MEDIUM 1 +#endif +#define FARF_RUNTIME_MEDIUM_LEVEL (HAP_LEVEL_RUNTIME | HAP_LEVEL_MEDIUM) + +#ifndef FARF_RUNTIME_HIGH +#define FARF_RUNTIME_HIGH 1 +#endif +#define FARF_RUNTIME_HIGH_LEVEL (HAP_LEVEL_RUNTIME | HAP_LEVEL_HIGH) + +#ifndef FARF_RUNTIME_ERROR +#define FARF_RUNTIME_ERROR 1 +#endif +#define FARF_RUNTIME_ERROR_LEVEL (HAP_LEVEL_RUNTIME | HAP_LEVEL_ERROR) + +#ifndef FARF_RUNTIME_FATAL +#define FARF_RUNTIME_FATAL 1 +#endif +#define FARF_RUNTIME_FATAL_LEVEL (HAP_LEVEL_RUNTIME | HAP_LEVEL_FATAL) +//! @endcond +/* @} */ + + +//! @cond Doxygen_Suppress + +#define _FARF_PASTE(a,b) _FARF_PASTE_(a,b) +#define _FARF_PASTE_(a,b) a##b +#define _FARF_VAL(a) a + + +#define _FARF_0(x, ...) + +#ifndef __FILENAME__ +#define __FILENAME__ __FILE__ +#endif + +#define _FARF_1(x, ...) \ + do { \ + if(0 == (HAP_debug_v2)) { \ + _HAP_debug_v2(FARF_##x##_LEVEL, __FILENAME__, __LINE__, ##__VA_ARGS__); \ + } else { \ + if (FARF_##x##_LEVEL & HAP_LEVEL_RUNTIME) { \ + if (0 != HAP_debug_runtime) { \ + HAP_debug_runtime(FARF_##x##_LEVEL ^ HAP_LEVEL_RUNTIME , __FILENAME__, __LINE__, ##__VA_ARGS__); \ + } else { \ + break; \ + } \ + } else { \ + HAP_debug_v2(FARF_##x##_LEVEL, __FILENAME__, __LINE__, ##__VA_ARGS__); \ + } \ + } \ + } while (0) + +#endif /* #ifndef HAP_FARF_H */ +//! @endcond diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.md new file mode 100755 index 0000000000000..35111fa2dfb37 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_farf.md @@ -0,0 +1,7 @@ +# HAP_farf + +## Overview + +The FARF API on DSP is used to generate diagnostic messages. These messages are sent to a diagnostic (or DIAG) framework on the DSP, from which they can be collected via USB using a tool called mini-dm running on the host computer. Parallelly, the DSP FARF messages can be routed to the application processor, allowing the user to collect DSP messages with logcat. These tools and the process for collecting messages is explained in the Messaging resources page from the SDK documentation. + +FARF messages can be enabled at compile-time and runtime. The Messaging resources page from the SDK documentation explains in detail the differences between compile-time and runtime FARF messages, how to enable them, and how to display them. diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.h new file mode 100755 index 0000000000000..0b6bae4d8336b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.h @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2012-2020 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc + */ + +#ifndef HAP_MEM_H +#define HAP_MEM_H +#include +#include "AEEStdDef.h" +#include "AEEStdErr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file HAP_mem.h + * @brief HAP Memory APIs + */ + + +/* + * Protections are chosen from these bits, or-ed together + */ + + + /*! @name HAP_PROT + \brief These macros define the permissions on memory block described by the file descriptor. + + It is passed as input parameter 'prot' to HAP_mmap(). These can be ORed to set the required permissions. + + +*/ + +///@{ + +/*! \def HAP_PROT_NONE + \brief Passing HAP_PROT_NONE as input results in setting 'NO' permissions on the buffer. +*/ +#define HAP_PROT_NONE 0x00 /* no permissions */ + +/*! \def HAP_PROT_READ + \brief Passing HAP_PROT_READ as input results in setting 'Read' permissions on the buffer. +*/ +#define HAP_PROT_READ 0x01 /* pages can be read */ +/*! \def HAP_PROT_WRITE + \brief Passing HAP_PROT_WRITE as input results in setting 'Write' permissions on the buffer. +*/ + +#define HAP_PROT_WRITE 0x02 /* pages can be written */ + +/*! + \def HAP_PROT_EXEC + \brief Passing HAP_PROT_EXEC as input results in setting 'Execute' permissions on the buffer. Currently not supported. +*/ +#define HAP_PROT_EXEC 0x04 /* pages can be executed */ + + +///@} + +/* + * Cache policy or-ed with protections parameter + */ + + /*! @name HAP_MEM_CACHE + \brief These macros define the cache policies for mapping memory pages to DSP MMU. Default cache policy is cache writeback. + + It is passed as input parameter 'prot', or-ed with page protections to HAP_mmap(). + +*/ + +///@{ + +/*! \def HAP_MEM_CACHE_WRITEBACK + \brief Passing HAP_MEM_CACHE_WRITEBACK as input results in mapping memory as cache writeback +*/ +#define HAP_MEM_CACHE_WRITEBACK (0x10) /* cache write back */ + +/*! \def HAP_MEM_CACHE_NON_SHARED + \brief Passing HAP_MEM_CACHE_NON_SHARED as input results in mapping memory as uncached +*/ +#define HAP_MEM_CACHE_NON_SHARED (0x20) /* normal uncached memory */ + +/*! \def HAP_MEM_CACHE_WRITETHROUGH + \brief Passing HAP_MEM_CACHE_WRITETHROUGH as input results in mapping memory as cache write through +*/ + +#define HAP_MEM_CACHE_WRITETHROUGH (0x40) /* write through memory */ + +///@} + +/*! @name HAP_MEM_FLAGS + \brief These macros define the buffer attribute flags for allocating APPS memory from the DSP. + + It is passed as input parameter 'flags' to HAP_apps_mem_request(). + +*/ + +///@{ + +/*! \def HAP_MEM_FLAGS_SKIP_DSP_MAP + \brief Allocate memory on HLOS but skip DSP mapping +*/ + +#define HAP_MEM_FLAGS_SKIP_DSP_MAP 0 + +/*! \def HAP_MEM_FLAGS_DSP_MAP + \brief Allocate memory on HLOS and map on DSP +*/ + +#define HAP_MEM_FLAGS_DSP_MAP 1 + +/*! \def HAP_MEM_FLAGS_EXTENDED_MAP + \brief Allocate memory on HLOS and map beyond 4GB virtual address range on DSP. + + Unsupported currently. Reserved for future use. +*/ + +#define HAP_MEM_FLAGS_EXTENDED_MAP 2 + +/*! \def HAP_MEM_FLAGS_MAX + \brief Max number of flags supported by HAP_apps_mem_request +*/ + +#define HAP_MEM_FLAGS_MAX (HAP_MEM_FLAGS_EXTENDED_MAP + 1) + +///@} + +/** + * Allocate a block of memory. + * @param[in] bytes size of memory block in bytes. + * @param[out] pptr pointer to the memory block + * @return int AEE_SUCCESS for success and AEE_ENOMEMORY for failure. + */ + +static inline int HAP_malloc(uint32 bytes, void** pptr) +{ + *pptr = malloc(bytes); + if (*pptr) { + return AEE_SUCCESS; + } + return AEE_ENOMEMORY; +} + +/** + * Free the memory block allocated through HAP_malloc(). + * @param[in] ptr pointer to the memory block + * @return int AEE_EBADCLASS if ptr is NULL + AEE_SUCCESS if ptr is not NULL + + */ + +static inline int HAP_free(void* ptr) +{ + if(ptr == NULL) + return AEE_EBADCLASS; + free(ptr); + return AEE_SUCCESS; +} + +/** Statistics of user heap memory */ +struct HAP_mem_stats { + uint64 bytes_free; /**< number of bytes free from all the segments, + * may not be available for a single alloc + */ + uint64 bytes_used; /**< number of bytes used */ + uint64 seg_free; /**< number of segments free */ + uint64 seg_used; /**< number of segments used */ + uint64 min_grow_bytes; /**< minimum number of bytes to grow the heap by when creating a new segment */ +}; + +/** + * @brief Enum for reqID for HAP_mem_get_heap_info() + */ +enum HAP_mem_stats_request { + USAGE_STATS = 1, + MAX_USED +}; + +/** + * @brief RequestID/Response for HAP_mem_get_heap_info + */ +typedef struct { + enum HAP_mem_stats_request req_id; + union { + struct HAP_mem_stats usage_stats; + unsigned long max_used; /* Peak heap usage */ + }; +} HAP_mem_heap_info_t; + +/** + * Get the current statistics from the heap. + * + * @param[in,out] stats pointer to stats structure + * @retval AEE_SUCCESS + */ +int HAP_mem_get_stats(struct HAP_mem_stats *stats); + +/** + * Get the heap info. + * + * @param payload, pointer to store the request/response + * @retval, 0 on success + */ +int HAP_mem_get_heap_info(HAP_mem_heap_info_t *payload); + +/** + * Enum to hold the START and END marker values + * + */ +typedef enum +{ + START = 0, + END +} marker_t; + +/** + * Request types: + * HAP_MEM_LOG_BLOCKS - to log all the blocks to csv + * file named: hprt_block_info_.csv + * + * HAP_MEM_SET_MARKER - to set markers for different instances. + * (2^16 instances are possible per application) + * + * HAP_MEM_MAP - to map buffer at random VA or reserved VA + * + * HAP_MEM_UNMAP - to unmap buffer + * + * HAP_RESERVE_VA - to reserve VA space on DSP without mapping + * + * HAP_UNRESERVE_VA - to unreserve VA space on DSP + */ +typedef enum +{ + HAP_MEM_LOG_BLOCKS = 1, + HAP_MEM_SET_MARKER = 2, + HAP_MEM_MAP = 3, + HAP_MEM_UNMAP = 4, + HAP_RESERVE_VA = 5, + HAP_UNRESERVE_VA = 6 +} HAP_mem_req_t; + +/** + * Payload structure for HAP_MEM_SET_MARKER request + * marker_type, START or END marker + * instance, incase of START - NOOP; if request is success, instance number. + * incase of END - instance number to find leaks + * + */ +typedef struct +{ + marker_t marker_type; + uint16_t instance; +} HAP_mem_marker_payload_t; + +/* Payload structure for HAP_MEM_MAP request */ +typedef struct { + uint64_t addr; // [in] reserved va (optional). If 0, buffer mapped at random VA + uint64_t len; // [in] length of buffer to be mapped + int prot; // [in] permissions and cache-mode of mapping + int flags; // [in] buffer flags + int fd; // [in] file descriptor of buffer + uint64_t dsp_pa; // [in] Offset + uint64_t dsp_va; // [out] Mapped DSP virtual address +} HAP_mem_map_t; + +/* Payload structure for HAP_MEM_UNMAP request */ +typedef struct { + uint64_t dsp_va; // [in] DSP VA to be unmapped + uint64_t len; // [in] length of mapping +} HAP_mem_unmap_t; + +/* Payload structure for HAP_RESERVE_VA request */ +typedef struct { + uint64_t len; // [in] Length of VA space to be reserved + int prot; // [in] Permissions of the VA space + int flags; // [in] flags (unused for now) + uint64_t dsp_va; // [out] Reserved DSP virtual address +} HAP_mem_reserve_t; + +/* Payload structure for HAP_UNRESERVE_VA request */ +typedef struct { + uint64_t dsp_va; // [in] DSP VA to be unreserved + uint64_t len; // [in] Length of buffer to be unreserved +} HAP_mem_unreserve_t; + +/** + * Payload for different requests + * New request payload structures should be + * added to the union. + */ +typedef struct +{ + HAP_mem_req_t request_id; + union { + HAP_mem_marker_payload_t mem_marker_payload; + HAP_mem_map_t mmap; + HAP_mem_unmap_t munmap; + HAP_mem_reserve_t reserve; + HAP_mem_unreserve_t unreserve; + }; +} HAP_mem_req_payload_t; + +/** + * Generic request API, which will decode request type + * and use the payload to parse the input and output + * for the request + * @param mem_payload- input and output payload for the request + * @retval 0 on success. + */ +int HAP_mem_request(HAP_mem_req_payload_t *mem_payload); + +/** + * Set the minimum and maximum grow size. + * + * This API allows to configure the minimum and maximum size that should + * be added to the DSP user heap when an allocation fails and more memory + * needs to be obtained from the HLOS. Using this API is optional. If not + * used, the runtime will try to choose reasonable growth sizes based on + * allocation history. + * + + * @param[in] min minimum bytes to grow the heap by when requesting a new segment + * @param[in] max maximum bytes to grow the heap by when requesting a new segment + * @retval AEE_SUCCESS + * + */ +int HAP_mem_set_grow_size(uint64 min, uint64 max); + +/** + * Set low and high memory thresholds for heap + * + * Thresholds must be tuned according to the memory requirements + * + * Improper thresholds might led to heap failure + * + * @param[in] low_largest_block_size (in bytes) - the heap will grow if size of the largest free block is less than this threshold. + * Currently, setting this parameter will have no impact on the heap. + * @param[in] high_largest_block_size (in bytes) - the heap manager will release all unused sections if size of the largest free block is greater than this threshold. + * The recommended value for this, is the size of largest single allocation possible in your application. + * @return AEE_SUCCESS on success + * AEE_EBADPARM on failure + */ +int HAP_mem_set_heap_thresholds(unsigned int low_largest_block_size, unsigned int high_largest_block_size); + + +/** + * Map buffer associated with the file descriptor to DSP memory. The reference + * count gets incremented if the file descriptor is already mapped. This API is + * limited to buffer size less then 2 GB. Recommendation is to use HAP_mmap2 for + * buffer of size > 2 power(8*sizeof(size_t)) + * + * @param[in] addr mapping at fixed address, not supported currently. This has to be set to NULL + * @param[in] len size of the buffer to be mapped + * @param[in] prot protection flags - supported are only HAP_PROT_READ and HAP_PROT_WRITE. HAP_PROT_EXEC is not supported + * @param[in] flags HAP_MAP_NO_MAP - Increment reference count with no mapping + * 0 - map the buffer and increment the reference count + * @param[in] fd file descriptor for the buffer + * @param[in] offset offset into the buffer + * @retval mapped address + * -1 on failure + */ +void* HAP_mmap(void *addr, int len, int prot, int flags, int fd, long offset); + +/** + * Map buffer associated with the file descriptor to DSP memory. The reference + * count gets incremented if the file descriptor is already mapped. + * + * @param[in] addr mapping at fixed address, not supported currently. This has to be set to NULL + * @param[in] len size of the buffer to be mapped + * @param[in] prot protection flags - supported are only HAP_PROT_READ and HAP_PROT_WRITE. HAP_PROT_EXEC is not supported + * @param[in] flags HAP_MAP_NO_MAP - Increment reference count with no mapping + * 0 - map the buffer and increment the reference count + * @param[in] fd file descriptor for the buffer + * @param[in] offset offset into the buffer + * @retval mapped address + * -1 on failure + */ +void* HAP_mmap2(void *addr, size_t len, int prot, int flags, int fd, long offset); + +/** + * Decrements the reference count and unmaps the buffer from memory if the reference count goes to 0. + * This API is used for buffer size less then 2 GB. Recommendation is to use HAP_munmap2 for buffer of + * size > 2 power(8*sizeof(size_t)). + * + * @param[in] addr mapped address + * @param[in] len size of the mapped buffer + * @return 0 on success + * AEE_NOSUCHMAP in input addr is invalid + */ +int HAP_munmap(void *addr, int len); + +/** + * Decrements the reference count and unmaps the buffer from memory if the reference count goes to 0. + * + * @param[in] addr mapped address + * @param[in] len size of the mapped buffer + * @return 0 on success + * AEE_NOSUCHMAP in input addr is invalid + */ +int HAP_munmap2(void *addr, size_t len); + +/** + * Get virtual and physical address associated with the buffer and increments + * the reference count. + * + * @param[in] fd file descriptor for the buffer + * @param[out] vaddr virtual address associated with the buffer + * @param[out] paddr physical address associated with the buffer + * @retval 0 on success + * AEE_ENOSUCHMAP if fd is invalid + */ +int HAP_mmap_get(int fd, void **vaddr, uint64 *paddr); + +/** + * Decrements the reference count of the file descriptor. + * + *@param[in] fd file descriptor of the buffer + *@retval 0 on success + * AEE_ENOSUCHMAP if fd is invalid + * AEE_EBADMAPREFCNT if map refcount is <=0 + */ +int HAP_mmap_put(int fd); + +/** + * Get the stack size (in bytes) available for current thread + * Supported only on Lahaina and Cedros + * @return available stack for current thread, on success + * AEE_EINVALIDTHREAD if unable to get current thread id + * AEE_ERESOURCENOTFOUND if unable to get stack for current thread + */ +uint64 HAP_mem_available_stack(void); + +/** + * Allocate and map APPS memory from DSP + * + * Usage of this API over malloc() is recommended when client wants greater control over DSP virtual address space + * as free() does not necessarily free the allocated memory depending on heap thresholds. + * HAP_apps_mem_request and HAP_apps_mem_release guarantee freeing of the allocated memory. + * + * @param[in] len size of memory to be allocated + * @param[in] flags Buffer attribute flags HAP_MEM_FLAGS_SKIP_DSP_MAP, HAP_MEM_FLAGS_DSP_MAP or HAP_MEM_FLAGS_EXTENDED_MAP + * @param[out] fd file descriptor of buffer + * @param[out] dsp_va DSP mapped virtual address + * @return 0 on success + */ +int HAP_apps_mem_request(size_t len, uint32_t flags, int *fd, uint64_t *dsp_va); + +/** + * Release previously allocated APPS memory from DSP. + * Releases memory from HLOS. Also unmaps memory from DSP + * if HAP_MEM_FLAGS_DSP_MAP was previously passed while + * requesting memory. + * + * @param[in] fd previously returned file descriptor of buffer + * @return 0 on success + */ +int HAP_apps_mem_release(int fd); + +#ifdef __cplusplus +} +#endif + +#endif // HAP_MEM_H + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.md new file mode 100755 index 0000000000000..42be2ab6cba12 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_mem.md @@ -0,0 +1,75 @@ +# HAP_mem APIs + +## Overview +The HAP_mem APIs provide functionality available from the DSP to + +* allocate and free memory - HAP_malloc() and HAP_free() +* map and unmap ION buffers allocated on the application processor and passed to the DSP using file descriptors - HAP_mmap() and HAP_munmap() +* get heap statistics and set properties - HAP_mem_get_stats(), HAP_mem_set_grow_size(), HAP_mmap_get(), HAP_mem_set_heap_thresholds() and HAP_mmap_put() +* allocate and free APPS memory - HAP_apps_mem_request() and HAP_apps_mem_free() + +## Memory mapping + +A common usage scenario for using the mapping functionality consists of the application processor allocating ION memory and passing the file descriptor to the DSP. +The DSP will then use the HAP_mem APIs to map the buffer onto the DSP and obtain a memory pointer. The mapping will remain valid until the buffer is being unmapped. +This approach allows to maintain a mapping across multiple FastRPC calls. + +## Memory allocation + +HAP_malloc and HAP_free are simple wrappers around the DSP malloc and free functions. +If a user memory allocation request cannot be fulfilled with the existing DSP heap, the FastRPC +runtime will attempt to grow the DSP heap by reserving additional memory from the HLOS. + +The HAP_set_grow_size API can be called to configure the minimum and maximum size that should be added to the DSP heap when one of these growth events occurs. +If many growth events are anticipated, it may be appropriate to set a larger growth rate to reduce the number of growth events. However, increasing +the heap more than necessary will impact HLOS performance. Therefore, care must be taken in finding the appropriate growth rate for a given application. + +Here is how the min and max values set by the HAP_set_grow_size control the growth of the heap: + + min_grow_bytes = MIN(max,MAX(min,min_grow_bytes)); + + // The value will be aligned to the next 1MB boundary. + + actual_grow_bytes = min_grow_bytes + request_size + actual_grow_bytes = ALIGN(actual_grow_bytes,0x100000) + +`HAP_apps_mem_request()` and `HAP_apps_mem_release()` APIs can be called from the DSP to allocate APPS memory and map the same memory on the DSP if required. + +These HAP request and release APIs are recommended when the user wants greater control over the DSP virtual address space: unlike `malloc` and `free`, these APIs guarantee that the memory will be mapped when allocated and unmapped when freed. + +The mapping on the DSP can be controlled using the `flags` parameter in `HAP_apps_mem_request()`: + + * `HAP_MEM_FLAGS_SKIP_DSP_MAP` results in skipping the mapping on the DSP. In that case, the user needs to map the DSP memory by calling `HAP_mmap()`. + + * `HAP_MEM_FLAGS_DSP_MAP` results in mapping the buffer on the DSP upon calling `HAP_apps_mem_request()`. + +`HAP_apps_mem_release()` will always free the allocated HLOS memory but will only unmap the buffer on the DSP if the flag `HAP_MEM_FLAGS_DSP_MAP` was used when calling `HAP_apps_mem_request()`. + +***NOTE*** +If HAP_MEM_FLAGS_SKIP_DSP_MAP flag was used when calling `HAP_apps_mem_request()`, and the memory was mapped later using `HAP_mmap()`, then the user needs to unmap DSP memory by calling `HAP_munmap()`. + +## Memory statistics + +HAP_mem_get_stats is useful when called at the beginning and end of an application to check for any memory leaks. + +## Memory request API +HAP_mem_request is the request API, which support different request types. Requests supported are: + +* `HAP_MEM_LOG_BLOCKS`: This request will log all the heap blocks to the csv file named - hprt_block_info_.csv, for parsing use QMemCheck tool. + If block info logging is successful - 0 will be returned back by the HAP_mem_request. This request doesn't need any payload union. +* `HAP_MEM_SET_MARKER`: This request is to mark instances for leak detection, the markers can be START or END markers. + When START marker is called, a marker instance number will be returned back to caller of the API (if the request is SUCCESS(0)) in the payload member: + mem_marker_payload. + When END marker is called, the caller should fill the instance number for which marker needs to be ended. If the request is success, + all the leaks from the START to END of that instance will be logged to hprt_leak_block_info__.csv +* `HAP_MEM_MAP`: This request is to create a DSP mapping for a shared buffer. + The payload structure for this request can be referred to in `HAP_mem_map_t`. To create the mapping at a reserved va, the start address needs to be specified in the `addr` field of the payload. + If the request is SUCCESS(0), the `dsp_va` member of payload will hold the mapped virtual address (VA). +* `HAP_MEM_UNMAP`: This request is to unmap the memory region on the DSP. + The payload structure for this request can be referred to in `HAP_mem_unmap_t`. The starting virtual address and length of buffer needs to passed as payload members `dsp_va` and `len`. + If the request is SUCCESS(0), the virtual address (VA) mapping is removed from the DSP. +* `HAP_RESERVE_VA`: This request is to reserve virtual address (VA) space on the DSP without creating any mappings. + The payload structure for this request can be referred to in `HAP_mem_reserve_t`. + If the request is SUCCESS(0), the `dsp_va` member of payload will hold the reserved virtual address (VA). +* `HAP_UNRESERVE_VA`: This request is to unreserve the virtual address (VA) space on the DSP. + The payload structure for this request can be referred to in `HAP_mem_unreserve_t`. If the request is SUCCESS(0), the virtual address space is successfully unreserved. diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_pd_dtor.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_pd_dtor.h new file mode 100755 index 0000000000000..e612ed135a908 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_pd_dtor.h @@ -0,0 +1,51 @@ +#ifndef HAP_PD_DTOR_H +#define HAP_PD_DTOR_H +/*============================================================================== + Copyright (c) 2015 Qualcomm Technologies Incorporated. + All Rights Reserved Qualcomm Technologies Proprietary + + Export of this technology or software is regulated by the U.S. + Government. Diversion contrary to U.S. law prohibited. +==============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This type is used to provide the qdi driver the register address, and the + * bits of the register to clear. + * + * @param register_addr, The register address whose value needs to modified on process exit + * @param register_mask, A mask that indicates which bits of the register need to be set. + * @param register_val, The value that needs to be applied to the unmasked bits. + */ +typedef struct { + uintptr_t register_addr; + uint32 register_mask; + uint32 register_value; +}HAP_register_t; + +/** + * A fastrpc process can call this method and provide a list of register addresses + * and their desired values. When the fastrpc process exits, a previous call to this + * method will ensure that the bits (defined in the bitmask) for the provided + * registers are cleared. + + * @param num_registers, Number of registers that need to be modified on process exit + * @param registers, The register address and masks. + */ +int HAP_clear_registers(unsigned int num_registers, HAP_register_t* registers); + +/** + * This method is used by the kernel to free any memory that + * a fastrpc client might have line-locked +*/ +int HAP_free_linelocked_memory(unsigned int asid); + +#ifdef __cplusplus +} +#endif + +#endif /*HAP_PD_DTOR_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.h new file mode 100755 index 0000000000000..1f9da76d8c785 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.h @@ -0,0 +1,120 @@ +/*============================================================================== +@file + HAP_perf.h + +@brief + Header file for DSP Perf APIs + +Copyright (c) 2012-2017, 2020 QUALCOMM Technologies, Incorporated. +All Rights Reserved. +QUALCOMM Proprietary. +==============================================================================*/ +#ifndef HAP_PERF_H +#define HAP_PERF_H + +#include "AEEStdDef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup timer_functionality Timer functionality. + * @{ + */ + +/** + * Gets the current value of 56-bit, 19.2MHz hardware counter converted + * to micro-seconds. This value should be treated as relative and + * not absolute. The value wraps around to zero once it exceeds the + * maxiumum value. This function performs an integer division in order + * to convert ticks to time, which adds some overhead. Consider using + * HAP_perf_get_qtimer_count for a lower overhead. +*/ +#ifdef __hexagon__ +#include "hexagon_sim_timer.h" +static inline uint64 HAP_perf_get_time_us(void) +{ + /* Converts ticks into microseconds + 1 tick = 1/19.2MHz seconds + Micro Seconds = Ticks * 10ULL/192ULL */ + unsigned long long count; + asm volatile (" %0 = c31:30 " : "=r"(count)); + return (uint64)(count) * 10ull / 192ull; +} +#else +uint64 HAP_perf_get_time_us(void) +{ + static long long start = 0; + // TODO + // assume 500 MHz on simulator + //return HAP_perf_get_pcycles() / 500; + return start++; +} +#endif + +/** + * Gets the current 56 bit, 19.2MHz global hardware clock count. + * This value should be treated as relative and not absolute. + * The value wraps around to zero once it exceeds the maxiumum value. +*/ +static inline uint64 HAP_perf_get_qtimer_count(void) { + unsigned long long cur_count; + asm volatile(" %0 = c31:30 " : "=r"(cur_count)); + return (uint64)cur_count; +} + +/** + * Converts the 19.2 MHz global hardware count to micro-seconds. + * @param[in] count - 19.2 MHz global hardware count + * @returns - Time in micro-seconds. +*/ +uint64 HAP_perf_qtimer_count_to_us(uint64 count); + +/** + * Gets the current 64-bit Hexagon Processor cycle count. + * The processor cycle count is the current number of processor + * cycles executed since the processor was last reset. Note + * that this counter stops incrementing whenever the DSP enters + * a low-power state (such as clock gating), as opposed to the + * qtimer, which increments regardless of the DSP power state. +*/ +#ifdef __hexagon__ +#include "hexagon_sim_timer.h" +static inline uint64 HAP_perf_get_pcycles(void) +{ + uint64_t pcycle; + asm volatile ("%[pcycle] = C15:14" : [pcycle] "=r"(pcycle)); + return pcycle; +} +#else +uint64 HAP_perf_get_pcycles(void) +{ + return (uint64)0; +} +#endif + +/** + * @} + */ + +/** @defgroup sleep_functionality Sleep functionality. + * @{ + */ + +/** + * Suspends the calling thread from execution until the + * specified duration has elapsed. + * @param[in] sleep_duration: - Sleep duration in micro-seconds. + * @returns - returns 0 on success, non zero in error case. +*/ +int HAP_timer_sleep(unsigned long long sleep_duration); + +/** + * @} // sleep_functionality + */ + +#ifdef __cplusplus +} +#endif + +#endif // HAP_PERF_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.md new file mode 100755 index 0000000000000..39895f35a5699 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_perf.md @@ -0,0 +1,23 @@ +# Introduction {#intro} + +The Hexagon SDK provides APIs to measure the elapsed time in both microseconds +and processor cycles(pcycles). + + +# API Overview {#api-overview} + +The HAP_perf APIs are used by clients for profiling their code when running on the DSP. The profiling +can be done in both microseconds and pcycles based on the needs. Morevover, the HAP_perf library +also provides sleep APIs to the clients. + +The HAP_perf APIs include the following functions: + +::HAP_perf_get_time_us + +::HAP_perf_get_qtimer_count + +::HAP_perf_qtimer_count_to_us + +::HAP_perf_get_pcycles + +::HAP_timer_sleep diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.h new file mode 100755 index 0000000000000..55138edb1871f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.h @@ -0,0 +1,825 @@ +/*============================================================================== +@file + HAP_power.h + +@brief + Header file of DSP power APIs. + +Copyright (c) 2015,2019,2022 Qualcomm Technologies, Inc. +All rights reserved. Qualcomm Proprietary and Confidential. +==============================================================================*/ + +#ifndef _HAP_POWER_H +#define _HAP_POWER_H + +#include "AEEStdErr.h" +#include "AEEStdDef.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//Add a weak reference so shared objects do not throw link error +#pragma weak HAP_power_destroy_client + +/** + * Low-power modes for HAP DCVS V3 interface, used in 'sleep_disable' param in DCVS_v3. + * + * In general, applications are expected to vote for their latency tolerance via the + * 'latency' parameter in DCVS_v3/DCVS_v2 options. The aggregated latency vote across + * clients is used in selecting appropriate low-power mode (LPM) of the DSP subsystem. + * LPM will save power when the DSP subsystem is idle by reducing leakage current. + * Deeper LPMs typically have higher wake up latencies, which will increase interrupt + * service delays and add to inter-processor communication latencies. Though the + * latency vote controls the selection of low-power modes, the vote required for + * disabling/allowing certain LPMs is difficult to calculate as the wakeup latency + * associated with these LPMs could change from chipset to chipset and between runs + * within the same chipset. + * + * This 'sleep_disable' parameter in DCVS_v3 allows user to directly prevent certain LPM + * levels of the DSP subsystem. By default, there is no restriction placed on LPMs i.e. + * all the LPMs are enabled and the aggregated latency vote (along with other system + * parameters) is used in LPM selection. The 'sleep_disable' parameter in DCVS_v3 is for + * the advanced developers who would like to disable certain low-power modes explicitly + * irrespective of the latency vote. Developers need to consider their power-performance + * tradeoff requirements and if necessary profile the results before voting using this + * parameter. Regular users are suggested to choose the default i.e. 'HAP_DCVS_LPM_ENABLE_ALL'. + * + * If any particular LPM level is not supported on the DSP subsystem then it will enable + * nearest shallow LPM level. For example, in absense of 'HAP_DCVS_LPM_LEVEL3' it will select + * 'HAP_DCVS_LPM_LEVEL2' which is nearest shallow LPM level to 'HAP_DCVS_LPM_LEVEL3'. + */ +#define HAP_DCVS_LPM_LEVEL1 1 /**< To disable all low-power modes */ +#define HAP_DCVS_LPM_LEVEL2 2 /**< To enable only standalone APCR */ +#define HAP_DCVS_LPM_LEVEL3 3 /**< To enable RPM assisted APCR */ +#define HAP_DCVS_LPM_ENABLE_ALL 0 /**< To enable all low-power modes (enables full power collapse) */ + +#define HAP_DCVS_VOLT_CORNER_TURBO_L2_L3_DEFINED /**< To indicate presence of L2 and L3 corners in HAP_dcvs_voltage_corner_t */ +#define HAP_POWER_SET_HMX_V2_DEFINED /**< To indicate support for HAP_power_set_HMX_v2 request type in HAP_power_set */ +#define HAP_POWER_SET_CENG_BUS_VOTING_DEFINED /**< To indicate support for HAP_power_set_CENG_bus request type in HAP power_set */ + +/** +* Possible error codes returned +*/ +typedef enum { + HAP_POWER_ERR_UNKNOWN = -1, + HAP_POWER_ERR_INVALID_PARAM = -2, + HAP_POWER_ERR_UNSUPPORTED_API = -3 +} HAP_power_error_codes; + +/** Payload for HAP_power_set_mips_bw */ +typedef struct { + boolean set_mips; /**< Set to TRUE to request MIPS */ + unsigned int mipsPerThread; /**< mips requested per thread, to establish a minimal clock frequency per HW thread */ + unsigned int mipsTotal; /**< Total mips requested, to establish total number of MIPS required across all HW threads */ + boolean set_bus_bw; /**< Set to TRUE to request bus_bw */ + uint64 bwBytePerSec; /**< Max bus BW requested (bytes per second) */ + unsigned short busbwUsagePercentage; /**< Percentage of time during which bwBytesPerSec BW is required from the bus (0..100) */ + boolean set_latency; /**< Set to TRUE to set latency */ + int latency; /**< maximum hardware wakeup latency in microseconds. The higher the value, + * the deeper state of sleep that can be entered but the longer it may take + * to awaken. Only values > 0 are supported (1 microsecond is the smallest valid value) */ +} HAP_power_mips_bw_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ + /** Clock frequency match type*/ +typedef enum { + HAP_FREQ_AT_LEAST, /**< Matches at least the specified frequency. */ + HAP_FREQ_AT_MOST, /**< Matches at most the specified frequency. */ + HAP_FREQ_CLOSEST, /**< Closest match to the specified frequency. */ + HAP_FREQ_EXACT, /**< Exact match with the specified frequency. */ + HAP_FREQ_MAX_COUNT /**< Maximum count. */ +} HAP_freq_match_type; +/** + * @} // HAP_power_enums + */ + +/** Configuration for bus bandwidth */ +typedef struct { + boolean set_bus_bw; /**< Set to TRUE to request bus_bw */ + uint64 bwBytePerSec; /**< Max bus BW requested (bytes per second) */ + unsigned short busbwUsagePercentage; /**< Percentage of time during which bwBytesPerSec BW is required from the bus (0..100) */ +} HAP_power_bus_bw; + +/** +* @brief Payload for vapps power request +* vapps core is used for Video post processing +*/ +typedef struct { + boolean set_clk; /**< Set to TRUE to request clock frequency */ + unsigned int clkFreqHz; /**< Clock frequency in Hz */ + HAP_freq_match_type freqMatch; /**< Clock frequency match */ + HAP_power_bus_bw dma_ext; /**< DMA external bus bandwidth */ + HAP_power_bus_bw hcp_ext; /**< HCP external bus bandwidth */ + HAP_power_bus_bw dma_int; /**< DMA internal bus bandwidth */ + HAP_power_bus_bw hcp_int; /**< HCP internal bus bandwidth */ +} HAP_power_vapss_payload; + +/** +* @brief Payload for vapps_v2 power request +* Supported in targets which have split VAPPS core(DMA and HCP) form Hana onwards +*/ +typedef struct { + boolean set_dma_clk; /**< Set to TRUE to reqeust DMA clock frequency */ + boolean set_hcp_clk; /**< Set to TRUE to reqeust HCP clock frequency */ + unsigned int dmaClkFreqHz; /**< DMA Clock frequency in Hz */ + unsigned int hcpClkFreqHz; /**< HCP Clock frequency in Hz */ + HAP_freq_match_type freqMatch; /**< Clock frequency match type */ + HAP_power_bus_bw dma_ext; /**< DMA external bus bandwidth */ + HAP_power_bus_bw hcp_ext; /**< HCP external bus bandwidth */ + HAP_power_bus_bw dma_int; /**< DMA internal bus bandwidth */ + HAP_power_bus_bw hcp_int; /**< HCP internal bus bandwidth */ +} HAP_power_vapss_payload_v2; + +/** Payload for HAP_power_set_HVX */ +typedef struct { + boolean power_up; /**< Set to TRUE to turn on HVX, and FALSE to turn off. */ +} HAP_power_hvx_payload; + +/** +* Payload for HAP_power_set_HMX +* Supported from Lahaina onwards*/ +typedef struct { + boolean power_up; /**< Set to TRUE to turn on HMX, and FALSE to turn off. + * When TRUE, on chipsets with separate HMX clock, a default + * HMX clock will be selected based on the voted + * Q6 core clock level from the same HAP_power_set context. + */ +} HAP_power_hmx_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ +/** Payload for HAP power client classes */ +typedef enum { + HAP_POWER_UNKNOWN_CLIENT_CLASS = 0x00, /**< Unknown client class */ + HAP_POWER_AUDIO_CLIENT_CLASS = 0x01, /**< Audio client class */ + HAP_POWER_VOICE_CLIENT_CLASS = 0x02, /**< Voice client class */ + HAP_POWER_COMPUTE_CLIENT_CLASS = 0x04, /**< Compute client class */ + HAP_POWER_STREAMING_1HVX_CLIENT_CLASS = 0x08, /**< Camera streaming with 1 HVX client class */ + HAP_POWER_STREAMING_2HVX_CLIENT_CLASS = 0x10, /**< Camera streaming with 2 HVX client class */ +} HAP_power_app_type_payload; +/** + * @} // HAP_power_enums + */ + +/** Payload for HAP_power_set_linelock */ +typedef struct { + void* startAddress; /**< Start address of the memory region to be locked. */ + uint32 size; /**< Size (bytes) of the memory region to be locked. Set size + * to 0 to unlock memory. */ + uint32 throttleBlockSize; /**< Block size for throttling, in bytes; + * 0 for no throttling. The region to be locked will be divided into + * blocks of this size for throttling purposes. + * Use for locking larger cache blocks. + * Applicable only when enabling line locking.Only ONE throttled linelock call is supported at this time. + * You can linelock additional regions (without throttling) using HAP_power_set_linelock_nothrottle*/ + uint32 throttlePauseUs; /**< Pause to be applied between locking each block, in microseconds. Applicable only when enabling line locking*/ +} HAP_power_linelock_payload; + +/** Payload for HAP_power_set_linelock_nothrottle */ +typedef struct { + void* startAddress; /**< Start address of the memory region to be locked. */ + uint32 size; /**< Size (bytes) of the memory region to be locked. Set size to 0 + * to unlock memory */ +} HAP_power_linelock_nothrottle_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ +/** Option for dcvs payload */ +typedef enum { + HAP_DCVS_ADJUST_UP_DOWN = 0x1, /**< increase and decrease core/bus clock speed. */ + HAP_DCVS_ADJUST_ONLY_UP = 0x2, /**< restricts DCVS from lowering the clock speed below the requested value . */ +} HAP_power_dcvs_payload_option; +/** + * @} // HAP_power_enums + */ + +/** Payload for HAP_power_set_DCVS */ +typedef struct { + boolean dcvs_enable; /**< Set to TRUE to participate in DCVS, and FALSE otherwise. */ + HAP_power_dcvs_payload_option dcvs_option; /**< Set to one of + * HAP_DCVS_ADJUST_UP_DOWN - Allows for DCVS to adjust up and down. + * HAP_DCVS_ADJUST_ONLY_UP - Allows for DCVS to adjust up only. */ +} HAP_power_dcvs_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ +/** Voltage corners for HAP DCVS V2 interface */ +typedef enum { + HAP_DCVS_VCORNER_DISABLE, + HAP_DCVS_VCORNER_SVS2, + HAP_DCVS_VCORNER_SVS, + HAP_DCVS_VCORNER_SVS_PLUS, + HAP_DCVS_VCORNER_NOM, + HAP_DCVS_VCORNER_NOM_PLUS, + HAP_DCVS_VCORNER_TURBO, + HAP_DCVS_VCORNER_TURBO_PLUS, + HAP_DCVS_VCORNER_TURBO_L2, /**< On targets released till Kailua, HAP_DCVS_VCORNER_TURBO_L2 level will be treated as HAP_DCVS_VCORNER_TURBO_PLUS */ + HAP_DCVS_VCORNER_TURBO_L3, /**< On targets released till Kailua, HAP_DCVS_VCORNER_TURBO_L3 level will be treated as HAP_DCVS_VCORNER_TURBO_PLUS */ + HAP_DCVS_VCORNER_MAX = 255, +} HAP_dcvs_voltage_corner_t; + +/** +* Expanded voltage corners for HAP_power_set corner voting options +*/ +typedef enum { + HAP_DCVS_EXP_VCORNER_DISABLE = 0, + HAP_DCVS_EXP_VCORNER_MIN = 0x100, + /**< Selects the minimum voltage corner defined for the chipset */ + HAP_DCVS_EXP_VCORNER_LOW_SVS_D2 = 0x134, + HAP_DCVS_EXP_VCORNER_LOW_SVS_D1 = 0x138, + HAP_DCVS_EXP_VCORNER_LOW_SVS = 0x140, + HAP_DCVS_EXP_VCORNER_SVS = 0x180, + HAP_DCVS_EXP_VCORNER_SVS_L1 = 0x1C0, + HAP_DCVS_EXP_VCORNER_NOM = 0x200, + HAP_DCVS_EXP_VCORNER_NOM_L1 = 0x240, + HAP_DCVS_EXP_VCORNER_TUR = 0x280, + HAP_DCVS_EXP_VCORNER_TUR_L1 = 0x2A0, + HAP_DCVS_EXP_VCORNER_TUR_L2 = 0x2B0, + HAP_DCVS_EXP_VCORNER_TUR_L3 = 0x2C0, + HAP_DCVS_EXP_VCORNER_MAX = 0xFFFF, + /**< Selects the maximum voltage corner defined for the chipset */ +} HAP_dcvs_exp_voltage_corner_t; + +/** +* Perf modes to specify clock frequency level within +* target voltage corner. +*/ +typedef enum { + HAP_CLK_PERF_HIGH = 0, /**< To select max frequency at target voltage corner. */ + HAP_CLK_PERF_LOW, /**< To select min frequency at target voltage corner. */ +} HAP_clk_perf_mode_t; + +/** + * @} // HAP_power_enums + */ + +#define HAP_DCVS_VCORNER_SVSPLUS HAP_DCVS_VCORNER_SVS_PLUS +#define HAP_DCVS_VCORNER_NOMPLUS HAP_DCVS_VCORNER_NOM_PLUS +#define HAP_DCVS_VCORNER_TURBO_L1 HAP_DCVS_VCORNER_TURBO_PLUS + +/** DCVS parameters for HAP_power_dcvs_v2_payload */ +typedef struct { + HAP_dcvs_voltage_corner_t target_corner; /**< target voltage corner */ + HAP_dcvs_voltage_corner_t min_corner; /**< minimum voltage corner */ + HAP_dcvs_voltage_corner_t max_corner; /**< maximum voltage corner */ + uint32 param1; /**< reserved */ + uint32 param2; /**< reserved */ + uint32 param3; /**< reserved */ +} HAP_dcvs_params_t; + +/** Core clock parameters for HAP_power_dcvs_v3_payload */ +typedef struct { + HAP_dcvs_voltage_corner_t target_corner; /**< target voltage corner */ + HAP_dcvs_voltage_corner_t min_corner; /**< minimum voltage corner */ + HAP_dcvs_voltage_corner_t max_corner; /**< maximum voltage corner */ + uint32 param1; /**< reserved */ + uint32 param2; /**< reserved */ + uint32 param3; /**< reserved */ +} HAP_core_params_t; + +/** Bus clock parameters for HAP_power_dcvs_v3_payload */ +typedef struct { + HAP_dcvs_voltage_corner_t target_corner; /**< target voltage corner */ + HAP_dcvs_voltage_corner_t min_corner; /**< minimum voltage corner */ + HAP_dcvs_voltage_corner_t max_corner; /**< maximum voltage corner */ + uint32 param1; /**< reserved */ + uint32 param2; /**< reserved */ + uint32 param3; /**< reserved */ +} HAP_bus_params_t; + +/** DCVS v3 parameters for HAP_power_dcvs_v3_payload */ +typedef struct { + uint32 param1; /**< reserved */ + uint32 param2; /**< reserved */ + uint32 param3; /**< reserved */ + uint32 param4; /**< reserved */ + uint32 param5; /**< reserved */ + uint32 param6; /**< reserved */ +} HAP_dcvs_v3_params_t; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ +/** option for dcvs_v2 payload */ +typedef enum { + HAP_DCVS_V2_ADJUST_UP_DOWN = 0x1, /**< Allows for DCVS to adjust up and down. */ + HAP_DCVS_V2_ADJUST_ONLY_UP = 0x2, /**< Allows for DCVS to adjust up only. */ + HAP_DCVS_V2_POWER_SAVER_MODE = 0x4, /**< HAP_DCVS_POWER_SAVER_MODE - Higher thresholds for power efficiency. */ + HAP_DCVS_V2_POWER_SAVER_AGGRESSIVE_MODE = 0x8, /**< HAP_DCVS_POWER_SAVER_AGGRESSIVE_MODE - Higher thresholds for power efficiency with faster ramp down. */ + HAP_DCVS_V2_PERFORMANCE_MODE = 0x10, /**< HAP_DCVS_PERFORMANCE_MODE - Lower thresholds for maximum performance */ + HAP_DCVS_V2_DUTY_CYCLE_MODE = 0x20, /**< HAP_DCVS_DUTY_CYCLE_MODE - only for HVX based clients. + * For streaming class clients: + * > detects periodicity based on HVX usage + * > lowers clocks in the no HVX activity region of each period. + * For compute class clients: + * > Lowers clocks on no HVX activity detects and brings clocks up on detecting HVX activity again. + * > Latency involved in bringing up the clock with be at max 1 to 2 ms. */ + + + +} HAP_power_dcvs_v2_payload_option; +/** + * @} // HAP_power_enums + */ +/** Payload for HAP_power_set_DCVS_v2 */ +typedef struct { + boolean dcvs_enable; /**< Set to TRUE to participate in DCVS, and FALSE otherwise */ + HAP_power_dcvs_v2_payload_option dcvs_option; /**< Set to one of HAP_power_dcvs_v2_payload_option */ + boolean set_latency; /**< TRUE to set latency parameter, otherwise FALSE */ + uint32 latency; /**< sleep latency */ + boolean set_dcvs_params; /**< TRUE to set DCVS params, otherwise FALSE */ + HAP_dcvs_params_t dcvs_params; /**< DCVS parameters */ +} HAP_power_dcvs_v2_payload; + +/** Payload for HAP_power_set_DCVS_v3 */ +typedef struct { + boolean set_dcvs_enable; /**< TRUE to consider DCVS enable/disable and option parameters, otherwise FALSE */ + boolean dcvs_enable; /**< Set to TRUE to participate in DCVS, and FALSE otherwise. */ + HAP_power_dcvs_v2_payload_option dcvs_option; /**< Set to one of HAP_power_dcvs_v2_payload_option */ + boolean set_latency; /**< TRUE to consider latency parameter, otherwise FALSE */ + uint32 latency; /**< sleep latency */ + boolean set_core_params; /**< TRUE to consider core clock params, otherwise FALSE */ + HAP_core_params_t core_params; /**< Core clock parameters */ + boolean set_bus_params; /**< TRUE to consider bus clock params, otherwise FALSE */ + HAP_bus_params_t bus_params; /**< Bus clock parameters */ + boolean set_dcvs_v3_params; /**< TRUE to consider DCVS v3 params, otherwise FALSE */ + HAP_dcvs_v3_params_t dcvs_v3_params; /**< DCVS v3 parameters */ + boolean set_sleep_disable; /**< TRUE to consider sleep disable/enable parameter, otherwise FALSE */ + unsigned char sleep_disable; /**< See HAP_DCVS_LPM_LEVEL1, HAP_DCVS_LPM_LEVEL2, HAP_DCVS_LPM_LEVEL3 and HAP_DCVS_LPM_ENABLE ALL above */ +} HAP_power_dcvs_v3_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ + /** Type for dcvs update request */ +typedef enum { + HAP_POWER_UPDATE_DCVS = 1, + HAP_POWER_UPDATE_SLEEP_LATENCY, + HAP_POWER_UPDATE_DCVS_PARAMS, +} HAP_power_update_type_t; +/** + * @} // HAP_power_enums + */ +/** Payload for DCVS update */ +typedef struct { + boolean dcvs_enable; /**< TRUE for DCVS enable and FALSE for DCVS disable */ + HAP_power_dcvs_v2_payload_option dcvs_option; /**< Requested DCVS policy in case DCVS enable is TRUE */ +} HAP_power_update_dcvs_t; + +/** Payload for latency update */ +typedef struct { + boolean set_latency; /**< TRUE if sleep latency request has to be considered */ + unsigned int latency; /**< Sleep latency request in micro seconds */ +} HAP_power_update_latency_t; + +/** Payload for DCVS params update */ +typedef struct { + boolean set_dcvs_params; /**< Flag to mark DCVS params structure validity, TRUE for valid DCVS + *params request and FALSE otherwise */ + HAP_dcvs_params_t dcvs_params; /**< Intended DCVS params if set_dcvs_params is set to TRUE */ +} HAP_power_update_dcvs_params_t; + +/** Payload for HAP_power_set_DCVS_v2 */ +typedef struct { + HAP_power_update_type_t update_param; /**< Type for which param to update */ + union { + HAP_power_update_dcvs_t dcvs_payload; + HAP_power_update_latency_t latency_payload; + HAP_power_update_dcvs_params_t dcvs_params_payload; + }; /**< Update payload for DCVS, latency or DCVS params */ +} HAP_power_dcvs_v2_update_payload; + +/** Payload for HAP_power_set_streamer */ +typedef struct { + boolean set_streamer0_clk; /**< Set streamer 0 clock */ + boolean set_streamer1_clk; /**< Set streamer 1 clock */ + unsigned int streamer0_clkFreqHz; /**< Streamer 0 clock frequency */ + unsigned int streamer1_clkFreqHz; /**< Streamer 1 clock frequency */ + HAP_freq_match_type freqMatch; /**< Clock frequency match */ + uint32 param1; /**< Reserved for future streamer parameters */ + uint32 param2; /**< Reserved for future streamer parameters */ + uint32 param3; /**< Reserved for future streamer parameters */ +} HAP_power_streamer_payload; + +/** +* Payload for HAP_power_set_HMX_v2. +* Provides user flexibility to vote for HMX clock based on either voltage +* corner or frequency. User can also provide DCVS limits for HMX clock when +* DCVS participation is enabled via HAP_power_set_DCVS/_v2/_v3 options. +* On chipsets without separate HMX clock, requests made for target corner or +* frequency will return AEE_EBADPARM error. +*/ + +typedef struct { + boolean set_power; /**< Set to TRUE to consider HMX power_up parameter to turn ON/OFF HMX, otherwise FALSE. */ + boolean power_up; /**< Set to TRUE to turn on HMX, and FALSE to turn off. */ + boolean set_clock; /**< TRUE to consider HMX clock parameters. All the following parameters + * will be ignored if set to FALSE. By default, lowest HMX clock frequency will be selected. + * The default being 0 for pick_default, target_corner, freq_mhz and floor_freq_mhz. */ + boolean pick_default; /**< Set to TRUE to select default HMX clock based on the voted + * Q6 core clock level from the same HAP_power_set context, otherwise FALSE. + * When TRUE, target_corner, freq_mhz and floor_freq_mhz params + * should be set to 0.*/ + HAP_dcvs_exp_voltage_corner_t target_corner; /**< Target voltage corner. See HAP_dcvs_exp_voltage_corner_t. + * For target_corner > 0, pick_default, freq_mhz and floor_freq_mhz + * params should be set to 0. + * Maximum target_corner request among the requesting clients + * will be considered as the final vote. */ + HAP_dcvs_exp_voltage_corner_t min_corner; /**< minimum voltage corner for DCVS. See HAP_dcvs_exp_voltage_corner_t. */ + HAP_dcvs_exp_voltage_corner_t max_corner; /**< maximum voltage corner for DCVS. See HAP_dcvs_exp_voltage_corner_t. */ + HAP_clk_perf_mode_t perf_mode; /**< To specify clock frequency level within target voltage corner. */ + uint32 freq_mhz; /**< Frequency request in MHz. freq_mhz requests across clients + * will be accumulated. For freq_mhz > 0, target_corner and + * pick_default should be set to 0. */ + uint32 floor_freq_mhz; /**< Floor frequency request in MHz. + * For floor_freq_mhz > 0, target_corner and pick_default + * should be set to 0. Maximum floor_freq_mhz request among the + * requesting clients will be considered. + * Maximum between the aggregated freq_mhz and floor_freq_mhz + * will be considered as the final frequency request. */ + uint32 param1; /**< Reserved */ + uint32 param2; /**< Reserved */ + uint32 param3; /**< Reserved */ +} HAP_power_hmx_payload_v2; + +/** Payload for HAP_power_set_CENG_bus */ +typedef struct { + HAP_dcvs_voltage_corner_t target_corner; /**< Target voltage corner. For target_corner > 0, + * bwBytePerSec and busbwUsagePercentage params should be set to 0. */ + HAP_dcvs_voltage_corner_t min_corner; /**< Minimum voltage corner for DCVS */ + HAP_dcvs_voltage_corner_t max_corner; /**< Maximum voltage corner for DCVS */ + HAP_clk_perf_mode_t perf_mode; /**< To specify clock frequency level within target voltage corner */ + uint64 bwBytePerSec; /**< Clock request in terms of bandwidth (bytes per second). + * For bwBytePerSec > 0, target_corner should be set to 0. */ + uint32 busbwUsagePercentage; /**< Percentage of time during which bwBytesPerSec BW is required from the bus (0..100) */ + uint32 param1; /**< Reserved */ + uint32 param2; /**< Reserved */ + uint32 param3; /**< Reserved */ +} HAP_power_ceng_bus_payload; + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ + /** Identifies the HAP power request type */ +typedef enum { + HAP_power_set_mips_bw = 1, /**< Requests for MIPS. Provides + * fine-grained control to set MIPS values. + * Payload is set to HAP_power_payload */ + HAP_power_set_HVX, /**< Requests to enable / disable HVX + * Payload is set to HAP_power_hvx_payload */ + HAP_power_set_apptype, /**< Sets the app_type + * Payload is set to HAP_power_app_type_payload */ + HAP_power_set_linelock, /**< Sets the throttled L2 cache line locking parameters. + * Only one throttled call is supported at this time. Additional + * un-throttled line-locks can be performed using HAP_power_set_linelock_nothrottle + * Payload is set to HAP_power_linelock_payload */ + HAP_power_set_DCVS, /**< Requests to participate / stop participating in DCVS */ + HAP_power_set_linelock_nothrottle, /**< Sets the L2 cache line locking parameters (non-throttled). + * Payload is set to HAP_power_linelock_nothrottle_payload */ + HAP_power_set_DCVS_v2, /**< Requests to participate / stop participating in DCVS_v2 */ + HAP_power_set_vapss, /**< Sets the VAPSS core clock and DDR/IPNOC bandwidth + * Payload is set to HAP_power_vapss_payload */ + HAP_power_set_vapss_v2, /**< Sets the VAPSS core DMA/HCP clocks and DDR/IPNOC bandwidths + * Payload is set to HAP_power_vapss_payload_v2 */ + HAP_power_set_dcvs_v2_update, /**< Updates DCVS params + * Payload is set to HAP_power_dcvs_v2_update_payload */ + HAP_power_set_streamer, /**< Sets the streamer core clocks + * Payload is set to HAP_power_streamer_payload */ + HAP_power_set_DCVS_v3, /**< Updates DCVS params + * Payload is set to HAP_power_dcvs_v3_payload */ + HAP_power_set_HMX, /**< Requests to enable / disable HMX + * Payload is set to HAP_power_hmx_payload */ + HAP_power_set_HMX_v2, /**< Requests for HMX power management along with + * HMX clock requirement. On chipsets without separate HMX + * clock, will return AEE_EBADPARM error + * if target corner / frequency is requested. + * Payload is set to HAP_power_hmx_payload_v2 */ + HAP_power_set_CENG_bus, /**< To vote for CENG bus + * Payload is set to HAP_power_ceng_bus_payload */ +} HAP_Power_request_type; +/** + * @} // HAP_power_enums + */ + +/** Data type to change power values on the DSP */ +typedef struct { + HAP_Power_request_type type; /**< Identifies the request type */ + union{ + HAP_power_mips_bw_payload mips_bw; /**< Requests for performance level */ + HAP_power_vapss_payload vapss; /**< Sets the VAPSS core clock and DDR/IPNOC bandwidth */ + HAP_power_vapss_payload_v2 vapss_v2; /**< Sets the VAPSS core clock and DDR/IPNOC bandwidth */ + HAP_power_streamer_payload streamer; /**< Sets the streamer core clocks */ + HAP_power_hvx_payload hvx; /**< Requests to enable / disable HVX */ + HAP_power_app_type_payload apptype; /**< Sets the app_type */ + HAP_power_linelock_payload linelock; /**< Sets the throttled L2 cache linelock parameters. Only one + * throttled linelock is permitted at this time. Additional + * un-throttled linelocks can be performed using linelock_nothrottle */ + HAP_power_dcvs_payload dcvs; /**< Updates DCVS params */ + HAP_power_dcvs_v2_payload dcvs_v2; /**< Updates DCVS_v2 params */ + HAP_power_dcvs_v2_update_payload dcvs_v2_update; /**< Updates DCVS_v2_update params */ + HAP_power_linelock_nothrottle_payload linelock_nothrottle; /**< Sets the un-throttled L2 cache linelock parameters */ + HAP_power_dcvs_v3_payload dcvs_v3; /**< Updates DCVS_v3 params */ + HAP_power_hmx_payload hmx; /**< Requests to turn on / off HMX + * When request is to turn on HMX, on chipsets with separate HMX clock, + * a default HMX clock will be selected based on the voted + * Q6 core clock level from the same HAP_power_set context. + */ + HAP_power_hmx_payload_v2 hmx_v2; /**< Requests for HMX power management along with HMX clock requirement. + * On chipsets without separate HMX clock, will return AEE_EBADPARM error + * if target corner / frequency is requested. */ + HAP_power_ceng_bus_payload ceng_bus; /**< Votes for CENG bus */ + }; +} HAP_power_request_t; + +/** @defgroup HAP_power_functions HAP POWER functions + * @{ + */ +/** +* Method to set power values from the DSP +* @param[in] context - To identify the power client +* @param[in] request - Request params. +* @retval 0 on success, AEE_EMMPMREGISTER on MMPM client register request failure, -1 on unknown error +*/ +int HAP_power_set(void* context, HAP_power_request_t* request); +/** + * @} // HAP_power_functions + */ + +/** @defgroup HAP_power_enums HAP POWER enums + * @{ + */ + /** Identifies the HAP power response type */ +typedef enum { + HAP_power_get_max_mips = 1, /**< Returns the max mips supported (max_mips) */ + HAP_power_get_max_bus_bw, /**< Returns the max bus bandwidth supported (max_bus_bw) */ + HAP_power_get_client_class, /**< Returns the client class (client_class) */ + HAP_power_get_clk_Freq, /**< Returns the core clock frequency (clkFreqHz) */ + HAP_power_get_aggregateAVSMpps, /**< Returns the aggregate Mpps used by audio and voice (clkFreqHz) */ + HAP_power_get_dcvsEnabled, /**< Returns the dcvs status (enabled / disabled) */ + HAP_power_get_vapss_core_clk_Freq, /**< Returns the VAPSS core clock frequency (clkFreqHz) */ + HAP_power_get_dma_core_clk_Freq, /**< Returns the DMA core clock frequency (clkFreqHz) */ + HAP_power_get_hcp_core_clk_Freq, /**< Returns the HCP core clock frequency (clkFreqHz) */ + HAP_power_get_streamer0_core_clk_Freq, /**< Returns the streamer 0 core clock frequency (clkFreqHz) */ + HAP_power_get_streamer1_core_clk_Freq, /**< Returns the streamer 1 core clock frequency (clkFreqHz) */ +} HAP_Power_response_type; +/** + * @} // HAP_power_enums + */ + +/** Data type to retrieve power values from the DSP */ +typedef struct { + HAP_Power_response_type type; /**< Identifies the type to retrieve. */ + union{ + unsigned int max_mips; /**< Max mips supported */ + uint64 max_bus_bw; /**< Max bus bw supported */ + unsigned int client_class; /**< Current client class */ + unsigned int clkFreqHz; /**< Current core CPU frequency */ + unsigned int aggregateAVSMpps; /**< Aggregate AVS Mpps used by audio and voice */ + boolean dcvsEnabled; /**< Indicates if dcvs is enabled / disabled. */ + }; +} HAP_power_response_t; + +/** @defgroup HAP_power_functions HAP POWER functions + * @{ + */ + +/** +* Method to retrieve power values from the DSP +* @param[in] context - Ignored +* @param[out] response - Response. +*/ +int HAP_power_get(void* context, HAP_power_response_t* response); + +/** +* Method to initialize dcvs v3 structure in request param. It enables +* flags and resets params for all fields in dcvs v3. So, this +* can also be used to remove applied dcvs v3 params and restore +* defaults. +* @param[in] request - Pointer to request params. +*/ +static inline void HAP_power_set_dcvs_v3_init(HAP_power_request_t* request) { + memset(request, 0, sizeof(HAP_power_request_t) ); + request->type = HAP_power_set_DCVS_v3; + request->dcvs_v3.set_dcvs_enable = TRUE; + request->dcvs_v3.dcvs_enable = TRUE; + request->dcvs_v3.dcvs_option = HAP_DCVS_V2_POWER_SAVER_MODE; + request->dcvs_v3.set_latency = TRUE; + request->dcvs_v3.latency = 65535; + request->dcvs_v3.set_core_params = TRUE; + request->dcvs_v3.set_bus_params = TRUE; + request->dcvs_v3.set_dcvs_v3_params = TRUE; + request->dcvs_v3.set_sleep_disable = TRUE; + return; +} + +/** +* Method to enable/disable dcvs and set particular dcvs policy. +* @param[in] context - User context. +* @param[in] dcvs_enable - TRUE to enable dcvs, FALSE to disable dcvs. +* @param[in] dcvs_option - To set particular dcvs policy. In case of dcvs disable +* request, this param will be ignored. +* @returns - 0 on success +*/ +static inline int HAP_power_set_dcvs_option(void* context, boolean dcvs_enable, + HAP_power_dcvs_v2_payload_option dcvs_option) { + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t) ); + request.type = HAP_power_set_DCVS_v3; + request.dcvs_v3.set_dcvs_enable = TRUE; + request.dcvs_v3.dcvs_enable = dcvs_enable; + if(dcvs_enable) + request.dcvs_v3.dcvs_option = dcvs_option; + return HAP_power_set(context, &request); +} + +/** +* Method to set/reset sleep latency. +* @param[in] context - User context. +* @param[in] latency - Sleep latency value in microseconds, should be > 1. +* Use 65535 max value to reset it to default. +* @returns - 0 on success +*/ +static inline int HAP_power_set_sleep_latency(void* context, uint32 latency) { + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t) ); + request.type = HAP_power_set_DCVS_v3; + request.dcvs_v3.set_latency = TRUE; + request.dcvs_v3.latency = latency; + return HAP_power_set(context, &request); +} + +/** +* Method to set/reset DSP core clock voltage corners. +* @param[in] context - User context. +* @param[in] target_corner - Target voltage corner. +* @param[in] min_corner - Minimum voltage corner. +* @param[in] max_corner - Maximum voltage corner. +* @returns - 0 on success +*/ +static inline int HAP_power_set_core_corner(void* context, uint32 target_corner, + uint32 min_corner, uint32 max_corner) { + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t) ); + request.type = HAP_power_set_DCVS_v3; + request.dcvs_v3.set_core_params = TRUE; + request.dcvs_v3.core_params.min_corner = (HAP_dcvs_voltage_corner_t) (min_corner); + request.dcvs_v3.core_params.max_corner = (HAP_dcvs_voltage_corner_t) (max_corner); + request.dcvs_v3.core_params.target_corner = (HAP_dcvs_voltage_corner_t) (target_corner); + return HAP_power_set(context, &request); +} + +/** +* Method to set/reset bus clock voltage corners. +* @param[in] context - User context. +* @param[in] target_corner - Target voltage corner. +* @param[in] min_corner - Minimum voltage corner. +* @param[in] max_corner - Maximum voltage corner. +* @returns - 0 on success +*/ +static inline int HAP_power_set_bus_corner(void* context, uint32 target_corner, + uint32 min_corner, uint32 max_corner) { + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t) ); + request.type = HAP_power_set_DCVS_v3; + request.dcvs_v3.set_bus_params = TRUE; + request.dcvs_v3.bus_params.min_corner = (HAP_dcvs_voltage_corner_t) (min_corner); + request.dcvs_v3.bus_params.max_corner = (HAP_dcvs_voltage_corner_t) (max_corner); + request.dcvs_v3.bus_params.target_corner = (HAP_dcvs_voltage_corner_t) (target_corner); + return HAP_power_set(context, &request); +} + +/** +* Method to select low power mode. +* @param[in] context - User context. +* @param[in] sleep_disable - See HAP_DCVS_LPM_LEVEL1, HAP_DCVS_LPM_LEVEL2, HAP_DCVS_LPM_LEVEL3 and HAP_DCVS_LPM_ENABLE ALL above. +* @returns - 0 on success +*/ +static inline int HAP_power_set_sleep_mode(void* context, unsigned char sleep_disable) { + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t) ); + request.type = HAP_power_set_DCVS_v3; + request.dcvs_v3.set_sleep_disable = TRUE; + request.dcvs_v3.sleep_disable = sleep_disable; + return HAP_power_set(context, &request); +} + + +/** +* This API is deprecated and might generate undesired results. +* Please use the HAP_power_get() and HAP_power_set() APIs instead. +* Requests a performance level by percentage for clock speed +* and bus speed. Passing 0 for any parameter results in no +* request being issued for that particular attribute. +* @param[in] clock - percentage of target's maximum clock speed +* @param[in] bus - percentage of target's maximum bus speed +* @param[in] latency - maximum hardware wake up latency in microseconds. The +* higher the value the deeper state of sleep +* that can be entered but the longer it may +* take to awaken. +* @retval 0 on success +* @par Comments : Performance metrics vary from target to target so the +* intent of this API is to allow callers to set a relative +* performance level to achieve the desired balance between +* performance and power saving. +*/ +int HAP_power_request(int clock, int bus, int latency); + +/** +* This API is deprecated and might generate undesired results. +* Please use the HAP_power_get() and HAP_power_set() APIs instead. +* Requests a performance level by absolute values. Passing 0 +* for any parameter results in no request being issued for that +* particular attribute. +* @param[in] clock - speed in MHz +* @param[in] bus - bus speed in MHz +* @param[in] latency - maximum hardware wakeup latency in microseconds. The +* higher the value the deeper state of +* sleep that can be entered but the +* longer it may take to awaken. +* @retval 0 on success +* @par Comments : This API allows callers who are aware of their target +* specific capabilities to set them explicitly. +*/ +int HAP_power_request_abs(int clock, int bus, int latency); + +/** +* This API is deprecated and might generate undesired results. +* Please use the HAP_power_get() and HAP_power_set() APIs instead. +* queries the target for its clock and bus speed capabilities +* @param[out] clock_max - maximum clock speed supported in MHz +* @param[out] bus_max - maximum bus speed supported in MHz +* @retval 0 on success +*/ +int HAP_power_get_max_speed(int* clock_max, int* bus_max); + +/** +* This API is deprecated and might generate undesired results. +* Please use the HAP_power_get() and HAP_power_set() APIs instead. +* Upvote for HVX power +* @retval 0 on success +*/ +int HVX_power_request(void); + +/** +* This API is deprecated and might generate undesired results. +* Please use the HAP_power_get() and HAP_power_set() APIs instead. +* Downvote for HVX power +* @retval 0 on success +*/ +int HVX_power_release(void); + +/** +* Method to destroy clients created through HAP_power_set +* @param[in] context - To uniquely identify the client +* @retval 0 on success, AEE_ENOSUCHCLIENT on Invalid context, -1 on unknown error +* @brief DO NOT call this API directly, use HAP_power_destroy instead. +*/ +int HAP_power_destroy_client(void *context); + +/** +* @param[in] client - To uniquely identify the client context. +* @retval 0 on success, AEE_EUNSUPPORTEDAPI if the API is not supported on the DSP image, AEE_ENOSUCHCLIENT on Invalid context, -1 on unknown error +* @brief Method to destroy clients created through HAP_power_set, wrapper to HAP_power_destroy_client API +*/ +static inline int HAP_power_destroy(void *client){ + if(0 != HAP_power_destroy_client) + return HAP_power_destroy_client(client); + return AEE_EUNSUPPORTEDAPI; +} + +/** +* Method to create user client context +* @retval context for client +*/ +static inline void* HAP_utils_create_context(void) { + /* + * Allocate 1 byte of memory for a unique context identifier + * Clients can also allocate memory and use it as unique context identifier + */ + return malloc(1); +} + +/** +* Method to destroy user client context +* @param context of client +*/ +static inline void HAP_utils_destroy_context(void* context) { + free(context); +} + +/** + * @} // HAP_power_functions + */ +#ifdef __cplusplus +} +#endif +#endif //_HAP_POWER_H + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.md new file mode 100755 index 0000000000000..44ad184ac0eca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_power.md @@ -0,0 +1,946 @@ +# Introduction {#intro} + +The Hexagon SDK provides APIs to control DSP core and bus clocks based on power and performance needs. +By default, every compute session votes for NOMINAL voltage corner and powers on HVX. +Clients can choose to overwrite this by HAP power APIs below. + +# HAP_power API {#api} + + +## API Overview {#api-overview} + +HAP_power_* APIS are used by clients to override the power settings of the DSPs according to their needs. This API is supported on ADSP, CDSP and SLPI. + +The HAP power API contains a set of interfaces that allow programmers to adjust the DSP power usage as per the application's power requirement, thereby providing a good balance between power consumption and performance. + +* HAP_power_set(): This is used to vote for performance levels on the DSP +* HAP_power_get(): This is used to query the DSP for current performance levels +* HAP_power_destroy(): This is used to destroy power clients created through HAP_power_set API + +::HAP_power_set can be used to control these parameters on the DSP: +* DSP MIPS +* Bus speed / bandwidth +* Dynamic scaling of bus and DSP clocks and bus speeds (DCVS) +* Application type (client class), more details on this can be found [here](#app-type) +* L2 cache line locking +* Hexagon Vector eXtension (HVX) blocks + +::HAP_power_get can be used to query the DSP for these parameters: +* Max MIPS supported +* Max bus speed / bandwidth supported +* Current Core clock speed +* Current application type (client class) +* Aggregate Mpps used by audio and voice + +::HAP_power_destroy can be used to destroy the power clients created through HAP_power_set API. + Destroys any existing HAP_power votes associated with the provided client context, and disassociates that context from HAP_power. + + +## Usage {#usage} + +See HAP_power.h for more information on this API. + +::HAP_power_set : This accepts two parameters +* context - Unique identifier (explained below) +* request - The power request. + +context is a unique identifier (in the scope of the PD) provided by the user to identify an independent voting client of HAP_power. For each unique context passed in a HAP_power_set invocation, HAP_power adds a new client to its state to be associated with that context. + +On targets after Lahaina, helper APIs HAP_utils_create_context and HAP_utils_destroy_context are added to create and destroy unique context identifiers. If these are not available, the recommended alternative is to create a context by allocating a dummy byte and using the pointer value as the context, and freeing that byte later after destroying the context's associated HAP_power client via HAP_power_destroy. +* HAP_utils_create_context(): This is used to create a unique context identifier +* HAP_utils_destroy_context(): This is used to destroy unique context identifier. HAP_utils_destroy_context should only be called on a context after destroying the HAP_power client associated to that context, via HAP_power_destroy(context). Failure to destroy both in the proper order may cause a leak. + +Refer to the following table for voting/unvoting call flow: + +
Voting/Unvoting call flowLibrary code +
Create unique client contextcontext = userLibCodeToCreateUniqueContext() (or) context = HAP_utils_create_context() +
Create power client and voteHAP_power_set(context, request) +
Destroy power clientHAP_power_destroy(context) (or) HAP_power_destroy_client(context) +
Destroy unique client contextuserLibCodeToDestroyUniqueContext(context) (or) HAP_utils_destroy_context(context) +
+ +NOTE: Using a context set to NULL has specific implications, discussed below in [default voting](#default_voting) + +Example: Module1 and Module2 are two different clients running in the same user PD on DSP. Module1 creates a new, unique client context and votes for its needs. Module2 also creates a new, unique client context and votes for its needs. The figure below shows the different client contexts and their votes to power manager. + +![screenshot](../../images/hap_power.png) + +The type in the request is set to one of: +* HAP_power_set_mips_bw: Used to set MIPS and / or bus speed (bandwidth). The payload in this case should contain HAP_power_mips_bw_payload. +* HAP_power_set_HVX: Used to enable / disable power for HVX. The payload in this case should contain HAP_power_hvx_payload. +* HAP_power_set_apptype: Used to set the application type. The payload in this case should contain ::HAP_power_app_type_payload. +* HAP_power_set_linelock: Used to line lock memory in the L2 cache. The payload in this case should contain HAP_power_linelock_payload. +* HAP_power_set_DCVS: Used to participate / stop participating in DCVS. The payload in this case should contain HAP_power_dcvs_payload. +* HAP_power_set_DCVS_v2: Enhanced version of HAP_power_set_DCVS with more options. The payload in this case should contain HAP_power_dcvs_v2_payload. +* HAP_power_set_DCVS_v3: Enhanced version of HAP_power_set_DCVS_v2 with more options to select core and bus operating corners separately. The payload in this case should contain HAP_power_dcvs_v3_payload. + +NOTE: +* More details on HAP_power_set_DCVS_v2 can be found [here](#DCVS_V2). +* HAP_power_set_DCVS_v3 is supported from SM8250 onwards. More details can be found [here](#DCVS_V3). +* In Older targets, maximum of 8 clients can be created per PD, (including the default client). This limitation has been removed from SM8250 onwards. +* HAP_power_hmx_payload_v2 is supported starting with v75. On chipsets (v75 onwards) without separate HMX clock plan, requests made for target corner or +frequency will return AEE_EBADPARM (invalid parameter) error. +* HAP_power_set_CENG_bus is supported from v75 onwards. On chipsets (v75 onwards) not supporting independent Q6-CENG bus clock scaling, this request type +will return AEE_EBADPARM (invalid parameter) error. + +Example is provided below. + +~~~{.c} + //Vote + /* Populate request structure */ + int retVal; + HAP_power_request_t request; + memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. + request.type = HAP_power_set_DCVS_v2; + request.dcvs_v2.dcvs_enable = TRUE; + request.dcvs_v2.dcvs_option = HAP_DCVS_V2_PERFORMANCE_MODE; + request.dcvs_v2.set_latency = TRUE; + request.dcvs_v2.latency = 1000; + request.dcvs_v2.set_dcvs_params = TRUE; + request.dcvs_v2.dcvs_params.min_corner = HAP_DCVS_VCORNER_SVS; + request.dcvs_v2.dcvs_params.max_corner = HAP_DCVS_VCORNER_TURBO; + request.dcvs_v2.dcvs_params.target_corner = HAP_DCVS_VCORNER_NOM; + /* Call HAP_power_set API with the updated request structure */ + /* cv is a global variable or an address in heap to uniquely identify the clients */ + retVal = HAP_power_set(&cv, &request); + ... +~~~ +::HAP_power_get : This accepts two parameters + +* context - this parameter is ignored and response is for the system level +* response - The power response + +The type in the request is set to one of +* HAP_power_get_max_mips: Used to query for maximum MIPS supported +* HAP_power_get_max_bus_bw: Used to query for maximum bus bandwidth supported +* HAP_power_get_client_class: Used to query for current application type. +* HAP_power_get_clk_Freq: Used to query for current core clock frequency. +* HAP_power_get_aggregateAVSMpps: Used to query for aggregate Mpps used by audio and voice. + +::HAP_power_destroy : This accepts one parameter + +* context - the unique client context identifying the HAP_power client to destroy. + +Example to remove default vote for a PD and to destroy default client. +~~~{.c} + //Vote + int nErr= 0; + + if(0 == (nErr = HAP_power_destroy(NULL))){ + //Client destroyed successfully + } +~~~ + +### Default voting {#default_voting} +In older targets, NULL is a valid HAP_power context that is used by FastRPC to establish a default vote for some reasonable clock settings. In order to override the default vote on these targets, it is necessary for a client to place a canceling vote using the NULL context. + +Permitting clients to use NULL context can lead to conflicts where multiple clients in the same PD may try to independently manage the NULL context. +To address these conflicts, support for any NULL context voting has been removed starting in targets after Lahaina. For these targets, behavior of default voting has been changed. A suitable vote is placed automatically at opportune times (such as startup or object loading) on a unique context, and is automatically removed when no longer needed. For example, the FastRPC driver places a high clock vote when a new session is started on the DSP, and removes it as soon as any user in that session places any other HAP_power vote. This ensures clocks are high during startup and object loading, up until the point the user application is able to place its own vote. + +The recommended client behavior is as follows: + +* Lahaina and older targets: While it is allowed to rely on the default vote to establish reasonable clocks, it is recommended to place a canceling vote (with low/zero clock values as shown below) on the NULL context, plus an active vote for the requirements on a different unique context. + +* Targets after Lahaina: Simply place an active vote for required clock settings on a unique context. + +If a single client implementation is required to work correctly on all targets, the recommendation is as follows: +* Make an attempt to place a canceling NULL-context vote. If the error code AEE_ENULLCONTEXT is returned, it means the target does not support NULL context. Thus, this error can be ignored. +* Place a (non-NULL) unique context vote for the clock requirements. + +On targets that support NULL context default voting, it can be removed using HAP_power_destroy(NULL) or as follows: + +~~~{.c} +req.type = HAP_power_set_DCVS_v2; +req.dcvs_v2.dcvs_enable = FALSE; +req.dcvs_v2.set_latency = FALSE; +req.dcvs_v2.set_dcvs_params = FALSE; +VERIFY(AEE_SUCCESS == (nErr = HAP_power_set(NULL, &req))); +~~~ + + +### Application type/Client class {#app-type} +HAP_power_set() API exposes an API for users to register for an application type. + +'apptype' in ::HAP_power_request_t passed as parameter to HAP_power_set request allows user to register an application as one of the client classes available in ::HAP_power_app_type_payload. +Setting an appropriate client class can be important as this information is used in DSP DCVS, QoS, DSP power management drivers. HAP_power clients who do not explicitly vote their apptype are treated as general compute applications, which is appropriate for most cases. + +####Users of Client class information +DCVS selects HAP_DCVS_V2_POWER_SAVER_MODE as default DCVS policy for COMPUTE and STREAMING class clients. Client can always power their own DCVS policy by issuing a DCVS_v2 request, click [here](#DCVS_V2) for more details on DCVS_v2 request type of HAP_power_set. +QoS driver modifies L2 scoreboard thresholds on detecting STREAMING class clients to allow DSP L2 slave accesses. + + +###DSP DCVS v2 HAP interface {#DCVS_V2} +Based on user configuration, DCVS module in DSP (ADSP/CDSP) can adjust the core and bus clock frequencies based on core and bus usage metrics captured by SysMon. The existing DCVS interface via HAP_power_set() (type: HAP_power_set_DCVS) only allows users to vote for DCVS participation with 2 different options. DSP DCVS v2 algorithm exposes an enhanced set of DCVS options for diversified clients and a simplified voltage corner based voting scheme. On supported targets (8998 and latest), these new DCVS options and voting scheme are exposed to clients via HAP_power_set()(type: HAP_power_set_DCVS_v2). + +####HAP API Support +The HAP_power_set API is enhanced to support the new mode registrations with DSP DCVS logic. Following table illustrates the new type of request and the new dcvs_v2 request structure associated with it. + + +
API HAP_power_set (void* context, HAP_power_request_t* request) +
context Explained [here](#usage). Votes across all contexts will be aggregated accordingly. +
request type HAP_power_set_DCVS_v2 This new request type allows user to request via the new dcvs_v2 request structure. +
dcvs_v2 dcvs_enable DCVS participation flag +
dcvs_option These options instruct DCVS algorithm to use a pre-defined set of thresholds and operation logic based on the selected option. +
set_latency Latency vote validity flag. If FALSE then default sleep latency vote of 65535 micro seconds will be considered. +
latency Sleep latency vote in micro seconds. Valid when the set_latency flag is set to TRUE +
set_dcvs_params DCVS params validity flag. If FALSE then all parameters of dcvs_params will be set to default zero. +
dcvs_params DCVS params structure with flexibility to set upper and lower DCVS thresholds and also vote for core and bus clocks using a voltage corner. +
+ +###DSP DCVS v3 HAP interface {#DCVS_V3} +Based on user configuration, DCVS module in DSP can adjust the core and bus clock frequencies based on core and bus usage metrics captured by SysMon. The existing DCVS v2 algorithm via HAP_power_set() (type: HAP_power_set_DCVS_v2) exposes multiple DCVS options for diversified clients and a simplified voltage corner based voting scheme. But along with existing features, DCVS v3 provides separate voltage corner voting option to user for core and bus clock and also option to disable all low power modes without explicit sleep latency vote need. In scenarios where user is ok for same voltage corner voting for core and bus clock then they can still use DCVS v2. Also, in DCVS v3 user can vote for individual field/multiple fields based on his requirement. On supported targets (SM8250 and latest), these new DCVS options and voting scheme are exposed to clients via HAP_power_set() (type: HAP_power_set_DCVS_v3). Also, added wrapper functions built around same HAP_power_set() (type: HAP_power_set_DCVS_v3) to help user to select and vote for individual functionality in DCVS v3 without bothering about DCVS v3 structure and related details. This document captures information on these new DCVS v3 features and ways to use them. + +####HAP API Support +The HAP_power_set API is enhanced to support the new user options with DCVS v3 with the new request type HAP_power_set_DCVS_v3 with HAP_power_dcvs_v3_payload. + + +
API HAP_power_set (void* context, HAP_power_request_t* request) +
context Explained [here](#usage). Votes across all contexts will be aggregated accordingly. +
request type HAP_power_set_DCVS_v3 This new request type allows user to request via the new dcvs_v3 request structure +
dcvs_v3 set_dcvs_enable DCVS participation validity flag. If FALSE then the dcvs_enable and dcvs_option fields will be ignored. +
dcvs_enable DCVS participation flag. Vaild when the set_dcvs_enable is set to TRUE. +
dcvs_option These options instruct DCVS algorithm to use a pre-defined set of thresholds and operation logic based on the selected option. +
set_latency Latency vote validity flag. If FALSE then the latency field will be ignored. +
latency sleep latency vote in micro seconds. Valid when the set_latency flag is set to TRUE +
set_core_params Core clock params validity flag. If FALSE then the core_params field be ignored. +
core_params Core clock params structure with flexibility to set upper and lower core clock DCVS thresholds and also vote for core clock using a voltage corner. Valid when set_core_params is set to TRUE. +
set_bus_params Bus clock params validity flag. If FALSE then the bus_params field will be ignored. +
bus_params Bus clock params structure with flexibility to set upper and lower bus clock DCVS thresholds and also vote for bus clock using a voltage corner. Valid when set_bus_params is set to TRUE. +
set_dcvs_v3_params Validity flag for reserved DCVS params. If FALSE then the dcvs_v3_params field will be ignored. +
dcvs_v3_params Reserved DCVS params +
set_sleep_disable Sleep param validity flag. If FALSE then the sleep_disable field will be ignored. +
sleep_disable To select low-power mode (LPM). Valid when set_sleep_disable is set to TRUE. Refer to [Sleep Disable](#sleep_disable) for options. +
+ +####Wrapper APIs +There are wrapper functions built around same HAP_power_set()(type: HAP_power_set_DCVS_v3) to help user to select and vote for individual functionality in DCVS v3 without bothering about DCVS v3 structure and related details. Below section provides these APIs details. + +* HAP_power_set_dcvs_v3_init() +* HAP_power_set_dcvs_option() +* HAP_power_set_sleep_latency() +* HAP_power_set_core_corner() +* HAP_power_set_bus_corner() +* HAP_power_set_sleep_mode() + +####DCVS Enable +'dcvs_enable' parameter of dcvs_v2 structure enables user to vote for DCVS participation. + +
Value Description +
TRUE Enable DSP DCVS (if not already enabled). Using dcvs_option, based on the application demand, user can choose a particular option to guide DSP DCVS logic +
FALSE Don't enable DSP DCVS. Valid only when the client requesting is the only one actively voting for clocks or is one among the clients voting for this same option. +
+ +'set_dcvs_enable' and 'dcvs_enable parameters' of dcvs_v3 structure enables user to vote for DCVS participation. + +
set_dcvs_enable FALSE No DCVS request from the client, dcvs_enable and dcvs_option fields will be ignored. +
TRUE Client request for DCVS is valid and desired DCVS participation is provided in dcvs_enable field. +
dcvs_enable TRUE Enable DSP DCVS (if not already enabled). Using dcvs_option, based on the application demand, user can choose a particular option to guide DSP DCVS logic. +
FALSE Don't enable DSP DCVS. Valid only when the client requesting is the only one actively voting for clocks or is one among the clients voting for this same option. +
+ +When a DCVS participating client is active, DCVS logic would be enabled, but the aggregated clients vote requesting for DCVS disable will be considered as a FLOOR request in DCVS logic i.e, DCVS would't lower the clocks below the aggregated value. + +DCVS participation and options are considered only for active clients. A client is deemed inactive when there is no MIPS and bandwidth request (made by setting request type to 'HAP_power_set_mips_bw' in 'HAP_power_set' [API](#usage)) and when target_corner for core and bus under dcvs_params is set to HAP_DCVS_VCORNER_DISABLE. + +####DCVS Options +'dcvs_option' parameter of dcvs_v2 structure enables user to request for a particular DCVS mode when 'dcvs_enable' option is set to TRUE. + +'dcvs_option' parameter of dcvs_v3 structure enables user to request for a particular DCVS mode when 'set_dcvs_enable' and 'dcvs_enable' both are set to TRUE. + +Following table captures the gist of the available DCVS modes. + + +
Value Description +
HAP_DCVS_V2_ADJUST_UP_DOWN + Legacy option: For clients voting via HAP_power_set_mips_bw request type. +This mode allows DCVS to both increase and decrease core/bus clock speeds based on need. DCVS selects thresholds corresponding to a balanced mode (legacy) of operation with respect to power and performance. + +min_corner and max_corner votes via dcvs_params are used as lower and + +upper limit guidelines in DCVS. + +NOTE: If client votes via target_corner under dcvs_params of this structure, both HAP_DCVS_V2_ADJUST_ONLY_UP and HAP_DCVS_V2_ADJUST_UP_DOWN modes are identical. min_corner and max_corner votes are used as lower and upper limit guidelines in DCVS while using balanced mode (legacy) thresholds. + +
HAP_DCVS_V2_ADJUST_ONLY_UP + Legacy option: For clients voting via HAP_power_set_mips_bw request type. + +This mode restricts DCVS from lowering the clock below the values requested via HAP_power_set_mips_bw request. DCVS can only increase the clock above the requested levels. DCVS selects thresholds corresponding to a balanced mode(legacy) of operation with respect to power and performance. max_corner vote via dcvs_params is used as upper limit guideline in DCVS. + +NOTE: If client votes via target_corner under dcvs_params of this structure, both HAP_DCVS_V2_ADJUST_ONLY_UP and HAP_DCVS_V2_ADJUST_UP_DOWN modes are identical. min_corner and max_corner votes are used as lower and upper limit guidelines in DCVS while using balanced mode (legacy) thresholds. + +
HAP_DCVS_V2_POWER_SAVER_MODE + New option: + +Default for all clients participating in DCVS. DCVS can both increase and decrease the core/bus clock speeds while min_corner and max_corner votes are used as lower and upper limit guidelines. DCVS selects thresholds corresponding to power saving model. This mode is meant for applications where saving power is of higher priority than achieving fastest performance. Performance may be slower in this mode than in HAP_DCVS_V2_PERFORMANCE_MODE or the legacy modes i.e, HAP_DCVS_V2_ADJUST_ONLY_UP HAP_DCVS_V2_ADJUST_UP_DOWN + +
HAP_DCVS_V2_POWER_SAVER_AGGRESSIVE_MODE + New option: + +DCVS can both increase and decrease the core/bus clock speeds while min_corner and max_corner votes are used as lower and upper limit guidelines. DCVS selects thresholds corresponding to a power saving model. Further, the DCVS monitoring durations in lowering the clocks is decreased for a faster ramp down and hence greater power saving compared to the power saver mode. This mode is meant for applications where saving power is of higher priority than achieving fastest performance. Performance may be slower in this mode than in HAP_DCVS_V2_PERFORMANCE_MODE HAP_DCVS_V2_POWER_SAVER_MODE or the legacy modes i.e, HAP_DCVS_V2_ADJUST_ONLY_UP HAP_DCVS_V2_ADJUST_UP_DOWN + +
HAP_DCVS_V2_PERFORMANCE_MODE +New option: + +DCVS can both increase and decrease the core/bus clock speeds while min_corner and max_corner votes are used as lower and upper limit guidelines. DCVS selects a set of aggressive thresholds in terms of performance. DCVS can quickly bump up the clocks in this mode assisting higher performance at the cost of power. + +
HAP_DCVS_V2_DUTY_CYCLE_MODE + This mode is for periodic use cases. Starting with Lahaina, DCVS when in this mode detects the periodicity and sets/removes the core and bus clock votes for active/idle durations respectively. This mode helps save power significantly by reducing idle leakage current while keeping the performance intact. Compared to Applications setting/removing clock votes for each active frame to save the power, the DCVS duty cycle mode provides better performance and more power savings, as in this mode, the voting is done upfront by DCVS just before active duration start based on periodicity prediction. +
+In cases where multiple clients have registered different DCVS options, following table depicts the DCVS policy aggregation logic. + +
PERFORMANCE (Yes / No) POWER SAVER (Yes / No) POWER SAVER AGGRESSIVE (Yes / No) BALANCED (UP ONLY/UP AND DOWN clients) (Yes / No) Final DCVS thresholds +
Y Y /N Y /N Y /N PERFORMANCE +
N Y Y /N Y /N POWER SAVER +
N N Y Y POWER SAVER +
+ +####DCVS Duty Cycle +DCVS duty cycle mode is for periodic use cases. The DCVS algorithm detects periodicity and sets the core and bus clock votes as per active and idle duration. This helps in saving the power to great extent by reducing idle leakage current while keeping the performance intact. + +Below example illustrates DCVS duty cycle working for an application with 30FPS activity and TURBO_PLUS votes for core and bus clocks. + +For this application run, core, bus clocks and related DSP metrics with and without DCVS duty cycle mode are shown below. In no duty cycle case, core and bus clocks are at TURBO_PLUS throughout the application run. +In DCVS duty cycle case, the DCVS algorithm detects periodicity in use case and sets core and bus clocks to TURBO_PLUS in activity time and to LOW SVS (SVS2) during idle time of each frame. + +![screenshot](../../images/DCVS_CoreClock_DutyCycle.png) + +![screenshot](../../images/DCVS_BusClock_DutyCycle.png) + +With increasing processing capabilities, active time for applications will improve resulting in greater power savings for periodic activities with DCVS duty cycle mode due to increased idle time. + +The DCVS duty cycle mode is supported starting with Lahaina. On chipsets prior Lahaina, DCVS fallsback to power saver mode on selecting duty cycling. + +####DCVS Duty Cycle Modes +Starting with Waipio, DCVS duty cycle mode is further expanded to cover following scenarios/sub-modes. + +####Fixed Corners Mode +Fixed active and idle clock corners: +* Client decides fixed active clock and idle clock +* DCVS only uses those selected corners + +Example: +* Max corner : HAP_DCVS_VCORNER_DISABLE +* Target corner : TURBO +* Min corner : LOW SVS (SVS2) +* Mode : Duty_cycle +* DCVS Enable flag: 0 +* Expectation : Duty cycle between TUBRO and LOW SVS (SVS2) only + +![screenshot](../../images/HAP_set_dcvs_v3_duty_cycle_fixed_corners_mode.png) + +####Active Range Mode +Client and the DCVS algorithm decides active clock corners: +* Client decides active clock range and idle clock +* The DCVS algorithm decides active corner within provided range based on power vs performance tradeoff and user given max active time (if provided) + +Example: +* Max corner : TURBO +* Target corner : SVS PLUS +* Min corner : LOW SVS (SVS2) +* Mode : Duty_cycle +* DCVS Enable flag: 1 +* Expectation : Active clock is decided by the DCVS algorithm within the provided range (Target corner, max corner) +* The DCVS algorithm starts with client provided max corner for active clock, tunes it based on performance vs power tradeoff and user given max active time. + +![screenshot](../../images/HAP_set_dcvs_v3_duty_cycle_active_range_mode.png) + +####Full DCVS Control Mode +DCVS decides active and idle clock corners: +* Client does not provide active and idle clock corner +* The DCVS algorithm can decide any clock corner for active and idle durations based on power vs performance tradeoff and user given max active time (if provided) +* Max corner : HAP_DCVS_VCORNER_DISABLE +* Target corner : HAP_DCVS_VCORNER_DISABLE +* Min corner : HAP_DCVS_VCORNER_DISABLE +* Mode : Duty_cycle +* DCVS Enable flag: 1 +* Expectation : Active and idle clocks are decided by the DCVS algorithm +* DCVS starts with NOM as active corner and LOW SVS (SVS2) as idle corner and later tunes it based on performance vs power tradeoff and user given max active time (if provided). +* DCVS picks LOW SVS (SVS2) clock corner when there is no activity. + +![screenshot](../../images/HAP_set_dcvs_v3_duty_cycle_full_dcvs_control_mode.png) + +####DCVS Duty Cycle Helper APIs +Starting Waipio, the DCVS duty cycle helper APIs are added for ease of configuration. See [HAP_dcvs.h](../../doxygen/HAP_dcvs/index.html) for more information. + +####Sleep latency {#sleep-latency} +'set_latency' and 'latency' parameters of structure dcvs_v2 can be used to request for a sleep latency in micro seconds. + + +
set_latency FALSE No sleep latency request from the client. If FALSE then default sleep latency vote of 65535 micro seconds will be considered. +
TRUE Client request for a sleep latency is valid and desired latency is provided in latency field. +
latency Sleep latency request in micro-seconds. +
+ +Similarly 'set_latency' and 'latency' parameters of structure dcvs_v3 can be used to request for a sleep latency in micro seconds. + + +
set_latency FALSE No sleep latency request from the client. If FALSE then the latency field will be ignored. +
TRUE Client request for a sleep latency is valid and desired latency is provided in latency field. +
latency Sleep latency request in micro-seconds. +
+ +NOTE: HAP_power_set provides below possible ways for voting for sleep latency: + +1. via HAP_power_set_mips_bw request type: +~~~{.c} +/* For sleep latency */ +mips_bw.set_latency = TRUE; +mips_bw.latency = +~~~ +2. via HAP_power_set_DCVS_v2 request type: +~~~{.c} +/* For sleep latency */ +dcvs_v2.set_latency = TRUE; +dcvs_v2.latency = +~~~ + Or via HAP_power_set_DCVS_v3 request type: +~~~{.c} +/* For sleep latency */ +dcvs_v3.set_latency = TRUE; +dcvs_v3.latency = +~~~ + +Clients should use only 1 of the above methods to vote for latency i.e, either via mips_bw or via dcvs_v2/dcvs_v3 but not both. Voting via dcvs_v2/dcvs_v3 does NOT cancel any previous vote done via mips_bw and vice versa. + +latency value can be set to a minimum of 10 micro-second. The Application should vote for a latency that is tolerable. For latency critical applications, the latency can be set to its minimum value of 10 micro-second. + + +####DCVS params +set_dcvs_params and dcvs_params parameters of dcvs_v2 can be used to update DCVS thresholds and target corner vote. +set_core_params and core_params parameters of dcvs_v3 can be used to update DCVS thresholds and target corner vote for core clock. Similarly set_bus_params and bus_params parameters for bus clock. +This structure is valid irrespective of chosen dcvs_enable and dcvs_option values. Client can request for a target_corner even when the dcvs_enable option is set to FALSE. + +When set_dcvs_params/set_core_params/set_bus_params is TRUE, target_corner, min_corner and max_corner parameters of dcvs_params/core_params/bus_params can take one of the value in ::HAP_dcvs_voltage_corner_t; + + +
HAP_dcvs_voltage_corner_t Description +
HAP_DCVS_VCORNER_DISABLE No specific corner request (No Vote) +
HAP_DCVS_VCORNER_SVS2 SVS2 / LOW SVS corner +Note: On targets that don't support this voltage corner, this option will be interpreted as HAP_DCVS_VCORNER_SVS +
HAP_DCVS_VCORNER_SVS SVS corner +
HAP_DCVS_VCORNER_SVS_PLUS SVS Plus corner +Note: On targets that don't support this voltage corner, this option will be interpreted as HAP_DCVS_VCORNER_SVS +
HAP_DCVS_VCORNER_NOM NOMINAL corner +
HAP_DCVS_VCORNER_NOM_PLUS NOMINAL Plus corner +Note: On targets that don't support this voltage corner, this option will be interpreted as HAP_DCVS_VCORNER_NOM +
HAP_DCVS_VCORNER_TURBO TURBO corner +
HAP_DCVS_VCORNER_TURBO_PLUS TURBO Plus corner +Note: On targets released till Kailua, this option selects the clock frequencies defined under corners TURBO_PLUS and above (TURBO_L2 / L3) and falls back to TURBO when there is no clock frequency available at these corners. On targets post Kailua, this option selects clock frequencies defined under TURBO_PLUS (or TURBO when no defined frequency under TURBO_PLUS). Frequencies defined under TURBO_L2 / L3 corners can be selected via the new HAP_DCVS_VCORNER_TURBO_L2 / L3 options. +
HAP_DCVS_VCORNER_TURBO_L2 TURBO L2 corner +Note: On targets released till Kailua, this option is interpreted as HAP_DCVS_VCORNER_TURBO_PLUS. On targets post Kailua, this option selects the closest TURBO clock frequency (corresponding to HAP_DCVS_VCORNER_TURBO_PLUS / TURBO) when there is no clock frequency defined under the TURBO_L2 voltage corner. +
HAP_DCVS_VCORNER_TURBO_L3 TURBO L3 corner +Note: On targets released till Kailua, this option is interpreted as HAP_DCVS_VCORNER_TURBO_PLUS. On targets post Kailua, this option selects the closest TURBO clock frequency (corresponding to HAP_DCVS_VCORNER_TURBO_L2 / TURBO_PLUS / TURBO) when there is no clock frequency defined under the TURBO_L3 voltage corner. +
HAP_DCVS_VCORNER_MAX MAX possible corner defined for maximum performance. +
+
+ +
dcvs_params/core_params/bus_params target_corner Type: HAP_dcvs_voltage_corner_t. +Alternative to HAP_power_set_mips_bw MIPS and Bandwidth request. HAP_power_set provides 2 possible ways for voting for sleep latency and core/bus clocks. +1. via HAP_power_set_mips_bw request type: +~~~{.c} +/* For core clock */ +mips_bw.set_mips = TRUE; +mips_bw.mipsPerThread = +mips_bw.mipsTotal = +/* For bus clock */ +mips_bw.set_bus_bw = TRUE; +mips_bw.bwBytePerSec = +mips_bw.busbwUsagePercentage = +/* For sleep latency */ +mips_bw.set_latency = TRUE; +mips_bw.latency = +~~~ +2. via HAP_power_set_DCVS_v2 request type: +~~~{.c} +/* For core and bus clock */ +dcvs_v2.set_dcvs_params = TRUE; +dcvs_v2.dcvs_params.target_corner = +/* For sleep latency */ +dcvs_v2.set_latency = TRUE; +dcvs_v2.latency = +~~~ +or + +3. via HAP_power_set_DCVS_v3 request type: +~~~{.c} +/* For core clock */ +dcvs_v3.set_core_params = TRUE; +dcvs_v3.core_params.target_corner = +/* For bus clock */ +dcvs_v3.set_bus_params = TRUE; +dcvs_v3.bus_params.target_corner = +/* For sleep latency */ +dcvs_v3.set_latency = TRUE; +dcvs_v3.latency = +~~~ +Client can request core and bus clock to run at at a particular voltage corner instead of providing MIPS and Bandwidth (bytes per second) requests. DCVS will convert the requested voltage corner value to appropriate core clock and bus clock votes and forwards the request to the power manager on client's behalf. Clients should use only 1 of the above methods to vote i.e, either via mips_bw or via dcvs_v2/dcvs_v3 but not both. Voting via dcvs_v2/dcvs_v3 does NOT cancel any previous vote done via mips_bw and vice versa. If one would like to switch between these 2 methods, cancel any previous vote done via the other method before requesting. + +When target_corner = HAP_DCVS_VCORNER_DISABLE (No vote), DSP DCVS doesn't request for any core or bus clocks at the time of API call and it's client's responsibility to vote for core and bus clocks using HAP_power_set_mips_bw type request type. + +If enabled > HAP_DCVS_VCORNER_DISABLE, DSP DCVS logic will pick the highest available frequency plan for both core and bus clocks at the given voltage corner and requests for these clock frequencies synchronously in the API context on client's behalf. When the HAP_power_set API returns with success, core and bus clock frequencies would be set by DSP DCVS on a valid target_corner request. + +
min_corner Type: HAP_dcvs_voltage_corner_t. + +If disabled, min_corner == HAP_DCVS_VCORNER_DISABLE, the lower threshold/minimum value that DCVS can correct the clock will remain unchanged. If enabled > HAP_DCVS_VCORNER_DISABLE, DSP DCVS picks the lowest core clock frequency at the given voltage corner and uses it as the lower threshold/minimum value that DCVS can correct the clock to, irrespective of the dcvs_option selected. + +min_corner should always be less than or equal to target_corner and max_corner unless they are disabled HAP_DCVS_VCORNER_DISABLE. + +For clients requesting dcvs_enable as FALSE and using target_corner, min_corner should be equal to target_corner. + +
max_corner Type: HAP_dcvs_voltage_corner_t. + +If disabled, max_corner == HAP_DCVS_VCORNER_DISABLE, the upper threshold/maximum value that DCVS can correct the clock will remain unchanged. Typically, that would be HAP_DCVS_VCORNER_MAX in this case. If enabled > HAP_DCVS_VCORNER_DISABLE, DSP DCVS picks the highest core and bus clock frequencies at the given voltage corner and uses it as the upper threshold/maximum value that DCVS can correct the clocks to, irrespective of the dcvs_option selected. + +DSP DCVS logic overrides the max_corner vote from a client to MAX in presence of a concurrency. Concurrency is defined as a scenario where 2 or more FastRPC dynamic loaded clients are active or active Audio/Voice sessions with MPPS load greater than a pre-defined threshold. + +max_corner should always be greater than or equal to target_corner and min_corner votes, or, should be disabled HAP_DCVS_VCORNER_DISABLE. + +
param1 Type: HAP_dcvs_voltage_corner_t. + +NOTE: Set this option to HAP_DCVS_VCORNER_DISABLE unless required. + +This parameter allows user to set CPU L3 clock frequency to the requested corner. Valid only on CDSP subsystem in targets with CPU L3 cache and IO-coherency enabled (SDM845, SDM710, SM8150...), ignored elsewhere. On CDSP, based on the requested target_corner, CPU L3 clock vote from CDSP is set to a balanced level (with minimal power impact) to start with and DCVS (if enabled) increases the vote based on need to attain higher performance. This option is useful to peg CPU L3 clock at a higher level (at the cost of higher power) than that of the default balanced vote and that of the DCVS algorithm votes. This option is for advanced users and should be configured to default (HAP_DCVS_VCORNER_DISABLE) unless there is a need to explicitly set CPU L3 clock frequency based on performance and power analysis/characterization + +
param2 Reserved. +
param3 Reserved. +
+ +####Clock frequency level selection at given target corner +By default DCVS picks the highest available frequency for a given core/bus clock target corner. On latest chipsets(released after Palima), APIs are added to allow the user to specify frequency level (highest/lowest) for given core/bus clock target corner. See [HAP_dcvs.h](../../doxygen/HAP_dcvs/index.html) for more information. + +####DCVS vote aggregation logic in case of concurrency +Following logic explains the aggregation logic for min and target corner votes when there are multiple requesting clients: +~~~{.c} +DCVS min_corner vote = MAX (min_corner vote client 1, client 2, ...) +DCVS target_corner vote = MAX (target_corner vote client 1, client 2, ...) +~~~ +The following scenarios are treated as a concurrency in DCVS vote aggregation logic where DCVS max corner vote is set to TURBO by DCVS: +* More than 1 active HAP client with or without active Audio/Voice clients. +* One active HAP client and active Audio/Voice clients with MPPS load greater than a pre-defined threshold. +~~~{.c} + DCVS max_corner vote = HAP_DCVS_VCORNER_MAX +~~~ + +Note that DCVS overrides client's MAX corner vote to MAX to accommodate any concurrency requirement. DCVS MAX vote of MAX doesn't necessarily mean that DCVS will push the vote to MAX corner; MAX corner vote just sets the upper threshold for DCVS vote logic. DCVS will only bump up the clocks on need basis based on selected DCVS option. + +####Sleep Disable {#sleep_disable} +'set_sleep_disable' and 'sleep_disable' parameters of dcvs_v3 structure enables user to select low-power mode (LPM) in DSP. + +In general, applications are expected to vote for their latency tolerance via the [latency](#sleep-latency) parameter in dcvs_v3/dcvs_v2 options. The aggregated latency vote across clients is used in selecting appropriate low-power mode (LPM) of the DSP subsystem. LPM will save power when the DSP subsystem is idle by reducing leakage current. Deeper LPMs typically have higher wake up latencies, which will increase interrupt service delays and add to inter-processor communication latencies. Though the latency vote controls the selection of low-power modes, the vote required for disabling/allowing certain LPMs is difficult to calculate as the wakeup latency associated with these LPMs could change from chipset to chipset and between runs within the same chipset. + +This 'sleep_disable' parameter in dcvs_v3 allows user to directly prevent certain LPM levels of the DSP subsystem. By default, there is no restriction placed on LPMs i.e. all the LPMs are enabled and the aggregated latency vote (along with other system parameters) is used in LPM selection. The 'sleep_disable' parameter in dcvs_v3 is for the advanced developers who would like to disable certain low-power modes explicitly irrespective of the latency vote. Developers need to consider their power-performance tradeoff requirements and if necessary profile the results before voting using this parameter. Regular users are suggested to choose the default i.e. 'HAP_DCVS_LPM_ENABLE_ALL'. + +If any particular LPM level is not supported on the DSP subsystem then it will enable nearest shallow LPM level. For example, in absense of 'HAP_DCVS_LPM_LEVEL3' it will select +'HAP_DCVS_LPM_LEVEL2' which is nearest shallow LPM level to 'HAP_DCVS_LPM_LEVEL3'. + + +
set_sleep_disable FALSE No low-power mode request from the client. If FALSE then the sleep_disable field will be ignored. +
TRUE Client request for low-power mode is valid and desired option is provided in sleep_disable field. +
sleep_disable HAP_DCVS_LPM_LEVEL1 To disable sleep/low-power modes. +
HAP_DCVS_LPM_LEVEL2 To enable only standalone APCR. +
HAP_DCVS_LPM_LEVEL3 To enable RPM assisted APCR. +
HAP_DCVS_LPM_ENABLE_ALL To enable all low-power modes (enables full power collapse). +
+ +***NOTE:*** Till Palima, only HAP_DCVS_LPM_LEVEL1 and HAP_DCVS_LPM_ENABLE_ALL are supported. + +####Illustrations (DCVS_V2) +NOTE: +For working example, refer `$HEXAGON_SDK_ROOT\examples\common\benchmark_v65` application; See benchmark_setClocks() in src_dsp\benchmark_imp.c + +1. Requirement: Enable DCVS in PERFORMANCE mode, set sleep latency to 1000 micro-seconds, vote NOM in Target with SVS as Min and TURBO as Max. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v2; +request.dcvs_v2.dcvs_enable = TRUE; +request.dcvs_v2.dcvs_option = HAP_DCVS_V2_PERFORMANCE_MODE; +request.dcvs_v2.set_latency = TRUE; +request.dcvs_v2.latency = 1000; +request.dcvs_v2.set_dcvs_params = TRUE; +request.dcvs_v2.dcvs_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v2.dcvs_params.max_corner = HAP_DCVS_VCORNER_TURBO; +request.dcvs_v2.dcvs_params.target_corner = HAP_DCVS_VCORNER_NOM; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block + */ +... +//To remove the vote +memset(&request, 0, sizeof(HAP_power_request_t)); //Remove all votes. +request.type = HAP_power_set_DCVS_v2; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +2. Requirement: Disable DCVS; do NOT vote for any corners/latency +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v2; +request.dcvs_v2.dcvs_enable = FALSE; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +3. Requirement: Enable DCVS in Power saver mode. Do NOT vote for any target corner/latency, but set MIN and MAX thresholds to DCVS to SVS and TURBO respectively. Clock voting will be done via HAP_power_set_mips_bw request. +~~~{.c} +//Vote + +/* Populate request structure with dcvs_v2 request*/ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v2; +request.dcvs_v2.dcvs_enable = TRUE; +request.dcvs_v2.dcvs_option = HAP_DCVS_V2_POWER_SAVER_MODE; +request.dcvs_v2.set_dcvs_params = TRUE; +request.dcvs_v2.dcvs_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v2.dcvs_params.max_corner = HAP_DCVS_VCORNER_TURBO; +request.dcvs_v2.dcvs_params.target_corner = HAP_DCVS_VCORNER_DISABLE; //no vote +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +/* Populate request structure with mips_bw request */ +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_mips_bw; +request.mips_bw.set_mips = TRUE; +request.mips_bw.mipsPerThread = 150; +request.mips_bw.mipsTotal = 600; +request.mips_bw.set_bus_bw = TRUE; +request.mips_bw.bwBytesPerSec = 10*1000*1000; +request.mips_bw.busbwUsagePercentage = 50; +request.mips_bw.set_latency = TRUE; +request.mips_bw.latency = 1000; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); // Core and bus clocks will be set by this request. +... +/* + * Processing block + */ +... +//To remove the dcvs_v2 vote +memset(&request, 0, sizeof(HAP_power_request_t)); //Remove all votes. +request.type = HAP_power_set_DCVS_v2; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +//To remove the mips_bw vote +memset(&request, 0, sizeof(HAP_power_request_t)); //Remove all votes +request.type = HAP_power_set_mips_bw; +request.mips_bw.set_mips = TRUE; +request.mips_bw.set_bus_bw = TRUE; +request.mips_bw.set_latency = TRUE; +request.mips_bw.latency = 65535; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +4. Requirement: Enable DCVS in DUTY CYCLE mode, vote TURBO in Target with SVS as Min. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v2; +request.dcvs_v2.dcvs_enable = TRUE; +request.dcvs_v2.dcvs_option = HAP_DCVS_V2_DUTY_CYCLE_MODE; +request.dcvs_v2.set_latency = TRUE; +request.dcvs_v2.latency = 1000; +request.dcvs_v2.set_dcvs_params = TRUE; +request.dcvs_v2.dcvs_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v2.dcvs_params.max_corner = HAP_DCVS_VCORNER_TURBO; +request.dcvs_v2.dcvs_params.target_corner = HAP_DCVS_VCORNER_TURBO; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block + */ +... +//To remove the vote +memset(&request, 0, sizeof(HAP_power_request_t)); //Remove all votes. +request.type = HAP_power_set_DCVS_v2; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +####Illustrations (DCVS_V3) + + +1. Requirement: Enable DCVS in POWER SAVER mode, set sleep latency to 1000 micro-seconds, vote NOM in Target with SVS as Min and TURBO as Max for core clock, vote TURBO in Target with NOM as Min and TURBO PLUS as Max for bus clock. Later change bus clock vote as SVS_PLUS in Target with SVS as Min and NOM as Max. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.dcvs_enable = TRUE; +request.dcvs_v3.dcvs_option = HAP_DCVS_V2_POWER_SAVER_MODE; +request.dcvs_v3.set_latency = TRUE; +request.dcvs_v3.latency = 1000; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO; +request.dcvs_v3.core_params.target_corner = HAP_DCVS_VCORNER_NOM; +request.dcvs_v3.set_bus_params = TRUE; +request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_NOM; +request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +request.dcvs_v3.bus_params.target_corner = HAP_DCVS_VCORNER_TURBO; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block 1 + */ +... +//To update bus clock votes while keeping core clock and other parameters of dcvs_v3 request intact. +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_bus_params = TRUE; +request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_NOM; +request.dcvs_v3.bus_params.target_corner = HAP_DCVS_VCORNER_SVS_PLUS; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block 2 + */ +... +//To remove the vote +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.set_latency = TRUE; +request.dcvs_v3.latency = 65535; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.set_bus_params = TRUE; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +2. Requirement: Enable DCVS in PERFORMANCE mode, vote TURBO in Target with NOM as Min and TURBO PLUS as Max for core clock, do NOT vote for latency and bus clock. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.dcvs_enable = TRUE; +request.dcvs_v3.dcvs_option = HAP_DCVS_V2_PERFORMANCE_MODE; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_NOM; +request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +request.dcvs_v3.core_params.target_corner = HAP_DCVS_VCORNER_TURBO; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block + */ +... +//To remove the vote +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.set_core_params = TRUE; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +3. Requirement: Disable DCVS; do NOT vote for any corners/latency. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.dcvs_enable = FALSE; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_seti(ctx, &request); +~~~ + +4. Requirement: Disable sleep (all low power modes) and re-enable it after task completion. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_sleep_disable = TRUE; +request.dcvs_v3.sleep_disable = HAP_DCVS_LPM_LEVEL1; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block + */ +... +//To re-enable sleep. +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_sleep_disable = TRUE; +request.dcvs_v3.sleep_disable = HAP_DCVS_LPM_ENABLE_ALL; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +5. Requirement: Enable DCVS in PERFORMANCE mode. Do NOT vote for any target corner/latency, but set MIN and MAX DCVS thresholds for core clock to NOM and TURBO respectively, set MIN and MAX DCVS thresholds for bus clock to SVS and NOM respectively. Clock voting will be done via HAP_power_set_mips_bw request. +~~~{.c} +//Vote + +/* Populate request structure with dcvs_v3 request*/ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.dcvs_enable = TRUE; +request.dcvs_v3.dcvs_option = HAP_DCVS_V2_PERFORMANCE_MODE; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_NOM; +request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO; +request.dcvs_v3.set_bus_params = TRUE; +request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_NOM; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +/* Populate request structure with mips_bw request */ +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_mips_bw; +request.mips_bw.set_mips = TRUE; +request.mips_bw.mipsPerThread = 150; +request.mips_bw.mipsTotal = 600; +request.mips_bw.set_bus_bw = TRUE; +request.mips_bw.bwBytesPerSec = 10*1000*1000; +request.mips_bw.busbwUsagePercentage = 50; +request.mips_bw.set_latency = TRUE; +request.mips_bw.latency = 1000; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); // Core and bus clocks will be set by this request. +... +/* + * Processing block + */ +... +//To remove the dcvs_v3 vote +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.set_bus_params = TRUE; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +//To remove the mips_bw vote +memset(&request, 0, sizeof(HAP_power_request_t)); //Remove all votes +request.type = HAP_power_set_mips_bw; +request.mips_bw.set_mips = TRUE; +request.mips_bw.set_bus_bw = TRUE; +request.mips_bw.set_latency = TRUE; +request.mips_bw.latency = 65535; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +6. Requirement: Use wrapper APIs to: Enable DCVS in POWER SAVER AGGRESSIVE mode, set sleep latency to 1000 micro-seconds, vote NOM in Target with SVS as Min and TURBO as Max for core clock, vote TURBO in Target with NOM as Min and TURBO PLUS as Max for bus clock. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +HAP_power_set_dcvs_v3_init(&request); +retVal = HAP_power_set_dcvs_option(NULL, TRUE, HAP_DCVS_V2_POWER_SAVER_AGGRESSIVE_MODE); +retVal = HAP_power_set_sleep_latency(NULL, 1000); +retVal = HAP_power_set_core_corner(NULL, HAP_DCVS_VCORNER_NOM, HAP_DCVS_VCORNER_SVS, HAP_DCVS_VCORNER_TURBO); +retVal = HAP_power_set_bus_corner(NULL, HAP_DCVS_VCORNER_TURBO, HAP_DCVS_VCORNER_NOM, HAP_DCVS_VCORNER_TURBO_PLUS); +... +/* + * Processing block + */ +... +//To remove the vote +HAP_power_set_dcvs_v3_init(&request); +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ + +7. Requirement: Enable DCVS in DUTY CYCLE mode, vote TURBO_PLUS in Target with SVS as Min for core and bus clock. +~~~{.c} +//Vote + +/* Populate request structure */ +int retVal; +HAP_power_request_t request; +memset(&request, 0, sizeof(HAP_power_request_t)); //Important to clear the structure if only selected fields are updated. +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.dcvs_enable = TRUE; +request.dcvs_v3.dcvs_option = HAP_DCVS_V2_DUTY_CYCLE_MODE; +request.dcvs_v3.set_latency = TRUE; +request.dcvs_v3.latency = 1000; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.core_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v3.core_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +request.dcvs_v3.core_params.target_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +request.dcvs_v3.set_bus_params = TRUE; +request.dcvs_v3.bus_params.min_corner = HAP_DCVS_VCORNER_SVS; +request.dcvs_v3.bus_params.max_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +request.dcvs_v3.bus_params.target_corner = HAP_DCVS_VCORNER_TURBO_PLUS; +/* Call HAP_power_set API with the updated request structure */ +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +... +/* + * Processing block + */ +... +//To remove the vote +memset(&request, 0, sizeof(HAP_power_request_t)); +request.type = HAP_power_set_DCVS_v3; +request.dcvs_v3.set_dcvs_enable = TRUE; +request.dcvs_v3.set_latency = TRUE; +request.dcvs_v3.latency = 65535; +request.dcvs_v3.set_core_params = TRUE; +request.dcvs_v3.set_bus_params = TRUE; +/* ctx is an unique identifier, explained [here](#usage). */ +retVal = HAP_power_set(ctx, &request); +~~~ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_process.h new file mode 100755 index 0000000000000..a7aacf0287159 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_process.h @@ -0,0 +1,31 @@ +#ifndef HAP_PROCESS_H +#define HAP_PROCESS_H +/*============================================================================== + Copyright (c) 2024 Qualcomm Technologies Incorporated. + All Rights Reserved Qualcomm Technologies Proprietary + + Export of this technology or software is regulated by the U.S. + Government. Diversion contrary to U.S. law prohibited. +==============================================================================*/ + +/** @defgroup process_type Process type + * @{ + */ +/** Return values for HAP_get_pd_type + Returns any one of the below values depending on the type of PD spawned */ +enum process_type { + ROOT_PD = 0, + AUDIO_STATIC_PD = 1, + SENSOR_STATIC_PD = 2, + DYNAMIC_SIGNED_PD = 3, + DYNAMIC_UNSIGNED_PD = 4, + DYNAMIC_CPZ_PD = 5, + SECURE_PD = 6, + DYNAMIC_SYS_UNSIGNED_PD = 7, + OIS_STATIC_PD = 8, + MAX_PD_TYPE = 9 /**< Maximum number of supported PD types */ +}; +/** + * @} // process_type + */ +#endif \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.h new file mode 100755 index 0000000000000..89eac2a080350 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.h @@ -0,0 +1,164 @@ +#ifndef HAP_PS_H +#define HAP_PS_H +/*============================================================================== + Copyright (c) 2012-2019,2024 Qualcomm Technologies Incorporated. + All Rights Reserved Qualcomm Technologies Proprietary + + Export of this technology or software is regulated by the U.S. + Government. Diversion contrary to U.S. law prohibited. +==============================================================================*/ + +#include "AEEStdDef.h" +#include "HAP_process.h" + +/** + * Maximum allowed remote process name length + */ +#define PROCESS_NAME_LEN 56 + + +/** @defgroup manage_dynamic_list Manage Dynamic List. + * @{ + */ + +typedef struct HAP_process HAP_process; +struct HAP_process { + char name[PROCESS_NAME_LEN]; + int32 asid; + int32 hlos_pid; +}; + +/** + * Get list of active processes + * @param[out] num_processes : Number of active processes + * @param[out] processes : Pointer to the list of processes + * @return 0 on success, valid non-zero error code on failure + */ +int HAP_get_process_list(uint32* num_processes, HAP_process** processes); + +/** + * Add new entry to process list + * @param[in] process : Pointer to node to be added to the process list + * @return 0 on success, valid non-zero error code on failure + */ +int HAP_add_to_process_list(HAP_process* process); + +/** + * Remove entry from process list + * @param[in] hlos_pid : HLOS process ID of entry to be removed from the process list + * @return 0 on success, valid non-zero error code on failure + */ +int HAP_remove_from_process_list(int hlos_pid); + +/** + * Set name of current process + * @param[in] name : Name of process + * @return 0 on success, valid non-zero error code on failure + */ +int HAP_set_process_name(char *name); + +/** + * API deprecated from SM8150 onwards. + */ +int HAP_thread_migrate(int tidQ); + +/** + * @} + */ + + +/** @defgroup early_wakeup Signal early wakeup + * @{ + */ + + +/** Send signal to CPU for early wake up + * + * Send signal to CPU for early wake up with approximate time to complete the job. + * This signal helps to reduce FastRPC latency. + * + * Args: + * @param[in] tidQ : QuRT thread id of a skel invoke thread. Use qurt_thread_get_id() + * to retrieve the thread ID. + * @param[in] earlyWakeTime : approximate time (in us) to complete job after sending the signal + * Returns: 0 on success, valid non-zero error code on failure + */ +int HAP_send_early_signal(uint32_t tidQ, uint32_t earlyWakeTime); + +/** + * API deprecated from Lahaina onwards. Use HAP_send_early_signal() instead + */ +int fastrpc_send_early_signal(uint32_t tidQ, uint32_t earlyWakeTime); + +/** + * @} + */ + + + +/** @defgroup thread_priority_ceiling Enquire thread priority ceiling + * @{ + */ + + +/** Return the ceiling thread priority for the current process + * + * Return the thread priority ceiling for the current process. QuRT thread priorities + * run from 1 to 255, with 1 being the highest. Unprivileged user processes will + * have a ceiling priority of 64. + * + * Args: None + * Returns: Thread priority ceiling value (bet 1 & 255) on success, -1 on failure + */ +int HAP_get_thread_priority_ceiling(void); + +/** + * Identifies the HAP request user pd parameters type + * @param HAP_req_get_orig_apps_pid : Returns the process original apps pid. + */ +typedef enum { + HAP_req_get_orig_apps_pid = 1, +} HAP_req_userpd_params_type; + +/** + * Data type to get requested value from the DSP + * @param type : Identifies the request type. + * @param orig_apps_pid : Returns the process original apps pid. + */ +typedef struct { + HAP_req_userpd_params_type type; + union { + int orig_apps_pid; + }; +} HAP_req_userpd_params_t; + +/** + * Method to retrieve user process values from the DSP. This API support from SM8750 onwards. + * @param [in] request : Request params. + * @return Returns 0 for success, error code on failure. + */ +int HAP_get_userpd_params(HAP_req_userpd_params_t *request); + +/** + * @} + */ + +/** @defgroup HAP_get_pd_type Query the PD type of the process + * @{ + */ + + +/** Function to get PD type of the spawned process + * + * Args: + * @param[out] pd_type : Pointer to enum process_type to get PD type + * @return 0 on success, valid non-zero error code on failure + */ +int HAP_get_pd_type(enum process_type* pd_type); + +/** + * @} + */ + +#endif /*HAP_PS_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.md new file mode 100755 index 0000000000000..eed59f7adb3ce --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_ps.md @@ -0,0 +1,33 @@ +# Introduction {#intro} + +These APIs allow a user to perform the following actions: +* Manage the dynamic list of processes running on the current DSP +* Send a wakeup call to the CPU in order to decrease its response time upon returning from a FastRPC call +* Enquire about the thread priority ceiling for the current process + + +## API Overview {#api-overview} + +The HAP_ps.h APIs include the following functions: + +* ::HAP_get_process_list + +* ::HAP_add_to_process_list + +* ::HAP_remove_from_process_list + +* ::HAP_set_process_name + +* ::HAP_thread_migrate + +* ::HAP_send_early_signal + +* ::fastrpc_send_early_signal + +* ::HAP_get_thread_priority_ceiling + +* ::HAP_get_userpd_params + +* ::HAP_get_pd_type + +Header file: @b HAP_ps.h diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_traceme.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_traceme.h new file mode 100755 index 0000000000000..a46c56a835479 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_traceme.h @@ -0,0 +1,28 @@ +#ifndef HAP_TRACEME_H +#define HAP_TRACEME_H +/*============================================================================== + Copyright (c) 2012-2013 Qualcomm Technologies Incorporated. + All Rights Reserved Qualcomm Technologies Proprietary + + Export of this technology or software is regulated by the U.S. + Government. Diversion contrary to U.S. law prohibited. +==============================================================================*/ + +#include "AEEStdDef.h" +#include "HAP_debug.h" + +#if defined(_DEBUG) + +static __inline void HAP_traceme(void) +{ + (void)HAP_debug_ptrace(HAP_DEBUG_TRACEME, 0, 0, 0); +} + +#else /* #if defined(_DEBUG) */ + +#define HAP_traceme() + +#endif /* #if defined(_DEBUG) */ + +#endif /* #ifndef HAP_TRACEME_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.h new file mode 100755 index 0000000000000..cde225749d3c8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.h @@ -0,0 +1,221 @@ +/*----------------------------------------------------------------------------- + Copyright (c) 2019-2020 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------------*/ + +#ifndef HAP_USER_PMU_H_ +#define HAP_USER_PMU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file HAP_user_pmu.h + * @brief HAP user PMU API + */ + +/** @defgroup Constants constants + * @{ + */ + +/** Error value for unsupported APIs. */ +#define HAP_USER_PMU_READ_NOT_SUPPORTED 0x80000FFF + +/** Error value for PMU read failure. */ +#define HAP_USER_PMU_READ_FAILED 0xDEADDEAD + +/** @} + */ + +/** @defgroup Types Data types + * @{ + */ + +/** + * Input parameter type used when a group of PMU events must be read via + * HAP_register_pmu_group(), HAP_read_pmu_group() and HAP_deregister_pmu_group(). + + * The user must fill in the pmu_events[] array field of this structure with the + * specified PMU events to track and update the num_events field with the number + * of events to track. Only four unique PMU events can be tracked. + */ +typedef struct { + int contextId; + /**< Return value after registering the PMU group via HAP_register_pmu_group. */ + + unsigned int num_events; + /**< Input parameter specifying the number of PMU events register.*/ + + unsigned short pmu_events[4]; + /**< Input parameter specifying the list of PMU events to register.*/ + + unsigned int pmu_value[4]; + /**< Output parameter containing values of PMU events registered. */ +} HAP_pmu_group_config_t; + +/** @} + */ + +/** + * @cond DEV + */ +int __attribute__((weak)) __HAP_register_pmu_group(HAP_pmu_group_config_t* pmu_config); +int __attribute__((weak)) __HAP_deregister_pmu_group(int contextId); +int __attribute__((weak)) __HAP_read_pmu_group(HAP_pmu_group_config_t* pmu_config); +int __attribute__((weak)) __HAP_register_pmu_event(unsigned short pmu_event); +int __attribute__((weak)) __HAP_deregister_pmu_event(unsigned short pmu_event); +unsigned int __attribute__((weak)) __HAP_read_pmu_event(unsigned short pmu_event); + +/** + * @endcond + */ + +/** @defgroup GroupFunc API for reading a group of PMUs + * These APIs expose a way to register and read an array of PMU events + * (maximum of four PMU events) by using the #HAP_pmu_group_config_t structure. + * Alternatively, the user can use a different set of APIs explained in the next + * section to configure and read a single PMU event. + * @{ + */ + +/** + * Registers a group of PMU events to read. + * + * Call this function from the DSP user process to register a set of PMU events + * (maximum of four) for tracking. Fill in the pmu_events[] array file of + * @p pmu_config with the specified PMU events to track (maximum of four) and + * update the num_events field of @p pmu_config with the number of PMU events + * written into the pmu_events[] array. + * + * @param pmu_config Pointer to HAP_pmu_group_config_t structure with + * pmu_events[] array and num_events fields updated. + * + * @return 0 upon success. Updates the contextId field of @p pmu_config. + * @par + * The same pmu_config structure should be used for reading the PMU + * counter values #HAP_read_pmu_group() corresponding to the + * configured events and for de-registration #HAP_deregister_pmu_group(). + */ +static inline int HAP_register_pmu_group(HAP_pmu_group_config_t* pmu_config) { + if(__HAP_register_pmu_group) + return __HAP_register_pmu_group(pmu_config); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** + * Reads the PMU values of registered PMU events. + * + * Call this function after successfully calkling HAP_register_pmu_group() with the + * same structure pointer, @p pmu_config. + * This API uses the context_id field of the input @p pmu_config + * structure, which is set in a successful HAP_register_pmu_group(). + * + * @param pmu_config Pointer to the #HAP_pmu_group_config_t structure used in + * #HAP_register_pmu_group() call. + * @return + * 0 upon success. Updates the pmu_value[] array corresponding to the + * configured pmu_events[] in the structure pointed to by @p pmu_config. + * pmu_value[x] is updated to HAP_USER_PMU_READ_FAILED if the corresponding pmu_event[x] + * configuration has failed or is invalid. + * @par + * Other values upon failure. \n + * @par + * #HAP_USER_PMU_READ_NOT_SUPPORTED when unsupported. + */ +static inline int HAP_read_pmu_group(HAP_pmu_group_config_t* pmu_config) { + if(__HAP_read_pmu_group) + return __HAP_read_pmu_group(pmu_config); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** + * De-registers a group of PMU events registered via HAP_register_pmu_group(). + * + * @param pmu_config Pointer to the #HAP_pmu_group_config_t structure used in the + * HAP_register_pmu_group() call. + + * @return + * 0 upon success. \n + * Other values upon failure. + */ +static inline int HAP_deregister_pmu_group(HAP_pmu_group_config_t* pmu_config) { + if(__HAP_deregister_pmu_group) + return __HAP_deregister_pmu_group(pmu_config->contextId); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** + * @} + */ + +/** @defgroup singleFunc API for reading single PMU event + * These APIs allow the user to configure and read single PMU events. + * PMU event is used as an input in register, read and de-register APIs. + * Up to four unique PMU event requests can be served. + * @{ + */ + +/** + * Registers sa PMU event for read. + * + * @param pmu_event PMU event to register. + * + * @return + * 0 upon success. \n + * Other values upon failure. + */ +static inline int HAP_register_pmu_event(unsigned short pmu_event) { + if(__HAP_register_pmu_event) + return __HAP_register_pmu_event(pmu_event); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** + * Reads the PMU event registered via HAP_register_pmu_event(). + * + * @param pmu_event PMU event to read. Should already be registered via + * HAP_register_pmu_event(). + * + * @return + * The value of the PMU counter corresponding to the pmu_event. \n + * - HAP_USER_PMU_READ_NOT_SUPPORTED -- API is unsupported. \n + * - HAP_USER_PMU_READ_FAILED -- The given @p pmu_event read fails. + */ +static inline unsigned int HAP_read_pmu_event(unsigned short pmu_event) { + if(__HAP_read_pmu_event) + return __HAP_read_pmu_event(pmu_event); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** + * De-registers the PMU event registered via HAP_register_pmu_event(). + * + * @param pmu_event PMU event to de-register. It should already be registered + * via #HAP_register_pmu_event(). + * + * @return + * 0 upon success. \n + * Other values upon failure. \n + * HAP_USER_PMU_READ_NOT_SUPPORTED when not supported. + */ +static inline int HAP_deregister_pmu_event(unsigned short pmu_event) { + if(__HAP_deregister_pmu_event) + return __HAP_deregister_pmu_event(pmu_event); + + return HAP_USER_PMU_READ_NOT_SUPPORTED; +} + +/** @} + */ + +#ifdef __cplusplus +} +#endif +#endif /*HAP_USER_PMU_H_*/ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.md new file mode 100755 index 0000000000000..1deab8f3af81d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_user_pmu.md @@ -0,0 +1,26 @@ +# Performance monitoring unit + +The DSP subsystem has the PMU (Performance Monitoring Unit) with counters to track +hardware events (called PMU events). The HAP PMU framework exposes a +set of APIs to read these PMU counters configured with specified PMU events. PMU +events are Hexagon DSP architecture specific and the most common PMU events are briefly +described in the Hexagon DSP architecture documentation. +The [itrace](../../doxygen/itrace/index.html) library's header file `itrace_dsp_events_pmu.h` +provides a complete list of all available public PMU events alongside their descriptions. + +***NOTE:*** +* aDSP and cDSP DCVS relies on a set of PMU events to monitor DSP +statistics and make necessary decisions. Using these HAP APIs to register PMU +events results in DCVS no longer being able to track these events. This might +lead DCVS to making incorrect decisions. +* HAP PMU APIs only work on [debug-enabled](../../tools/sign.html#test-device) devices. + +The HAP PMU APIs are not accessible from unsigned PD. + +## Supported chipsets + +SM8250 and beyond + +## Framework APIs + +Header file: @b HAP_user_pmu.h diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.h new file mode 100755 index 0000000000000..dbd66f0bf88d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.h @@ -0,0 +1,214 @@ +/*----------------------------------------------------------------------------- + * Copyright (c) 2016-2020 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. +-----------------------------------------------------------------------------*/ + +#ifndef HAP_VTCM_MGR_H_ +#define HAP_VTCM_MGR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +void* __attribute__((weak)) HAP_request_async_VTCM(unsigned int size, unsigned int single_page_flag, unsigned int timeout_us); + +/** + * @defgroup vtcmapi HAP VTCM manager API. + * This section describes the HAP VTCM manager API to allocate and release VTCM. + * @{ + */ + +/** + * @file HAP_vtcm_mgr.h + * @brief APIs used to allocate, release, and query Vector TCM (VTCM) memory. + * VTCM is a high-performance, tightly-coupled memory in the cDSP + * subsystem. It can used for Hexagon Vector eXtensions (HVX) + * scatter/gather instructions, the Hexagon Matrix eXtension (HMX) engine + * (available in some cDSPs starting with Lahaina), or as high-performance + * scratch memory for other HVX workloads. + */ + +/** + * Request VTCM memory of a specified size and single page requirement. + * + * @param[in] size Size of the request in bytes. \n + * If (@p single_page_flag == 0), the size is aligned to 4 KB. \n + * If (@p single_page_flag == 1), the size is aligned to + * the closest possible page size: 4 KB, 16 KB, 64 KB, 256 KB, + * 1 MB, 4 MB, 16 MB. + * @param[in] single_page_flag Single page requirement for this allocation: + * 1 for single page requests, 0 otherwise. + * Single page requests are mandatory for + * scatter/gather operations because the operations + * must be contained within a single page of memory. + * (The memory region used by scatter/gather + * HVX instructions must reside in VTCM and cannot + * cross a page boundary). + * + * @return + * @c void* pointer to the allocated memory region on success. \n + * 0 on failure. + * + * @par Example + * @code + * // Request for a single page of 4000 bytes + * void *pVTCM = HAP_request_VTCM(4000, 1); + * if (0 != pVTCM) + * { + * // Allocation is successful. Try a release + * int result = HAP_release_VTCM(pVTCM); + * if (0 == result) + * { + * //Release successful + * } + * } + * @endcode + */ +void* HAP_request_VTCM(unsigned int size, unsigned int single_page_flag); + + /** + * Request VTCM memory of a specified size and single page requirement with a + * timeout option. + * + * This API can be used to wait for the provided timeout. The calling thread is + * suspended until the requested VTCM memory is available or until the timeout, + * whichever happens first. + * + * @b NOTE: A deadlock might occur when calling this API if the same + * thread holds a part of, or the entire VTCM memory prior to this call. + * This API is @a not supported from secure and CPZ PDs. + * + * @param[in] size Size of the request in bytes. \n + * If (@p single_page_flag == 0), the size is aligned to 4 KB. \n + * If (@p single_page_flag == 1), the size is aligned to + * the closest possible page size,: 4 KB, 16 KB, 64 KB, 256 KB, + * 1 MB, 4 MB, 16 MB + * @param[in] single_page_flag Single page requirement for this allocation: + * 1 for single page requests, 0 otherwise. + * Single page requests are mandatory for + * scatter/gather operations because the operations + * must be contained within a single page of memory. + * (The memory region used by scatter/gather + * instructions must reside in VTCM and cannot + * cross a page boundary). + * @param[in] timeout_us Timeout in microseconds. If the request is readily + * available, return success with a void pointer. If the + * request cannot be served, wait for the available VTCM + * memory until the timeout, or return failure on the + * timeout. This value must be greater than 200 for the + * timeout implementation to work; otherwise, it is treated + * like HAP_request_VTCM(). + * + * @return + * @c void* pointer to the allocated memory region on success. \n + * 0 on failure. + * + * @par Example + * @code + * // Request for a single page of 256 * 1024 bytes with + * // timeout set to 5 milliseconds + * void *pVTCM = HAP_request_async_VTCM(256 * 1024, 1, 5000); + * if (0 != pVTCM) + * { + * // Allocation is successful. Try a release + * int result = HAP_release_VTCM(pVTCM); + * if (0 == result) + * { + * //Release successful + * } + * } + * @endcode + */ +void* HAP_request_async_VTCM(unsigned int size, + unsigned int single_page_flag, + unsigned int timeout_us); + +/** + * Release a successful request for VTCM memory by providing the pointer + * to the previously allocated VTCM block. + * + * @param[in] pVA Pointer returned by a successful VTCM request call. + * + * @return + * @c int 0 on success. \n + * Non-zero on failure. + */ +int HAP_release_VTCM(void* pVA); + +/** + * Query for the VTCM size defined on target. + * + * @param[out] page_size Pointer to an @c unsigned @c int variable. + * If this parameter is non-zero on success, the memory + * location contains the maximum possible page size + * allocation (in bytes) in VTCM. + * @param[out] page_count Pointer to an @c unsigned @c int variable. + * If @p page_size is non-zero on success, the memory + * location contains the number of @p page_size + * blocks in VTCM. + * + * @return + * @c int 0 on success. \n + * Non-zero on failure. + * + * @par Example + * @code + * unsigned int page_size, page_count; + * if (0 == HAP_query_total_VTCM(&page_size, &page_count)) + * { + * // Query successful. + * // For SM8150 cDSP: + * // page_size will be 256 * 1024. + * // page_count will be 1. + * // VTCM memory defined for this chipset (256 KB) + * unsigned int total_vtcm = page_size * page_count; + * } + * @endcode + */ +int HAP_query_total_VTCM(unsigned int* page_size, unsigned int* page_count); + +/** + * API to query VTCM allocation status. + * + * @param[out] avail_block_size Pointer to an @c unsigned @c int variable. + * If this parameter is non-zero on success, the + * memory location contains the maximum contiguous + * memory chunk (in bytes) available in VTCM. + * @param[out] max_page_size Pointer to an @c unsigned @c int variable. + * If this parameter is non-zero, the memory location + * contains the maximum possible page size allocation + * (in bytes) in the available portion of VTCM. + * @param[out] num_pages Pointer to an @c unsigned @c int variable. + * If this parameter is non-zero on success, the memory + * location contains the value of @p max_page_size. + * + * @return + * @c int 0 on success. \n + * Non-zero on failure. + * + * @par Example + * @code + * unsigned int avail_block_size, max_page_size, num_pages; + * if (0 == HAP_query_avail_VTCM(&avail_block_size, &max_page_size, &num_pages)) + * { + * // Query successful. + * // Use avail_block_size, max_page_size, num_pages + * } + * @endcode + */ +int HAP_query_avail_VTCM(unsigned int* avail_block_size, + unsigned int* max_page_size, + unsigned int* num_pages); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif //HAP_VTCM_MGR_H_ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.md new file mode 100755 index 0000000000000..3d5542c05202a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/HAP_vtcm_mgr.md @@ -0,0 +1,21 @@ +# VTCM manager + +Vector TCM (VTCM) is available on supported targets with cDSP. VTCM +is a high-performance, tightly-coupled memory in the cDSP subsystem that can be used +for Hexagon Vector eXtensions (HVX) scatter/gather instructions, Hexagon Matrix +eXtension (HMX)(available in some cDSPs starting with Lahaina), or as +high-performance scratch memory for other HVX workloads. + +The VTCM manager exposes APIs in from the `HAP_vtcm_mgr.h` file to allocate, free, and query the availability of VTCM. + +***NOTE:*** +Starting with Lahaina, use the [compute resource manager](../../doxygen/HAP_compute_res/index.html){target=_blank} API for VTCM allocations instead of this legacy VTCM manager API. The compute resource manager is expanded to provide user options to do the following: + +* Allocate other compute resources (including VTCM) +* Manage application IDs, which control VTCM partitions and privileges +* Send release callbacks, which can be invoked when a high priority client requires the resource +* Release and reacquire the same VTCM size and page configuration +* Request VTCM with granular sizes (minimum and maximum required) and specific page size requirements + +The VTCM manager API is restricted to allocate VTCM only from the +primary VTCM partition (if the partition is defined). diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/adsp_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/adsp_mmap.h new file mode 100755 index 0000000000000..7e5fd438b0902 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/adsp_mmap.h @@ -0,0 +1,25 @@ +#ifndef ADSP_MMAP_H +#define ADSP_MMAP_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "AEEStdDef.h" +/** + * @param buf, the buffer virtual address + * @param bufLen, the length + * @param flags, the flags it was mapped with, 0 by default + */ +int adsp_addref_mmap(void* buf, int bufLen, uint32 flags); + +/** + * @param buf, the buffer virtual address + * @param bufLen, the length + */ +int adsp_release_mmap(void* buf, int bufLen); + + +#ifdef __cplusplus +} +#endif +#endif// ADSP_MMAP_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/apps_mem.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/apps_mem.h new file mode 100755 index 0000000000000..bb9ed189aa41b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/apps_mem.h @@ -0,0 +1,39 @@ +#ifndef _APPS_MEM_H +#define _APPS_MEM_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map)(int heapid, uint32 ion_flags, uint32 rflags, uint32 vin, int32 len, uint32* vapps, uint32* vadsp) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap)(uint32 vadsp, int32 len) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map64)(int heapid, uint32 ion_flags, uint32 rflags, uint64 vin, int64 len, uint64* vapps, uint64* vadsp) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap64)(uint64 vadsp, int64 len) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_share_map)(int fd, int size, uint64* vapps, uint64* vadsp) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_share_unmap)(uint64 vadsp, int size) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_APPS_MEM_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain.h new file mode 100755 index 0000000000000..62c6ecdadb0af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 QUALCOMM Technologies Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + * + */ + +#include "remote.h" + +#ifdef _AUTO + #include "domain_auto.h" +#else + #include "domain_default.h" +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain_default.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain_default.h new file mode 100755 index 0000000000000..efb741af8faee --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/domain_default.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021 QUALCOMM Technologies Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + * + */ + +#include "remote.h" + +domain supported_domains[] = { + {ADSP_DOMAIN_ID, ADSP_DOMAIN}, + {MDSP_DOMAIN_ID, MDSP_DOMAIN}, + {SDSP_DOMAIN_ID, SDSP_DOMAIN}, + {CDSP_DOMAIN_ID, CDSP_DOMAIN}, + {CDSP1_DOMAIN_ID, CDSP1_DOMAIN} +}; + +bool is_CDSP(int domain_id) { + return (domain_id == CDSP_DOMAIN_ID || domain_id == CDSP1_DOMAIN_ID); +} diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.h new file mode 100755 index 0000000000000..91a3a4b737b5e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.h @@ -0,0 +1,455 @@ +/* + Copyright (c) 2020 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +*/ + + +/** @file + Asynchronous DSP Packet Queue API. +*/ + +#ifndef DSPQUEUE_H +#define DSPQUEUE_H + +#include +#include +#include + + +/** @defgroup dspqueue_consts Asynchronous DSP Packet Queue API Constants + * @{ + */ + +/** Infinite timeout */ +#define DSPQUEUE_TIMEOUT_NONE 0xffffffff + + +/** + * Packet flags. The flags are used as a bitfield in packet read/write operations. + */ +enum dspqueue_packet_flags { + DSPQUEUE_PACKET_FLAG_MESSAGE = 0x0001, /**< Packet contains a message */ + DSPQUEUE_PACKET_FLAG_BUFFERS = 0x0002, /**< Packet contains buffer references */ + DSPQUEUE_PACKET_FLAG_WAKEUP = 0x0004, /**< Early wakeup packet */ + DSPQUEUE_PACKET_FLAG_DRIVER_READY = 0x0008, /**< Packet is ready for driver consumption. Currently unused. */ + DSPQUEUE_PACKET_FLAG_USER_READY = 0x0010, /**< Packet is ready for userspace library consumption */ + DSPQUEUE_PACKET_FLAG_RESERVED_ZERO = 0xffe0 +}; + +/** + * Buffer flags. The flags are used in dspqueue_buffer.flags as a bitfield. + */ +enum dspqueue_buffer_flags { + /* 1 and 2 reserved */ + DSPQUEUE_BUFFER_FLAG_REF = 0x00000004, /**< Add a reference to a previously mapped buffer */ + DSPQUEUE_BUFFER_FLAG_DEREF = 0x00000008, /**< Remove a reference from a previously mapped buffer */ + DSPQUEUE_BUFFER_FLAG_FLUSH_SENDER = 0x00000010, /**< Flush buffer from sender caches */ + DSPQUEUE_BUFFER_FLAG_INVALIDATE_SENDER = 0x00000020, /**< Invalidate buffer from sender caches */ + DSPQUEUE_BUFFER_FLAG_FLUSH_RECIPIENT = 0x00000040, /**< Flush buffer from recipient caches */ + DSPQUEUE_BUFFER_FLAG_INVALIDATE_RECIPIENT = 0x00000080, /**< Invalidate buffer from recipient caches */ + DSPQUEUE_BUFFER_FLAG_RESERVED_ZERO = 0xffffff00 +}; + + +/** + * Statistics readable with dspqueue_get_stat() + */ +enum dspqueue_stat { + DSPQUEUE_STAT_READ_QUEUE_PACKETS = 1, /**< Numbers of packets in the read queue */ + DSPQUEUE_STAT_READ_QUEUE_BYTES, /**< Number of bytes in the read queue */ + DSPQUEUE_STAT_WRITE_QUEUE_PACKETS, /**< Number of packets in the write queue */ + DSPQUEUE_STAT_WRITE_QUEUE_BYTES, /**< Number of bytes in the write queue */ + + DSPQUEUE_STAT_EARLY_WAKEUP_WAIT_TIME, /**< Total accumulated early wakeup wait time in microseconds. + Developers can use this value to tune their early wakeup + request timing; the target should be to have this value as + close to zero as possible while minimizing signaling latency. + For more information on tuning early wakeup requests, see the + "Performance Considerations" section in the main Hexagon SDK + "Asynchronous Packet Queue" document. */ + + DSPQUEUE_STAT_EARLY_WAKEUP_MISSES /**< Number accumulated of packets missed in the early wakeup loop. + Developers can use this value to tune their early wakeup + request timing. If this value is above zero it indicates the + early wakeup request was sent too early and it expired before + the corresponding packet was received. + For more information on tuning early wakeup requests, see the + "Performance Considerations" section in the main Hexagon SDK + "Asynchronous Packet Queue" document. */ +}; + +/** @} + */ + + +/** @defgroup dspqueue_types Asynchronous DSP Packet Queue API Data Types + * @{ + */ + +struct dspqueue; +typedef struct dspqueue* dspqueue_t; /**< Queue handle */ + + +/** + * Buffer reference in a packet. + * The buffer must already be mapped to the DSP using the same file descriptor. + * The subsection of the buffer as specified by #offset and #size must fit + * entirely within the mapped buffer. + * Note that buffer references are tracked based on the buffer file descriptor, + * and taking/releasing a reference to a buffer applies to the entire buffer as + * mapped to the DSP, not just the subsection specified. + */ +struct dspqueue_buffer { + uint32_t fd; /**< Buffer file descriptor */ + uint32_t size; /**< Buffer size in bytes. The client can set this field + to zero when writing packets; in this case the + framework will set the field to the size of the + buffer as mapped. */ + uint32_t offset; /**< Offset within the buffer in bytes as allocated and mapped. + The virtual address #ptr includes the offset */ + uint32_t flags; /**< Buffer flags, see enum #dspqueue_buffer_flags */ + union { + void *ptr; /**< Buffer virtual address; NULL if not mapped in the local context */ + uint64_t address; + }; +}; + + +/** + * Callback function type for all queue callbacks + * + * @param queue Queue handle from dspqueue_create() / dspqueue_import() + * @param error Error code + * @param context Client-provided context pointer + */ +typedef void (*dspqueue_callback_t)(dspqueue_t queue, AEEResult error, void *context); + +/** @} + */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @defgroup dspqueue_funcs Asynchronous DSP Packet Queue API Functions + * @{ + */ + +/** + * Create a new queue to communicate with the DSP. Queues can only be + * created on the host CPU. + * + * @param [in] domain DSP to communicate with (CDSP_DOMAIN_ID in remote.h for cDSP) + * @param [in] flags Queue creation flags + * @param [in] req_queue_size Total request queue memory size in bytes; use 0 for system default + * @param [in] resp_queue_size Total response queue memory size in bytes; use 0 for system default + * @param [in] packet_callback Callback function called when there are new packets to read. + * The call will be done in a different thread's context. + * NULL to disable the callback. Clients cannot use blocking read + * calls if a packet callback has been set. + * @param [in] error_callback Callback function called on unrecoverable errors. NULL to disable. + * @param [in] callback_context Context pointer for callback functions + * @param [out] queue Queue handle + * + * @return 0 on success, error code on failure. + * - AEE_ENOMEMORY: Not enough memory available + * - AEE_EUNSUPPORTED: Message queue not supported on the given DSP + * - AEE_EBADPARM: Bad parameters, e.g. Invalid domain (use CDSP_DOMAIN_ID for cDSP), Too many queues open for the DSP in this process + * - AEE_ERPC: Internal RPC error, e.g. Queue list corrupt + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_create(int domain, + uint32_t flags, + uint32_t req_queue_size, uint32_t resp_queue_size, + dspqueue_callback_t packet_callback, + dspqueue_callback_t error_callback, + void *callback_context, + dspqueue_t *queue); + +/** + * Close a queue and free all memory associated with it. The + * function can be called on the host CPU with queue handles from + * dspqueue_create() or on the DSP with handles from + * dspqueue_import(). + * + * @param [in] queue Queue handle from dsp_queue_create() from dsp_queue_import(). + * + * @return 0 on success, error code on failure. + * - AEE_EBADPARM: Bad parameters, e.g. The queue is open on the DSP when attempting to close it on the host CPU + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_close(dspqueue_t queue); + +/** + * Export a queue to the DSP. The CPU-side client calls this function, + * passes the ID to the DSP, which can then call dspqueue_import() to + * access the queue. + * + * @param [in] queue Queue handle from dspqueue_create() + * @param [out] queue_id Queue ID + * + * @return 0 on success, error code on failure. + */ +AEEResult dspqueue_export(dspqueue_t queue, uint64_t *queue_id); + +/** + * Import a queue on the DSP based on an ID passed in from the host + * CPU. The DSP client can use the returned queue handle to access the + * queue and communicate with its host CPU counterpart. + * + * @param [in] queue_id Queue ID from dspqueue_export(). + * @param [in] packet_callback Callback function called when there are new packets to read. + * The call will be done in a different thread's context. + * NULL to disable the callback. + * @param [in] error_callback Callback function called on unrecoverable errors. NULL to disable. + * @param [in] callback_context Context pointer fo callback functions + * @param [out] queue Queue handle + * + * @return 0 on success, error code on failure. + * - AEE_EITEMBUSY: The queue has already been imported + * - AEE_EQURTTHREADCREATE: Unable to create callback thread; the system may have + * reached its thread limit. + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_import(uint64_t queue_id, + dspqueue_callback_t packet_callback, + dspqueue_callback_t error_callback, + void *callback_context, + dspqueue_t *queue); +/** + * Write a packet to a queue. This variant of the function will not + * block, and will instead return AEE_EWOULDBLOCK if the queue does not have + * enough space for the packet. + * + * With this function the client can pass separate pointers to the + * buffer references and message to include in the packet and the + * library copies the contents directly to the queue. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [in] flags Packet flags. See enum #dspqueue_packet_flags + * @param [in] num_buffers Number of buffer references to insert to the packet; + * zero if there are no buffer references + * @param [in] buffers Pointer to buffer references + * @param [in] message_length Message length in bytes; + * zero if the packet contains no message + * @param [in] message Pointer to packet message + * + * @return 0 on success, error code on failure. + * - AEE_EWOULDBLOCK: The queue is full + * - AEE_EBADPARM: Bad parameters, e.g. buffers is NULL when num_buffers > 0 , + * The packet is too long to fit in the queue. The call will never succeed. + * - AEE_ENOSUCHMAP: Attempt to refer to an unmapped buffer. Buffers must be mapped to the DSP + * with fastrpc_mmap() before they can be used in queue packets. + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_write_noblock(dspqueue_t queue, uint32_t flags, + uint32_t num_buffers, struct dspqueue_buffer *buffers, + uint32_t message_length, const uint8_t *message); + +/** + * Write a packet to a queue. If the queue is full this function will + * block until space becomes available or the request times out. + * + * With this function the client can pass separate pointers to the + * buffer references and message to include in the packet and the + * library copies the contents directly to the queue. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [in] flags Packet flags. See enum #dspqueue_packet_flags + * @param [in] num_buffers Number of buffer references to insert to the packet; + * zero if there are no buffer references + * @param [in] buffers Pointer to buffer references + * @param [in] message_length Message length in bytes; + * zero if the packet contains no message + * @param [in] message Pointer to packet message + * @param [in] timeout_us Timeout in microseconds; use DSPQUEUE_TIMEOUT_NONE to + * block indefinitely until a space is available or + * zero for non-blocking behavior. + * + * @return 0 on success, error code on failure. + * - AEE_EBADPARM: Bad parameters, e.g. buffers is NULL when num_buffers > 0 + * The packet is too long to fit in the queue. The call will never succeed. + * - AEE_ENOSUCHMAP: Attempt to refer to an unmapped buffer. Buffers must be mapped to the DSP + * with fastrpc_mmap() before they can be used in queue packets. + * - AEE_EEXPIRED: Request timed out + * - AEE_EINTERRUPTED: The request was canceled + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_write(dspqueue_t queue, uint32_t flags, + uint32_t num_buffers, struct dspqueue_buffer *buffers, + uint32_t message_length, const uint8_t *message, + uint32_t timeout_us); + +/** + * Read a packet from a queue. This variant of the function will not + * block, and will instead return AEE_EWOULDBLOCK if the queue does not have + * enough space for the packet. + * + * This function will read packet contents directly into + * client-provided buffers. The buffers must be large enough to fit + * contents from the packet or the call will fail. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [out] flags Packet flags. See enum #dspqueue_packet_flags + * @param [in] max_buffers The maximum number of buffer references that can fit in the "buffers" parameter + * @param [out] num_buffers The number of buffer references in the packet + * @param [out] buffers Buffer reference data from the packet + * @param [in] max_message_length Maximum message length that can fit in the "message" parameter + * @param [out] message_length Message length in bytes + * @param [out] message Packet message + * + * @return 0 on success, error code on failure. + * - AEE_EBADPARM: Bad parameters, e.g. The packet is too large to fit in the provided buffers + * - AEE_ENOSUCHMAP: The packet refers to an unmapped buffer. Buffers must be mapped to the DSP + * with fastrpc_mmap() before they can be used in queue packets. + * - AEE_EWOULDBLOCK: The queue is empty; try again later + * - AEE_EBADITEM: The queue contains a corrupted packet. Internal error. + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_read_noblock(dspqueue_t queue, uint32_t *flags, + uint32_t max_buffers, uint32_t *num_buffers, struct dspqueue_buffer *buffers, + uint32_t max_message_length, uint32_t *message_length, uint8_t *message); + +/** + * Read a packet from a queue. If the queue is empty this function + * will block until a packet is available or the request times out. + * The queue must not have a packet callback set. + * + * This function will read packet contents directly into + * client-provided buffers. The buffers must be large enough to fit + * contents from the packet or the call will fail. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [out] flags Packet flags. See enum #dspqueue_packet_flags + * @param [in] max_buffers The maximum number of buffer references that can fit in the "buffers" parameter + * @param [out] num_buffers The number of buffer references in the packet + * @param [out] buffers Buffer reference data from the packet + * @param [in] max_message_length Maximum message length that can fit in the "message" parameter + * @param [out] message_length Message length in bytes + * @param [out] message Packet message + * @param [in] timeout_us Timeout in microseconds; use DSPQUEUE_TIMEOUT_NONE to + * block indefinitely until a packet is available or + * zero for non-blocking behavior. + * + * @return 0 on success, error code on failure. + * - AEE_EBADPARM: Bad parameters, e.g. The packet is too large to fit in the provided buffers + * - AEE_ENOSUCHMAP: The packet refers to an unmapped buffer. Buffers must be mapped to the DSP + * with fastrpc_mmap() before they can be used in queue packets. + * - AEE_EBADITEM: The queue contains a corrupted packet. Internal error. + * - AEE_EBADSTATE: Bad internal state + * - AEE_EEXPIRED: Request timed out + * - AEE_EINTERRUPTED: The request was canceled + */ +AEEResult dspqueue_read(dspqueue_t queue, uint32_t *flags, + uint32_t max_buffers, uint32_t *num_buffers, struct dspqueue_buffer *buffers, + uint32_t max_message_length, uint32_t *message_length, uint8_t *message, + uint32_t timeout_us); + +/** + * Retrieve information for the next packet if available, without reading + * it from the queue and advancing the read pointer. This function + * will not block, but will instead return an error if the queue is + * empty. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import(). + * @param [out] flags Packet flags. See enum #dspqueue_packet_flags + * @param [out] num_buffers Number of buffer references in packet + * @param [out] message_length Packet message length in bytes + * + * @return 0 on success, error code on failure. + * - AEE_EWOULDBLOCK: The queue is empty; try again later + * - AEE_EBADITEM: The queue contains a corrupted packet. Internal error. + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_peek_noblock(dspqueue_t queue, uint32_t *flags, uint32_t *num_buffers, + uint32_t *message_length); + +/** + * Retrieve information for the next packet, without reading it from the + * queue and advancing the read pointer. If the queue is empty this + * function will block until a packet is available or the request + * times out. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import(). + * @param [out] flags Packet flags. See enum #dspqueue_packet_flags + * @param [out] num_buffers Number of buffer references in packet + * @param [out] message_length Packet message length in bytes + * @param [out] timeout_us Timeout in microseconds; use DSPQUEUE_TIMEOUT_NONE to + * block indefinitely until a packet is available or + * zero for non-blocking behavior. + * + * @return 0 on success, error code on failure. + * - AEE_EEXPIRED: Request timed out + * - AEE_EINTERRUPTED: The request was canceled + * - AEE_EBADITEM: The queue contains a corrupted packet. Internal error. + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_peek(dspqueue_t queue, uint32_t *flags, uint32_t *num_buffers, + uint32_t *message_length, uint32_t timeout_us); + + +/** + * Write an early wakeup packet to the queue. Early wakeup packets are used + * to bring the recipient out of a low-power state in anticipation of a real + * message packet being availble shortly, and are typically used from the DSP + * to signal that an operation is almost complete. + * + * This function will return immediately if the queue is full. There is no + * blocking variant of this function; if the queue is full the other endpoint + * should already be processing data and an early wakeup would not be useful. + * + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [in] wakeup_delay Wakeup time in microseconds; this indicates how soon + * the real message packet should be available. Zero if not known. + * The recipient can use this information to determine how to + * wait for the packet. + * @param [in] packet_flags Flags for the upcoming packet if known. + * The framework can use this information to optimize its + * behavior if the flags match the upcoming packet; if not known + * set to zero. + * See enum #dspqueue_packet_flags + * + * @return 0 on success, error code on failure. + * - AEE_EWOULDBLOCK: The queue is full + * - AEE_EBADSTATE: Bad internal state + */ +AEEResult dspqueue_write_early_wakeup_noblock(dspqueue_t queue, uint32_t wakeup_delay, uint32_t packet_flags); + + +/** + * Retrieve statistics from a queue. Statistics are relative to the queue + * as viewed from the current endpoint (e.g. "read queue" refers to the + * queue as being read by the current endpoint). + * + * Reading an accumulating statistic (such as early wakeup wait time) + * will reset it to zero. + * + * Note that statistics values are only valid at the time when they're + * read. By the time this function returns the values may have + * changed due to actions from another thread or the other queue + * endpoint. + * + * @param [in] queue Queue handle from dspqueue_create() or dspqueue_import() + * @param [in] stat Statistic to read, see enum dspqueue_stat + * @param [out] value Statistic value. Reading a statistic will reset it to zero + * + * @return 0 on success, error code on failure. + * - AEE_EBADPARM: Invalid statistic + */ + +AEEResult dspqueue_get_stat(dspqueue_t queue, enum dspqueue_stat stat, uint64_t *value); + + +/** @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif //DSPQUEUE_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.md new file mode 100755 index 0000000000000..3f1ff3206156b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dspqueue.md @@ -0,0 +1,36 @@ +# Asynchronous DSP Packet Queue + +## API Overview {#api-overview} + +The Asynchronous DSP Packet Queue is accessed through a simple C +API. Most of the API is identical on both the host CPU and DSP with +the exception that queues can only be created on the CPU. + +* dspqueue_create(): Create a new queue. Queues can only be created + on the host CPU. + +* dspqueue_close(): Close a queue + +* dspqueue_export(): Export a queue on the host CPU, creating a + handle that be used with dspqueue_import() on the DSP. + +* dspqueue_import(): Import a queue for use on the DSP, using a + handle returned from dspqueue_export() on the CPU. + +* dspqueue_write() / dspqueue_write_noblock(): Write a packet to a + queue. Writes can either block if the queue is full or return an + error (dspqueue_write_noblock()); blocking writes can optionally + have a timeout. + +* dspqueue_read() / dspqueue_read_noblock(): Read a packet from a + queue. + +* dspqueue_peek() / dspqueue_peek_noblock(): Retrieve information + about the next packet without consuming it. + +* dspqueue_write_early_wakeup_noblock(): Write an early wakeup packet to the + queue. + +* dspqueue_get_stat(): Retrieve queue statistics, including the number + of packets queued and statistics about early wakeup. + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/dynsymbols.lst b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dynsymbols.lst new file mode 100755 index 0000000000000..17663f8ddb672 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/dynsymbols.lst @@ -0,0 +1,1364 @@ +{ +___dladdr; +___dlclose; +___dlerror; +___dlopen; +___dlsym; +__assert; +__builtin_mr_assignment; +__builtin_pseudo_barrier; +__builtinfunction_bitrev_update1_for_load; +__builtinfunction_bitrev_update1_for_store; +__builtinfunction_bitrev_update2_for_load; +__builtinfunction_bitrev_update2_for_store; +__builtinfunction_bitrev_update4_for_load; +__builtinfunction_bitrev_update4_for_store; +__builtinfunction_bitrev_update8_for_load; +__builtinfunction_bitrev_update8_for_store; +__builtinfunction_bitreverse; +__builtinfunction_bitrevupdate; +__builtinfunction_circular_update1_for_load; +__builtinfunction_circular_update1_for_store; +__builtinfunction_circular_update1I_for_load; +__builtinfunction_circular_update1I_for_store; +__builtinfunction_circular_update2_for_load; +__builtinfunction_circular_update2_for_store; +__builtinfunction_circular_update2I_for_load; +__builtinfunction_circular_update2I_for_store; +__builtinfunction_circular_update4_for_load; +__builtinfunction_circular_update4_for_store; +__builtinfunction_circular_update4I_for_load; +__builtinfunction_circular_update4I_for_store; +__builtinfunction_circular_update8_for_load; +__builtinfunction_circular_update8_for_store; +__builtinfunction_circular_update8I_for_load; +__builtinfunction_circular_update8I_for_store; +__builtinfunction_circupdate; +__CTOR_END__; +__cxa_atexit; +__cxa_finalize; +__cxa_finalize_stub; +__cxa_guard_abort; +__cxa_guard_acquire; +__cxa_guard_release; +__cxa_pure_virtual; +__deallocframe; +__default_hash; +__deregister_frame_info_bases; +__divdc3; +__divsc3; +__divxc3; +__dladdr; +__dlclose; +__dlerror; +__dlopen; +__dlsym; +__dso_handle; +__DTOR_LIST__; +__eh_nodes; +__hexagon_adddf3; +__hexagon_addsf3; +__hexagon_cmpdf2; +__hexagon_cmpsf2; +__hexagon_cmpxdf2; +__hexagon_cmpxsf2; +__hexagon_divdf3; +__hexagon_divdi3; +__hexagon_divsf3; +__hexagon_divsi3; +__hexagon_eqdf2; +__hexagon_eqsf2; +__hexagon_extendsfdf2; +__hexagon_fast2_adddf3; +__hexagon_fast2_divdf3; +__hexagon_fast2_divsf3; +__hexagon_fast2_muldf3; +__hexagon_fast2_sqrt; +__hexagon_fast2_sqrtdf2; +__hexagon_fast2_sqrtf; +__hexagon_fast2_subdf3; +__hexagon_fast_adddf3; +__hexagon_fast_divdf3; +__hexagon_fast_divsf3; +__hexagon_fast_gtdf2; +__hexagon_fast_ltdf2; +__hexagon_fast_muldf3; +__hexagon_fast_negdf2; +__hexagon_fast_sqrt; +__hexagon_fast_sqrtdf2; +__hexagon_fast_sqrtf; +__hexagon_fast_subdf3; +__hexagon_fixdfdi; +__hexagon_fixdfsi; +__hexagon_fixdfti; +__hexagon_fixsfdi; +__hexagon_fixsfsi; +__hexagon_fixsfti; +__hexagon_fixunsdfdi; +__hexagon_fixunsdfsi; +__hexagon_fixunsdfti; +__hexagon_fixunssfdi; +__hexagon_fixunssfsi; +__hexagon_fixunssfti; +__hexagon_floatdidf; +__hexagon_floatdisf; +__hexagon_floatsidf; +__hexagon_floatsisf; +__hexagon_floattidf; +__hexagon_floattisf; +__hexagon_floatundidf; +__hexagon_floatundisf; +__hexagon_floatunsidf; +__hexagon_floatunsisf; +__hexagon_fmadf4; +__hexagon_gedf2; +__hexagon_gesf2; +__hexagon_gtdf2; +__hexagon_gtsf2; +__hexagon_ledf2; +__hexagon_lesf2; +__hexagon_ltdf2; +__hexagon_ltsf2; +__hexagon_maxdf3; +__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes; +__hexagon_mindf3; +__hexagon_moddi3; +__hexagon_modsi3; +__hexagon_muldf3; +__hexagon_mulsf3; +__hexagon_nedf2; +__hexagon_negdf2; +__hexagon_negsf2; +__hexagon_nesf2; +__hexagon_sqrt; +__hexagon_sqrtdf2; +__hexagon_sqrtf; +__hexagon_subdf3; +__hexagon_subsf3; +__hexagon_truncdfsf2; +__hexagon_udivdi3; +__hexagon_udivmoddi4; +__hexagon_udivmodsi4; +__hexagon_udivsi3; +__hexagon_umoddi3; +__hexagon_umodsi3; +__hexagon_unorddf2; +__hexagon_unordsf2; +__ieee754_j0; +__ieee754_j1; +__ieee754_jn; +__ieee754_log; +__ieee754_scalb; +__ieee754_y0; +__ieee754_y1; +__ieee754_yn; +__muldc3; +__mulsc3; +__mulxc3; +__qdsp_adddf3; +__qdsp_addsf3; +__qdsp_cmpdf2; +__qdsp_cmpsf2; +__qdsp_cmpxdf2; +__qdsp_cmpxsf2; +__qdsp_divdf3; +__qdsp_divdi3; +__qdsp_divsf3; +__qdsp_divsi3; +__qdsp_eqdf2; +__qdsp_eqsf2; +__qdsp_extendsfdf2; +__qdsp_fast_gtdf2; +__qdsp_fast_ltdf2; +__qdsp_fast_negdf2; +__qdsp_fixdfdi; +__qdsp_fixdfsi; +__qdsp_fixdfti; +__qdsp_fixsfdi; +__qdsp_fixsfsi; +__qdsp_fixsfti; +__qdsp_fixunsdfdi; +__qdsp_fixunsdfsi; +__qdsp_fixunsdfti; +__qdsp_fixunssfdi; +__qdsp_fixunssfsi; +__qdsp_fixunssfti; +__qdsp_floatdidf; +__qdsp_floatdisf; +__qdsp_floatsidf; +__qdsp_floatsisf; +__qdsp_floattidf; +__qdsp_floattisf; +__qdsp_floatundidf; +__qdsp_floatundisf; +__qdsp_floatunsidf; +__qdsp_floatunsisf; +__qdsp_fmadf5; +__qdsp_gedf2; +__qdsp_gesf2; +__qdsp_gtdf2; +__qdsp_gtsf2; +__qdsp_ledf2; +__qdsp_lesf2; +__qdsp_ltdf2; +__qdsp_ltsf2; +__qdsp_maxdf3; +__qdsp_memcpy_likely_aligned_min32bytes_mult8bytes; +__qdsp_mindf3; +__qdsp_moddi3; +__qdsp_modsi3; +__qdsp_muldf3; +__qdsp_mulsf3; +__qdsp_nedf2; +__qdsp_negdf2; +__qdsp_negsf2; +__qdsp_nesf2; +__qdsp_sqrt; +__qdsp_sqrtdf2; +__qdsp_sqrtf; +__qdsp_subdf3; +__qdsp_subsf3; +__qdsp_truncdfsf2; +__qdsp_udivdi3; +__qdsp_udivmoddi4; +__qdsp_udivmodsi4; +__qdsp_udivsi3; +__qdsp_umoddi3; +__qdsp_umodsi3; +__qdsp_unorddf2; +__qdsp_unordsf2; +__register_frame_info_bases; +__registerx; +__restore_r16_through_r17_and_deallocframe; +__restore_r16_through_r17_and_deallocframe_before_tailcall; +__restore_r16_through_r19_and_deallocframe; +__restore_r16_through_r19_and_deallocframe_before_tailcall; +__restore_r16_through_r21_and_deallocframe; +__restore_r16_through_r21_and_deallocframe_before_tailcall; +__restore_r16_through_r23_and_deallocframe; +__restore_r16_through_r23_and_deallocframe_before_tailcall; +__restore_r16_through_r25_and_deallocframe; +__restore_r16_through_r25_and_deallocframe_before_tailcall; +__restore_r16_through_r27_and_deallocframe; +__restore_r16_through_r27_and_deallocframe_before_tailcall; +__restore_r24_through_r25_and_deallocframe; +__restore_r24_through_r25_and_deallocframe_before_tailcall; +__restore_r24_through_r27_and_deallocframe; +__restore_r24_through_r27_and_deallocframe_before_tailcall; +__restore_r27_through_r16_and_deallocframe; +__restore_r27_through_r16_and_deallocframe_before_sibcall; +__restore_r27_through_r18_and_deallocframe; +__restore_r27_through_r18_and_deallocframe_before_sibcall; +__restore_r27_through_r20_and_deallocframe; +__restore_r27_through_r20_and_deallocframe_before_sibcall; +__restore_r27_through_r22_and_deallocframe; +__restore_r27_through_r22_and_deallocframe_before_sibcall; +__restore_r27_through_r24_and_deallocframe; +__restore_r27_through_r24_and_deallocframe_before_sibcall; +__restore_r27_through_r26_and_deallocframe; +__restore_r27_through_r26_and_deallocframe_before_sibcall; +__save_r16_through_r17; +__save_r16_through_r19; +__save_r16_through_r21; +__save_r16_through_r23; +__save_r16_through_r25; +__save_r16_through_r27; +__save_r24_through_r25; +__save_r24_through_r27; +__save_r27_through_r16; +__save_r27_through_r18; +__save_r27_through_r20; +__save_r27_through_r22; +__save_r27_through_r24; +__sqrtf; +__stack_chk_fail; +__stack_chk_guard; +__tls_get_addr; +__wrap_calloc; +__wrap_free; +__wrap_malloc; +__wrap_memalign; +__wrap_realloc; +_Aldata; +_Assert; +_Atan; +_AtcountPrivate; +_AtcountPublic; +_Atdata; +_Atexit; +_Atfuns; +_Atrealloc; +_Btowc; +_C_tolower_; +_C_toupper_; +_Caddcc; +_Caddcr; +_Cbuild; +_Cdivcc; +_Cdivcr; +_Clearlocks; +_Clocale; +_Closreg; +_Cmulcc; +_Cmulcr; +_Cosh; +_CStrftime; +_CStrxfrm; +_Csubcc; +_Csubcr; +_CTinfo; +_CurrentTimeLocale; +_CWcsxfrm; +_Daysto; +_Dbl; +_Dclass; +_DefaultTimeLocale; +_Defloc; +_Denorm; +_Dint; +_Dnorm; +_Dscale; +_Dsign; +_Dtentox; +_Dtest; +_Dunscale; +_Eps; +_Erf_one; +_Erf_small; +_Erfc; +_Exit; +_Exp; +_FAtan; +_FCaddcc; +_FCaddcr; +_FCbuild; +_FCdivcc; +_FCdivcr; +_FCmulcc; +_FCmulcr; +_FCosh; +_FCsubcc; +_FCsubcr; +_FDclass; +_FDenorm; +_FDint; +_FDnorm; +_FDscale; +_FDsign; +_FDtentox; +_FDtest; +_FDunscale; +_Fenv0; +_FEps; +_Feraise; +_FErf_one; +_FErf_small; +_FErfc; +_FExp; +_FFpcomp; +_FGamma_big; +_Fgpos; +_FHypot; +_Files; +_Findloc; +_FInf; +_fini; +_FLog; +_FLogpoly; +_Flt; +_Fltrounds; +_FNan; +_Fofind; +_Fofree; +_Fopen; +_Foprep; +_Force_raise; +_Fpcomp; +_FPoly; +_FPow; +_FQuad; +_FQuadph; +_Freeloc; +_FRint; +_Frprep; +_FRteps; +_FSin; +_FSinh; +_FSnan; +_Fspos; +_FTgamma; +_Fwprep; +_FXbig; +_FXp_addh; +_FXp_addx; +_FXp_getw; +_FXp_invx; +_FXp_ldexpx; +_FXp_movx; +_FXp_mulh; +_FXp_mulx; +_FXp_setw; +_FXp_sqrtx; +_FXp_subx; +_FZero; +_Gamma_big; +_Genld; +_Gentime; +_Get_eh_data; +_Getcloc; +_Getdst; +_Geterrno; +_Getfld; +_Getfloat; +_Getint; +_Getlname; +_Getloc; +_Getmbcurmax; +_Getmem; +_Getnloc; +_Getpcostate; +_Getpctype; +_Getpmbstate; +_Getptimes; +_Getptolower; +_Getptoupper; +_Getpwcostate; +_Getpwcstate; +_Getpwctrtab; +_Getpwctytab; +_Getstr; +_Gettime; +_Getzone; +_Hugeval; +_Hypot; +_Inf; +_init; +_Init_db; +_Initlocks; +_Isdst; +_Iswctype; +_LAtan; +_LCaddcc; +_LCaddcr; +_LCbuild; +_LCdivcc; +_LCdivcr; +_LCmulcc; +_LCmulcr; +_LCosh; +_LCsubcc; +_LCsubcr; +_Ldbl; +_LDclass; +_LDenorm; +_LDint; +_LDscale; +_LDsign; +_LDtentox; +_LDtest; +_Ldtob; +_LDunscale; +_LEps; +_LErf_one; +_LErf_small; +_LErfc; +_LExp; +_LFpcomp; +_LGamma_big; +_LHypot; +_LInf; +_Litob; +_LLog; +_LLogpoly; +_LNan; +_Lockfilelock; +_Locksyslock; +_Locsum; +_Loctab; +_Locterm; +_Locvar; +_Log; +_Logpoly; +_LPoly; +_LPow; +_LQuad; +_LQuadph; +_LRint; +_LRteps; +_LSin; +_LSinh; +_LSnan; +_LTgamma; +_LXbig; +_LXp_addh; +_LXp_addx; +_LXp_getw; +_LXp_invx; +_LXp_ldexpx; +_LXp_movx; +_LXp_mulh; +_LXp_mulx; +_LXp_setw; +_LXp_sqrtx; +_LXp_subx; +_LZero; +_Makeloc; +_Makestab; +_Makewct; +_Mbtowc; +_Mbtowcx; +_Nan; +_Nats; +_Nnl; +_Parse_cie; +_Parse_csd; +_Parse_fde; +_Parse_fde_instr; +_Parse_lsda; +_Poly; +_Pow; +_Printf; +_Putfld; +_Putstr; +_Puttxt; +_Quad; +_Quadph; +_Read_enc_ptr; +_Read_sleb; +_Read_uleb; +_Readloc; +_Rint; +_Rteps; +_Scanf; +_Setloc; +_Sin; +_Sinh; +_Size_block; +_Skip; +_Snan; +_start; +_Stderr; +_Stdin; +_Stdout; +_Stod; +_Stodx; +_Stof; +_Stoflt; +_Stofx; +_Stold; +_Stoldx; +_Stoll; +_Stollx; +_Stolx; +_Stopfx; +_Stoul; +_Stoull; +_Stoullx; +_Stoulx; +_Stoxflt; +_Strcollx; +_Strerror; +_Strxfrmx; +_Tgamma; +_tolower; +_tolower_tab_; +_toupper; +_toupper_tab_; +_Towctrans; +_Ttotm; +_Tzoff; +_Unlockfilelock; +_Unlocksyslock; +_Unwind_DeleteException; +_Unwind_ForcedUnwind; +_Unwind_GetDataRelBase; +_Unwind_GetGR; +_Unwind_GetIP; +_Unwind_GetLanguageSpecificData; +_Unwind_GetRegionStart; +_Unwind_GetTextRelBase; +_Unwind_RaiseException; +_Unwind_Resume; +_Unwind_Resume_or_Rethrow; +_Unwind_SetGR; +_Unwind_SetIP; +_Vacopy; +_Valbytes; +_Wcscollx; +_Wcsftime; +_Wcsxfrmx; +_Wctob; +_Wctomb; +_Wctombx; +_WFrprep; +_WFwprep; +_WGenld; +_WGetfld; +_WGetfloat; +_WGetint; +_WGetstr; +_WLdtob; +_WLitob; +_WPrintf; +_WPutfld; +_WPutstr; +_WPuttxt; +_WScanf; +_WStod; +_WStodx; +_WStof; +_WStoflt; +_WStofx; +_WStold; +_WStoldx; +_WStoll; +_WStopfx; +_WStoul; +_WStoull; +_WStoxflt; +_Xbig; +_Xp_addh; +_Xp_addx; +_Xp_getw; +_Xp_invx; +_Xp_ldexpx; +_Xp_movx; +_Xp_mulh; +_Xp_mulx; +_Xp_setw; +_Xp_sqrtx; +_Xp_subx; +_Zero; +a64l; +abort; +abs; +access; +acos; +acosf; +acosh; +acoshf; +acoshl; +acosl; +AHB_User_Base; +ahbb; +alarm; +alarm_handler; +alarmx; +asctime; +asctime_r; +asin; +asinf; +asinh; +asinhf; +asinhl; +asinl; +atan; +atan2; +atan2f; +atan2l; +atanf; +atanh; +atanhf; +atanhl; +atanl; +atexit; +atof; +atoi; +atol; +atoll; +bcmp; +bcopy; +bsearch; +btowc; +bzero; +c16rtomb; +c32rtomb; +cabs; +cabsf; +cabsl; +cacos; +cacosf; +cacosh; +cacoshf; +cacoshl; +cacosl; +carg; +cargf; +cargl; +casin; +casinf; +casinh; +casinhf; +casinhl; +casinl; +catan; +catanf; +catanh; +catanhf; +catanhl; +catanl; +cbrt; +cbrtf; +cbrtl; +ccos; +ccosf; +ccosh; +ccoshf; +ccoshl; +ccosl; +ceil; +ceilf; +ceill; +cexp; +cexpf; +cexpl; +cimag; +cimagf; +cimagl; +clearerr; +clock; +clog; +clog10; +clog10f; +clog10l; +clogf; +clogl; +close; +closedir; +conj; +conjf; +conjl; +copysign; +copysignf; +copysignl; +cos; +cosf; +cosh; +coshf; +coshl; +cosl; +cpow; +cpowf; +cpowl; +cproj; +cprojf; +cprojl; +creal; +crealf; +creall; +create_qdouble; +create_qdouble_li; +csin; +csinf; +csinh; +csinhf; +csinhl; +csinl; +csqrt; +csqrtf; +csqrtl; +ctan; +ctanf; +ctanh; +ctanhf; +ctanhl; +ctanl; +ctime; +ctime_r; +d2qd; +dadd; +dadd_asm; +daylight; +difftime; +div; +dladdr; +dlclose; +dlerror; +dlinfo; +dlopen; +dlopenbuf; +dlsym; +dmpy; +dmpy_asm; +drand48; +drecip; +drecipsqrt; +dsub; +dsub_asm; +ecvt; +environ; +erand48; +erf; +erfc; +erfcf; +erfcl; +erff; +erfl; +err_Fatal_internal0; +execve; +exit; +exp; +exp10f; +exp2; +exp2f; +exp2l; +expf; +expl; +expm1; +expm1f; +expm1l; +fabs; +fabsf; +fabsl; +fast2_d2qd; +fast2_d2qld; +fast2_dadd; +fast2_dadd_asm; +fast2_dmpy; +fast2_dmpy_asm; +fast2_drecip; +fast2_drecipsqrt; +fast2_dsub; +fast2_dsub_asm; +fast2_f2qd; +fast2_f2qd_asm; +fast2_ldadd; +fast2_ldadd_asm; +fast2_ldmpy; +fast2_ldmpy_asm; +fast2_ldrecip; +fast2_ldrecipsqrt; +fast2_ldsub; +fast2_ldsub_asm; +fast2_qd2f; +fast2_qd2f_asm; +fast2_qld2d; +fast2_recipsqrtTable_qd; +fast2_recipsqrtTable_qld; +fast2_recipTable_qd; +fast2_recipTable_qld; +fclose; +fcntl; +fcvt; +fdim; +fdimf; +fdiml; +fdopen; +feclearexcept; +fegetenv; +fegetexceptflag; +fegetround; +fegettrapenable; +feholdexcept; +feof; +feraiseexcept; +ferror; +fesetenv; +fesetexceptflag; +fesetround; +fesettrapenable; +fetestexcept; +feupdateenv; +fflush; +ffs; +fgetc; +fgetpos; +fgets; +fgetwc; +fgetws; +fileno; +floor; +floorf; +floorl; +fma; +fmaf; +fmax; +fmaxf; +fmaxl; +fmemcpy_asm; +fmin; +fminf; +fminl; +fmod; +fmodf; +fmodl; +fopen; +fork; +fprintf; +fputc; +fputs; +fputwc; +fputws; +fread; +freopen; +frexp; +frexpf; +frexpl; +fscanf; +fseek; +fseeko; +fsetpos; +fstat; +ftell; +ftello; +ftruncate; +fwide; +fwprintf; +fwrite; +fwscanf; +gcvt; +get_exp_qd; +get_mant_qd; +getc; +getc_unlocked; +getchar; +getchar_unlocked; +getcwd; +getenv; +getopt; +getpid; +gets; +getsubopt; +gettimeofday; +getw; +getwc; +getwchar; +gmtime; +gmtime_r; +h_acosf; +h_asinf; +h_atanf; +h_cosf; +h_exp10f; +h_exp2f; +h_expf; +h_log10f; +h_log2f; +h_logf; +h_sinf; +h_tanf; +hcreate; +hdestroy; +hexagon_buffer_clean; +hexagon_buffer_cleaninv; +hexagon_buffer_inv; +hexagon_cache_cleaninv; +hexagon_cache_inva; +hexagon_memcpy_forward_vp4cp4n2; +hexagon_reg_clear_timer; +hexagon_reg_end_timer; +hexagon_reg_init_timer; +hexagon_reg_prof_off; +hexagon_reg_prof_on; +hexagon_reg_read_pcycles; +hexagon_reg_read_rev; +hexagon_reg_read_syscfg; +hexagon_reg_show_timer; +hexagon_reg_start_timer; +hsearch; +hypot; +hypotf; +hypotl; +ilogb; +ilogbf; +ilogbl; +imaxabs; +imaxdiv; +index; +isalnum; +isalpha; +isascii; +isatty; +isblank; +iscntrl; +isdigit; +isgraph; +isinf; +islower; +isnan; +isprint; +ispunct; +isspace; +isupper; +iswalnum; +iswalpha; +iswblank; +iswcntrl; +iswctype; +iswdigit; +iswgraph; +iswlower; +iswprint; +iswpunct; +iswspace; +iswupper; +iswxdigit; +isxdigit; +j0; +j1; +jn; +jrand48; +l64a; +l64a_r; +labs; +lcong48; +ldexp; +ldexpf; +ldexpl; +ldiv; +lgamma; +lgammaf; +lgammal; +llabs; +lldiv; +llrint; +llrintf; +llrintl; +llround; +llroundf; +llroundl; +localeconv; +localtime; +localtime_r; +log; +log10; +log10f; +log10l; +log1p; +log1pf; +log1pl; +log2; +log2f; +log2l; +logb; +logbf; +logbl; +logf; +logl; +longjmp; +lrand48; +lrint; +lrintf; +lrintl; +lround; +lroundf; +lroundl; +lseek; +mblen; +mbrlen; +mbrtoc16; +mbrtoc32; +mbrtowc; +mbsinit; +mbsnrtowcs; +mbsrtowcs; +mbstowcs; +mbtowc; +memccpy; +memchr; +memcmp; +memcpy; +memcpy_c; +memcpy_v; +memmove; +memmove_c; +memmove_v; +memscpy; +memset; +memset_c; +memset_s; +memset_v; +memsmove; +mkdir; +mkstemp; +mktemp; +mktime; +modf; +modff; +modfl; +mrand48; +nan; +nanf; +nanl; +nearbyint; +nearbyintf; +nearbyintl; +nextafter; +nextafterf; +nextafterl; +nexttoward; +nexttowardf; +nexttowardl; +norm; +normf; +norml; +npa_query_by_name; +nrand48; +open; +opendir; +optarg; +opterr; +optind; +optopt; +perror; +pow; +powf; +powl; +printf; +putc; +putc_unlocked; +putchar; +putchar_unlocked; +putenv; +puts; +putw; +putwc; +putwchar; +q6_buffer_clean; +q6_buffer_cleaninv; +q6_buffer_inv; +q6reg_clear_timer; +q6reg_end_timer; +q6reg_init_timer; +q6reg_prof_off; +q6reg_prof_on; +q6reg_read_pcycles; +q6reg_read_rev; +q6reg_read_syscfg; +q6reg_show_timer; +q6reg_start_timer; +qd2d; +qd_add; +qd_add_dq; +qd_add_qd; +qd_div; +qd_div_dq; +qd_div_qd; +qd_fabs; +qd_gt; +qd_gt_dq; +qd_gt_qd; +qd_lt; +qd_lt_dq; +qd_lt_qd; +qd_mul; +qd_mul_dq; +qd_mul_qd; +qd_neg; +qd_self_div; +qd_self_div_dd; +qd_self_increment; +qd_self_increment_qd; +qd_self_mul; +qd_self_mul_qd; +qd_self_sub; +qd_self_sub_dd; +qd_sqrt; +qd_sub_dq; +qd_sub_qd; +qsort; +raise; +rand; +rand_r; +read; +readdir; +recipsqrtTable_qd; +recipTable_qd; +remainder; +remainderf; +remainderl; +remove; +remquo; +remquof; +remquol; +rename; +rewind; +rindex; +rint; +rintf; +rintl; +rmdir; +rmemcpy_asm; +round; +roundf; +roundl; +sbrk; +scalb; +scalbln; +scalblnf; +scalblnl; +scalbn; +scalbnf; +scalbnl; +scanf; +seed48; +set_exp_qd; +set_mant_qd; +setbuf; +setjmp; +setlocale; +setvbuf; +signal; +sin; +sinf; +sinh; +sinhf; +sinhl; +sinl; +sleep; +snprintf; +sprintf; +sqrt; +sqrtf; +sqrtl; +srand; +srand48; +sscanf; +start; +stat; +statvfs; +strcasecmp; +strcat; +strchr; +strcmp; +strcmp_c; +strcoll; +strcpy; +strcspn; +strdup; +strerror; +strerror_r; +strftime; +strlcat; +strlcpy; +strlen; +strncasecmp; +strncat; +strncmp; +strncpy; +strpbrk; +strptime; +strrchr; +strsep; +strspn; +strstr; +strtod; +strtof; +strtoimax; +strtok; +strtok_r; +strtol; +strtold; +strtoll; +strtoul; +strtoull; +strtoumax; +strxfrm; +suboptarg; +swab; +swprintf; +swscanf; +sys_Mtxinit; +sys_Mtxlock; +sys_Mtxunlock; +sys_Tlsalloc; +sys_Tlsget; +sys_Tlsset; +sysconf; +system; +tan; +tanf; +tanh; +tanhf; +tanhl; +tanl; +tdelete; +tempnam; +tfind; +tgamma; +tgammaf; +tgammal; +time; +times; +timezone; +tmpfile; +tmpnam; +toascii; +todouble; +tolower; +toqdouble; +toupper; +towctrans; +towlower; +towupper; +trunc; +truncf; +truncl; +tsearch; +twalk; +tzname; +tzset; +u2g_client_open; +ungetc; +ungetwc; +unlink; +vasprintf; +vfprintf; +vfscanf; +vfwprintf; +vfwscanf; +vprintf; +vscanf; +vsnprintf; +vsprintf; +vsscanf; +vswprintf; +vswscanf; +vwprintf; +vwscanf; +wcrtomb; +wcscat; +wcschr; +wcscmp; +wcscoll; +wcscpy; +wcscspn; +wcsftime; +wcslen; +wcsncat; +wcsncmp; +wcsncpy; +wcsnrtombs; +wcspbrk; +wcsrchr; +wcsrtombs; +wcsspn; +wcsstr; +wcstod; +wcstof; +wcstoimax; +wcstok; +wcstol; +wcstold; +wcstoll; +wcstombs; +wcstoul; +wcstoull; +wcstoumax; +wcsxfrm; +wctob; +wctomb; +wctrans; +wctype; +wmemchr; +wmemcmp; +wmemcpy; +wmemmove; +wmemset; +wprintf; +write; +wscanf; +y0; +y1; +yn; +}; diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/qtest_stdlib.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/qtest_stdlib.h new file mode 100755 index 0000000000000..0da356fd1a46c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/qtest_stdlib.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012-2013,2021 QUALCOMM Technologies Inc. All Rights Reserved. + * Qualcomm Technologies Confidential and Proprietary + * + */ +#ifndef QTEST_STDLIB_H +#define QTEST_STDLIB_H + +#include +#include "rpcmem.h" + +#define WHILE(a) \ +__pragma(warning(suppress:4127)) while(a) + +#define FREEIF(pv) \ + do {\ + if(pv) { \ + void* tmp = (void*)pv;\ + pv = 0;\ + FREE(tmp);\ + } \ + } WHILE(0) + +#define ALIGNED_FREEIF(pv) \ + do {\ + if(pv) { \ + void* tmp = (void*)pv;\ + pv = 0;\ + ALIGNED_FREE(tmp);\ + } \ + } WHILE(0) + +#ifndef FASTRPC_DMA_FREE +#define FASTRPC_DMA_FREE(pv) rpcmem_free(pv) +#endif + +#define FASTRPC_DMA_FREEIF(pv) \ + do {\ + if(pv) { \ + void* tmp = (void*)pv;\ + pv = 0;\ + FASTRPC_DMA_FREE(tmp);\ + } \ + } WHILE(0) + +#ifndef QASSERT +#define QASSERT(st) assert(st) +#endif + +//had to copy this so not to bring in a1qtest headers +#if (((defined __linux__) && !(defined ANDROID)) || (defined __APPLE__)) +#include +#include +#include + +static __inline char* stacktrace(void) { + int bufsz = 0, sz = 0; + char* buf = 0; + void* callstack[256]; + int i, frames = backtrace(callstack, 256); + char** strs = backtrace_symbols(callstack, frames); + bufsz += snprintf(0, 0, "\n"); + for (i = 0; i < frames; ++i) { + bufsz += snprintf(0, 0, "%s\n", strs[i]); + } + buf = malloc(bufsz); + assert(buf != 0); + sz += snprintf(buf + sz, bufsz, "\n"); + bufsz -= sz; + for (i = 0; i < frames && bufsz > 0; ++i) { + sz += snprintf(buf + sz, bufsz, "%s\n", strs[i]); + bufsz -= sz; + } + free(strs); + return buf; +} + +#else + +static __inline char* stacktrace(void) { + return 0; +} + + +#endif //ANDROID + + +#ifndef QTEST +//default implementation for stdlib +#include + + +#define IF_QTEST(vv) (void)0 + +#ifndef QASSERT +#define QASSERT(st) (void)0 +#endif + +#ifndef MALLOC +#define MALLOC malloc +#endif + +#ifndef FASTRPC_DMA_MALLOC +#define FASTRPC_DMA_MALLOC(heapid, flags, size) rpcmem_alloc(heapid, flags, size) +#endif + +#ifndef CALLOC +#define CALLOC calloc +#endif + +#ifndef FREE +#define FREE free +#endif + +#ifndef REALLOC +#define REALLOC(pv, nsz, osz) realloc(pv, nsz) +#endif + +#ifndef ALIGNED_REALLOC +#define ALIGNED_REALLOC(pv, nsz, osz, aln) _aligned_realloc(pv, nsz, aln) +#endif + +#ifndef FASTRPC_DMA_REALLOC +#define FASTRPC_DMA_REALLOC(pv, nsz, osz, aln) fastrpc_dma_realloc(pv, nsz, osz) +#endif + +#ifndef ALIGNED_FREE +#define ALIGNED_FREE(pv) _aligned_free(pv) +#endif + +#define qtest_set_failure_mask(mask) (void)mask +#define qtest_get_failure_mask(mask) (void)mask +#define qtest_set_pass_count(cnt) (void)cnt +#define qtest_done() (void)0 +#define qtest_test_failure() 0 +#define qtest_atexit(pfn,ctx) (void)pfn; (void)ctx + +#else // QTEST + +#include "AEEStdDef.h" + +#define IF_QTEST(vv) do {\ + vv \ +} while (0) + +//causes alloc to fail when mask & 0x1 is true +//each test shifts the mask to the right +void qtest_set_failure_mask(uint32 mask); +void qtest_get_failure_mask(uint32* mask); + +//causes alloc to fail when count == 0 +//each test decrements the count +void qtest_set_pass_count(int count); + +//returns 0 if succeeds and shifts the mask +//usefull for generating controlled failures in functions +int qtest_test_failure(void); + +void qtest_atexit(void (*pfnAtExit)(void* pCtx), void* pvCxt); + +void qtest_done(void); + +void* qtest_malloc(const char* name, char* stack, int sz); + +void* qtest_calloc(const char* name, char* stack, int cnt, int sz); + +void* qtest_realloc(const char* name, char* stack, void* ptr, int sz); + +void qtest_free(const char* name, char* stack, void* rv); + +#define MALLOC(sz) qtest_malloc(__FILE_LINE__, stacktrace(), sz) +#define CALLOC(cnt, sz) qtest_calloc(__FILE_LINE__, stacktrace(), cnt, sz) +#define REALLOC(ptr, sz) qtest_realloc(__FILE_LINE__, stacktrace(), ptr, sz) +#define FREE(ptr) qtest_free(__FILE_LINE__, stacktrace(), ptr) + +#endif //QTEST +#endif //QTEST_STDLIB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.h new file mode 100755 index 0000000000000..be2e864346b29 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.h @@ -0,0 +1,1430 @@ +/* + * Copyright (c) 2012-2014,2016,2017,2019-2022,2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + */ +#ifndef REMOTE_H +#define REMOTE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __QAIC_REMOTE +#define __QAIC_REMOTE(ff) ff +#endif ///__QAIC_REMOTE + +#ifndef __QAIC_REMOTE_EXPORT +#ifdef _WIN32 +#ifdef _USRDLL +#define __QAIC_REMOTE_EXPORT __declspec(dllexport) +#elif defined(STATIC_LIB) +#define __QAIC_REMOTE_EXPORT /** Define for static libk */ +#else ///STATIC_LIB +#define __QAIC_REMOTE_EXPORT __declspec(dllimport) +#endif ///_USRDLL +#else +#define __QAIC_REMOTE_EXPORT +#endif ///_WIN32 +#endif ///__QAIC_REMOTE_EXPORT + +#ifndef __QAIC_RETURN +#ifdef _WIN32 +#define __QAIC_RETURN _Success_(return == 0) +#else +#define __QAIC_RETURN +#endif ///_WIN32 +#endif ///__QAIC_RETURN + +#ifndef __QAIC_IN +#ifdef _WIN32 +#define __QAIC_IN _In_ +#else +#define __QAIC_IN +#endif ///_WIN32 +#endif ///__QAIC_IN + +#ifndef __QAIC_IN_CHAR +#ifdef _WIN32 +#define __QAIC_IN_CHAR _In_z_ +#else +#define __QAIC_IN_CHAR +#endif ///_WIN32 +#endif ///__QAIC_IN_CHAR + +#ifndef __QAIC_IN_LEN +#ifdef _WIN32 +#define __QAIC_IN_LEN(len) _Inout_updates_bytes_all_(len) +#else +#define __QAIC_IN_LEN(len) +#endif ///_WIN32 +#endif ///__QAIC_IN_LEN + +#ifndef __QAIC_OUT +#ifdef _WIN32 +#define __QAIC_OUT _Out_ +#else +#define __QAIC_OUT +#endif ///_WIN32 +#endif ///__QAIC_OUT + +#ifndef __QAIC_INT64PTR +#ifdef _WIN32 +#define __QAIC_INT64PTR uintptr_t +#else +#define __QAIC_INT64PTR uint64_t +#endif ///_WIN32 +#endif ///__QAIC_INT64PTR + +#ifndef __QAIC_REMOTE_ATTRIBUTE +#define __QAIC_REMOTE_ATTRIBUTE +#endif ///__QAIC_REMOTE_ATTRIBUTE + +/** Retrieves method attribute from the scalars parameter */ +#define REMOTE_SCALARS_METHOD_ATTR(dwScalars) (((dwScalars) >> 29) & 0x7) + +/** Retrieves method index from the scalars parameter */ +#define REMOTE_SCALARS_METHOD(dwScalars) (((dwScalars) >> 24) & 0x1f) + +/** Retrieves number of input buffers from the scalars parameter */ +#define REMOTE_SCALARS_INBUFS(dwScalars) (((dwScalars) >> 16) & 0x0ff) + +/** Retrieves number of output buffers from the scalars parameter */ +#define REMOTE_SCALARS_OUTBUFS(dwScalars) (((dwScalars) >> 8) & 0x0ff) + +/** Retrieves number of input handles from the scalars parameter */ +#define REMOTE_SCALARS_INHANDLES(dwScalars) (((dwScalars) >> 4) & 0x0f) + +/** Retrieves number of output handles from the scalars parameter */ +#define REMOTE_SCALARS_OUTHANDLES(dwScalars) ((dwScalars) & 0x0f) + +/** Makes the scalar using the method attr, index and number of io buffers and handles */ +#define REMOTE_SCALARS_MAKEX(nAttr,nMethod,nIn,nOut,noIn,noOut) \ + ((((uint32_t) (nAttr) & 0x7) << 29) | \ + (((uint32_t) (nMethod) & 0x1f) << 24) | \ + (((uint32_t) (nIn) & 0xff) << 16) | \ + (((uint32_t) (nOut) & 0xff) << 8) | \ + (((uint32_t) (noIn) & 0x0f) << 4) | \ + ((uint32_t) (noOut) & 0x0f)) + +#define REMOTE_SCALARS_MAKE(nMethod,nIn,nOut) REMOTE_SCALARS_MAKEX(0,nMethod,nIn,nOut,0,0) + +/** Retrieves number of io buffers and handles */ +#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\ + REMOTE_SCALARS_OUTBUFS(sc) +\ + REMOTE_SCALARS_INHANDLES(sc) +\ + REMOTE_SCALARS_OUTHANDLES(sc)) + +/** Defines the domain IDs for supported DSPs */ +#define ADSP_DOMAIN_ID 0 +#define MDSP_DOMAIN_ID 1 +#define SDSP_DOMAIN_ID 2 +#define CDSP_DOMAIN_ID 3 +#define CDSP1_DOMAIN_ID 4 + +/** Defines the domain names for supported DSPs*/ +#define ADSP_DOMAIN_NAME "adsp" +#define MDSP_DOMAIN_NAME "mdsp" +#define SDSP_DOMAIN_NAME "sdsp" +#define CDSP_DOMAIN_NAME "cdsp" +#define CDSP1_DOMAIN_NAME "cdsp1" + +/** Defines to prepare URI for multi-domain calls */ +#define ADSP_DOMAIN "&_dom=adsp" +#define MDSP_DOMAIN "&_dom=mdsp" +#define SDSP_DOMAIN "&_dom=sdsp" +#define CDSP_DOMAIN "&_dom=cdsp" +#define CDSP1_DOMAIN "&_dom=cdsp1" + +/** Internal transport prefix */ +#define ITRANSPORT_PREFIX "'\":;./\\" + +/** Maximum length of URI for remote_handle_open() calls */ +#define MAX_DOMAIN_URI_SIZE 12 + +/** Token to specify the priority of a handle */ +#define FASTRPC_URI_PRIORITY_TOKEN "&_hpriority=" + +/** Macro to generate token string for priority */ +#define FASTRPC_HANDLE_PRIORITY_LEVEL(priority) \ + FASTRPC_URI_PRIORITY_TOKEN #priority + +/** + * The following defines are used to specify the priority level of a handle. + * Priority levels range from 1 to 7. Lower numbers indicate higher priority. + * For example, a priority of 1 indicates the highest priority while a priority + * of 7 indicates the lowest priority. + * + * If no priority level is specified, then handles are opened with highest + * priority. + */ +#define FASTRPC_HANDLE_PRIORITY_MIN 7 +#define FASTRPC_HANDLE_PRIORITY_MAX 1 + +/** Domain type for multi-domain RPC calls */ +typedef struct domain_t { + /** Domain ID */ + int id; + /** URI for remote_handle_open */ + char uri[MAX_DOMAIN_URI_SIZE]; +} domain; + +/** Remote handle parameter for RPC calls */ +typedef uint32_t remote_handle; + +/** Remote handle parameter for multi-domain RPC calls */ +typedef uint64_t remote_handle64; + +/** 32-bit Remote buffer parameter for RPC calls */ +typedef struct { + /** Address of a remote buffer */ + void *pv; + /** Size of a remote buffer */ + size_t nLen; +} remote_buf; + +/** 64-bit Remote buffer parameter for RPC calls */ +typedef struct { + /** Address of a remote buffer */ + uint64_t pv; + /** Size of a remote buffer */ + int64_t nLen; +} remote_buf64; + +/** 32-bit Remote DMA handle parameter for RPC calls */ +typedef struct { + /** File descriptor of a remote buffer */ + int32_t fd; + /** Offset of the file descriptor */ + uint32_t offset; +} remote_dma_handle; + +/** 64-bit Remote DMA handle parameter for RPC calls */ +typedef struct { + /** File descriptor of a remote buffer */ + int32_t fd; + /** Offset of the file descriptor */ + uint32_t offset; + /** Size of buffer */ + uint32_t len; +} remote_dma_handle64; + +/** 32-bit Remote Arg structure for RPC calls */ +typedef union { + /** 32-bit remote buffer */ + remote_buf buf; + /** non-domains remote handle */ + remote_handle h; + /** multi-domains remote handle */ + remote_handle64 h64; + /** 32-bit remote dma handle */ + remote_dma_handle dma; +} remote_arg; + +/** 64-bit Remote Arg structure for RPC calls */ +typedef union { + /** 64-bit remote buffer */ + remote_buf64 buf; + /** non-domains remote handle */ + remote_handle h; + /** multi-domains remote handle */ + remote_handle64 h64; + /** 64-bit remote dma handle */ + remote_dma_handle64 dma; +} remote_arg64; + +/** Async response type */ +enum fastrpc_async_notify_type { + /** No notification required */ + FASTRPC_ASYNC_NO_SYNC, + + /** Callback notification using fastrpc_async_callback */ + FASTRPC_ASYNC_CALLBACK, + + /** User will poll for the notification */ + FASTRPC_ASYNC_POLL, + +/** Update FASTRPC_ASYNC_TYPE_MAX when adding new value to this enum */ +}; + +/** Job id of Async job queued to DSP */ +typedef uint64_t fastrpc_async_jobid; + +/** Async call back response type, input structure */ +typedef struct fastrpc_async_callback { + /** Callback function for async notification */ + void (*fn)(fastrpc_async_jobid jobid, void* context, int result); + /** Current context to identify the callback */ + void *context; +}fastrpc_async_callback_t; + +/** Async descriptor to submit async job */ +typedef struct fastrpc_async_descriptor { + /** Async response type */ + enum fastrpc_async_notify_type type; + /** Job id of Async job queued to DSP */ + fastrpc_async_jobid jobid; + /** Async call back response type */ + fastrpc_async_callback_t cb; +}fastrpc_async_descriptor_t; + + +/** + * Flags used in struct remote_rpc_control_latency + * for request ID DSPRPC_CONTROL_LATENCY + * in remote handle control interface + **/ +enum remote_rpc_latency_flags { + + /** Request ID to disable QOS */ + RPC_DISABLE_QOS, + + /** Control cpu low power modes based on RPC activity in 100 ms window. + * Recommended for latency sensitive use cases. + */ + RPC_PM_QOS, + + /** DSP driver predicts completion time of a method and send CPU wake up signal to reduce wake up latency. + * Recommended for moderate latency sensitive use cases. It is more power efficient compared to pm_qos control. + */ + RPC_ADAPTIVE_QOS, + + /** + * After sending invocation to DSP, CPU will enter polling mode instead of + * waiting for a glink response. This will boost fastrpc performance by + * reducing the CPU wakeup and scheduling times. Enabled only for sync RPC + * calls. Using this option also enables PM QoS with a latency of 100 us. + */ + RPC_POLL_QOS, +}; + +/** + * Structure used for request ID `DSPRPC_CONTROL_LATENCY` + * in remote handle control interface + **/ +struct remote_rpc_control_latency { +/** Enable latency optimization techniques to meet requested latency. Use remote_rpc_latency_flags */ + uint32_t enable; + +/** + * Latency in microseconds. + * + * When used with RPC_PM_QOS or RPC_ADAPTIVE_QOS, user should pass maximum RPC + * latency that can be tolerated. It is not guaranteed that fastrpc will meet + * this requirement. 0 us latency is ignored. Recommended value is 100. + * + * When used with RPC_POLL_QOS, user needs to pass the expected execution time + * of method on DSP. CPU will poll for a DSP response for that specified duration + * after which it will timeout and fall back to waiting for a glink response. + * Max value that can be passed is 10000 (10 ms) + */ + uint32_t latency; +}; + +/** + * @struct fastrpc_capability + * @brief Argument to query DSP capability with request ID DSPRPC_GET_DSP_INFO + */ +typedef struct remote_dsp_capability { + /** @param[in] : DSP domain ADSP_DOMAIN_ID, SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID */ + uint32_t domain; + /** @param[in] : One of the DSP/kernel attributes from enum remote_dsp_attributes */ + uint32_t attribute_ID; + /** @param[out] : Result of the DSP/kernel capability query based on attribute_ID */ + uint32_t capability; +}fastrpc_capability; + + +/** + * @enum remote_dsp_attributes + * @brief Different types of DSP capabilities queried via remote_handle_control + * using DSPRPC_GET_DSP_INFO request id. + * DSPRPC_GET_DSP_INFO should only be used with remote_handle_control() as a handle + * is not needed to query DSP capabilities. + * To query DSP capabilities fill out 'domain' and 'attribute_ID' from structure + * remote_dsp_capability. DSP capability will be returned on variable 'capability'. + */ +enum remote_dsp_attributes { + /** Check if DSP supported: supported = 1, + unsupported = 0 */ + DOMAIN_SUPPORT, + + /** DSP unsigned PD support: supported = 1, + unsupported = 0 */ + UNSIGNED_PD_SUPPORT, + + /** Number of HVX 64B support */ + HVX_SUPPORT_64B, + + /** Number of HVX 128B support */ + HVX_SUPPORT_128B, + + /** Max page size allocation possible in VTCM */ + VTCM_PAGE, + + /** Number of page_size blocks available */ + VTCM_COUNT, + + /** Hexagon processor architecture version */ + ARCH_VER, + + /** HMX Support Depth */ + HMX_SUPPORT_DEPTH, + + /** HMX Support Spatial */ + HMX_SUPPORT_SPATIAL, + + /** Async FastRPC Support */ + ASYNC_FASTRPC_SUPPORT, + + /** DSP User PD status notification Support */ + STATUS_NOTIFICATION_SUPPORT , + + /** Multicast widget programming */ + MCID_MULTICAST, + + /** Mapping in extended address space on DSP */ + EXTENDED_MAP_SUPPORT, + + /** DSP support for handle priority */ + HANDLE_PRIORITY_SUPPORT , + + /** Update FASTRPC_MAX_DSP_ATTRIBUTES when adding new value to this enum */ +}; + +/** Macro for backward compatibility. Clients can compile wakelock request code + * in their app only when this is defined + */ +#define FASTRPC_WAKELOCK_CONTROL_SUPPORTED 1 + +/** + * Structure used for request ID `DSPRPC_CONTROL_WAKELOCK` + * in remote handle control interface + **/ +struct remote_rpc_control_wakelock { + /** enable control of wake lock */ + uint32_t enable; +}; + +/** + * Structure used for request ID `DSPRPC_GET_DOMAIN` + * in remote handle control interface. + * Get domain ID associated with an opened handle to remote interface of type remote_handle64. + * remote_handle64_control() returns domain for a given handle + * remote_handle_control() API returns default domain ID + */ +typedef struct remote_rpc_get_domain { + /** @param[out] : domain ID associcated with handle */ + int domain; +} remote_rpc_get_domain_t; + +/** + * Structure used for request IDs `DSPRPC_SET_PATH` and + * `DSPRPC_GET_PATH` in remote handle control interface. + */ +struct remote_control_custom_path { + /** value size including NULL char */ + int32_t value_size; + /** key used for storing the path */ + const char* path; + /** value which will be used for file operations when the corresponding key is specified in the file URI */ + char* value; +}; + +/** + * Request IDs for remote handle control interface + **/ +enum handle_control_req_id { + /** Reserved */ + DSPRPC_RESERVED, + + /** Request ID to enable/disable QOS */ + DSPRPC_CONTROL_LATENCY , + + /** Request ID to get dsp capabilites from kernel and Hexagon */ + DSPRPC_GET_DSP_INFO, + + /** Request ID to enable wakelock for the given domain */ + DSPRPC_CONTROL_WAKELOCK, + + /** Request ID to get the default domain or domain associated to an exisiting handle */ + DSPRPC_GET_DOMAIN, + + /** Request ID to add a custom path to the hash table */ + DSPRPC_SET_PATH, + + /** Request ID to read a custom path to the hash table */ + DSPRPC_GET_PATH, + +}; + +/** + * Structure used for request ID `FASTRPC_THREAD_PARAMS` + * in remote session control interface + **/ +struct remote_rpc_thread_params { + /** Remote subsystem domain ID, pass -1 to set params for all domains */ + int domain; + /** User thread priority (1 to 255), pass -1 to use default */ + int prio; + /** User thread stack size, pass -1 to use default */ + int stack_size; +}; + +/** + * Structure used for request ID `DSPRPC_CONTROL_UNSIGNED_MODULE` + * in remote session control interface + **/ +struct remote_rpc_control_unsigned_module { + /** Remote subsystem domain ID, -1 to set params for all domains */ + int domain; + /** Enable unsigned module loading */ + int enable; +}; + +/** + * Structure used for request ID `FASTRPC_RELATIVE_THREAD_PRIORITY` + * in remote session control interface + **/ +struct remote_rpc_relative_thread_priority { + /** Remote subsystem domain ID, pass -1 to update priority for all domains */ + int domain; + /** the value by which the default thread priority needs to increase/decrease + * DSP thread priorities run from 1 to 255 with 1 being the highest thread priority. + * So a negative relative thread priority value will 'increase' the thread priority, + * a positive value will 'decrease' the thread priority. + */ + int relative_thread_priority; +}; + +/** + * When a remote invocation does not return, + * then call "remote_session_control" with FASTRPC_REMOTE_PROCESS_KILL requestID + * and the appropriate remote domain ID. Once remote process is successfully + * killed, before attempting to create new session, user is expected to + * close all open handles for shared objects in case of domains. + * And, user is expected to unload all shared objects including + * libcdsprpc.so/libadsprpc.so/libmdsprpc.so/libsdsprpc.so in case of non-domains. + */ +struct remote_rpc_process_clean_params { + /** Domain ID to recover process */ + int domain; +}; + +/** + * Structure used for request ID `FASTRPC_SESSION_CLOSE` + * in remote session control interface + **/ +struct remote_rpc_session_close { + /** Remote subsystem domain ID, -1 to close all handles for all domains */ + int domain; +}; + +/** + * Structure used for request ID `FASTRPC_CONTROL_PD_DUMP` + * in remote session control interface + * This is used to enable/disable PD dump for userPDs on the DSP + **/ +struct remote_rpc_control_pd_dump { + /** Remote subsystem domain ID, -1 to set params for all domains */ + int domain; + /** Enable PD dump of user PD on the DSP */ + int enable; +}; + +/** + * Structure used for request ID `FASTRPC_REMOTE_PROCESS_EXCEPTION` + * in remote session control interface + * This is used to trigger exception in the userPDs running on the DSP + **/ +typedef struct remote_rpc_process_clean_params remote_rpc_process_exception; + +/** + * Process types + * Return values for FASTRPC_REMOTE_PROCESS_TYPE control req ID for remote_handle_control + * Return values denote the type of process on remote subsystem +**/ +enum fastrpc_process_type { + /** Signed PD running on the DSP */ + PROCESS_TYPE_SIGNED, + + /** Unsigned PD running on the DSP */ + PROCESS_TYPE_UNSIGNED, + +}; + +/** + * Structure for remote_session_control, + * used with FASTRPC_REMOTE_PROCESS_TYPE request ID + * to query the type of PD running defined by enum fastrpc_process_type + * @param[in] : Domain of process + * @param[out] : Process_type belonging to enum fastrpc_process_type + */ +struct remote_process_type { + /** @param[in] : Domain of process */ + int domain; + /** @param[out] : Process_type belonging to enum fastrpc_process_type */ + int process_type; +}; + +/** + * DSP user PD status notification flags + * Status flags for the user PD on the DSP returned by the status notification function + * +**/ +typedef enum remote_rpc_status_flags { + /** DSP user process is up */ + FASTRPC_USER_PD_UP, + + /** DSP user process exited */ + FASTRPC_USER_PD_EXIT, + + /** DSP user process forcefully killed. Happens when DSP resources needs to be freed. */ + FASTRPC_USER_PD_FORCE_KILL, + + /** Exception in the user process of DSP. */ + FASTRPC_USER_PD_EXCEPTION, + + /** Subsystem restart of the DSP, where user process is running. */ + FASTRPC_DSP_SSR, + +} remote_rpc_status_flags_t; + +/** + * fastrpc_notif_fn_t + * Notification call back function + * + * @param context, context used in the registration + * @param domain, domain of the user process + * @param session, session id of user process + * @param status, status of user process + * @retval, 0 on success + */ +typedef int (*fastrpc_notif_fn_t)(void *context, int domain, int session, remote_rpc_status_flags_t status); + + +/** + * Structure for remote_session_control, + * used with FASTRPC_REGISTER_STATUS_NOTIFICATIONS request ID + * to receive status notifications of the user PD on the DSP +**/ +typedef struct remote_rpc_notif_register { + /** @param[in] : Context of the client */ + void *context; + /** @param[in] : DSP domain ADSP_DOMAIN_ID, SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID */ + int domain; + /** @param[in] : Notification function pointer */ + fastrpc_notif_fn_t notifier_fn; +} remote_rpc_notif_register_t; + +/** + * Structure for remote_session_control, + * used with FASTRPC_PD_INITMEM_SIZE request ID + * to set signed userpd initial memory size + **/ +struct remote_rpc_pd_initmem_size { + /** Remote subsystem domain ID, pass -1 to set params for all domains **/ + int domain; + /** Initial memory allocated for remote userpd, minimum value : 3MB, maximum value 200MB **/ + /** Unsupported for unsigned user PD, for unsigned user PD init mem size is fixed at 5MB **/ + uint32_t pd_initmem_size; +}; + +/** + * Structure for remote_session_control, + * used with FASTRPC_RESERVE_SESSION request ID + * to reserve new fastrpc session of the user PD on the DSP. + * Default sesion is always 0 and remains available for any module opened without Session ID. + * New session reservation starts with session ID 1. +**/ +typedef struct remote_rpc_reserve_new_session { + /** @param[in] : Domain name of DSP, on which session need to be reserved */ + char *domain_name; + /** @param[in] : Domain name length, without NULL character */ + uint32_t domain_name_len; + /** @param[in] : Session name of the reserved sesssion */ + char *session_name; + /** @param[in] : Session name length, without NULL character */ + uint32_t session_name_len; + /** @param[out] : Effective Domain ID is the identifier of the session. + * Effective Domain ID is the unique identifier representing the session(PD) on DSP. + * Effective Domain ID needs to be used in place of Domain ID when application has multiple sessions. + */ + uint32_t effective_domain_id; + /** @param[out] : Session ID of the reserved session. + * An application can have multiple sessions(PDs) created on DSP. + * session_id 0 is the default session. Clients can reserve session starting from 1. + * Currently only 2 sessions are supported session_id 0 and session_id 1. + */ + uint32_t session_id; +} remote_rpc_reserve_new_session_t; + +/** + * Structure for remote_session_control, + * used with FASTRPC_GET_EFFECTIVE_DOMAIN_ID request ID + * to get effective domain id of fastrpc session on the user PD of the DSP +**/ +typedef struct remote_rpc_effective_domain_id { + /** @param[in] : Domain name of DSP */ + char *domain_name; + /** @param[in] : Domain name length, without NULL character */ + uint32_t domain_name_len; + /** @param[in] : Session ID of the reserved session. 0 can be used for Default session */ + uint32_t session_id; + /** @param[out] : Effective Domain ID of session */ + uint32_t effective_domain_id; +} remote_rpc_effective_domain_id_t; + +/** + * Structure for remote_session_control, + * used with FASTRPC_GET_URI request ID + * to get the URI needed to load the module in the fastrpc user PD on the DSP +**/ +typedef struct remote_rpc_get_uri { + /** @param[in] : Domain name of DSP */ + char *domain_name; + /** @param[in] : Domain name length, without NULL character */ + uint32_t domain_name_len; + /** @param[in] : Session ID of the reserved session. 0 can be used for Default session */ + uint32_t session_id; + /** @param[in] : URI of the module, found in the auto-generated header file*/ + char *module_uri ; + /** @param[in] : Module URI length, without NULL character */ + uint32_t module_uri_len; + /** @param[out] : URI containing module, domain and session. + * Memory for uri need to be pre-allocated with session_uri_len size. + * Typically session_uri_len is 30 characters more than Module URI length. + * If size of uri is beyond session_uri_len, remote_session_control fails with AEE_EBADSIZE + */ + char *uri ; + /** @param[in] : URI length */ + uint32_t uri_len; +} remote_rpc_get_uri_t; + +/** + * Structure for remote_session_control, used with FASTRPC_CONTEXT_CREATE request, + * to create a multidomain fastrpc context +**/ +typedef struct fastrpc_context_create { + /** @param[in] : List of effective domain IDs on which session needs to be + created. Needs to be allocated and populated by user. + A new effective domain id CANNOT be added to an existing context. */ + uint32_t *effec_domain_ids; + + /** @param[in] : Number of domain ids. + Size of effective domain ID array. */ + uint32_t num_domain_ids; + + /** @param[in] : Type of create request (unused) */ + uint64_t flags; + + /** @param[out] : Multi-domain context handle */ + uint64_t ctx; +} fastrpc_context_create; + +/** struct to be used with FASTRPC_CONTEXT_DESTROY request ID */ +typedef struct fastrpc_context_destroy { + /** @param[in] : Fastrpc multi-domain context */ + uint64_t ctx; + + /** @param[in] : Type of destroy request (unused) */ + uint64_t flags; +} fastrpc_context_destroy; + +/** + * Structure used for request ID `FASTRPC_MAX_THREAD_PARAM` + * in remote session control interface, to set max threads for + * unsigned PD. + **/ +struct remote_rpc_set_max_thread { +/** @param[in] : CDSP_DOMAIN_ID */ + int domain; +/** @param[in] : Max thread config for unsigned PD Minimum value : 128, maximum value 256. */ + unsigned int max_num_threads; +}; + +/** + * Request IDs for remote session control interface + **/ +enum session_control_req_id { + /** Reserved */ + FASTRPC_RESERVED_1, + + /** Set thread parameters like priority and stack size */ + FASTRPC_THREAD_PARAMS, + + /** Handle the unsigned module offload request, to be called before remote_handle_open() */ + DSPRPC_CONTROL_UNSIGNED_MODULE, + + /** Reserved */ + FASTRPC_RESERVED_2, + + /** To increase/decrease default thread priority */ + FASTRPC_RELATIVE_THREAD_PRIORITY, + + /** Reserved */ + FASTRPC_RESERVED_3, + + /** Kill remote process */ + FASTRPC_REMOTE_PROCESS_KILL, + + /** Close all open handles of requested domain */ + FASTRPC_SESSION_CLOSE, + + /** Enable PD dump feature */ + FASTRPC_CONTROL_PD_DUMP, + + /** Trigger Exception in the remote process */ + FASTRPC_REMOTE_PROCESS_EXCEPTION, + + /** Query type of process defined by enum fastrpc_process_type */ + FASTRPC_REMOTE_PROCESS_TYPE, + + /** Enable DSP User process status notifications */ + FASTRPC_REGISTER_STATUS_NOTIFICATIONS, + + /** Set signed userpd initial memory size */ + FASTRPC_PD_INITMEM_SIZE, + + /** Reserve new FastRPC session */ + FASTRPC_RESERVE_NEW_SESSION, + + /** Get effective domain ID of a FastRPC session */ + FASTRPC_GET_EFFECTIVE_DOMAIN_ID, + + /** Creates the URI needed to load a module in the DSP User PD */ + FASTRPC_GET_URI, + + /** Set max thread value for unsigned PD */ + FASTRPC_MAX_THREAD_PARAM, + + /** Create or attaches to remote session(s) on one or more domains */ + FASTRPC_CONTEXT_CREATE, + + /** Destroy or detach from remote sessions */ + FASTRPC_CONTEXT_DESTROY, +}; + + +/** + * Memory map control flags for using with remote_mem_map() and remote_mem_unmap() + **/ +enum remote_mem_map_flags { +/** + * Create static memory map on remote process with default cache configuration (writeback). + * Same remoteVirtAddr will be assigned on remote process when fastrpc call made with local virtual address. + * @Map lifetime + * Life time of this mapping is until user unmap using remote_mem_unmap or session close. + * No reference counts are used. Behavior of mapping multiple times without unmap is undefined. + * @Cache maintenance + * Driver clean caches when virtual address passed through RPC calls defined in IDL as a pointer. + * User is responsible for cleaning cache when remoteVirtAddr shared to DSP and accessed out of fastrpc method invocations on DSP. + * @recommended usage + * Map buffers which are reused for long time or until session close. This helps to reduce fastrpc latency. + * Memory shared with remote process and accessed only by DSP. + */ + REMOTE_MAP_MEM_STATIC, + +/** Update REMOTE_MAP_MAX_FLAG when adding new value to this enum **/ + }; + +/** + * @enum fastrpc_map_flags for fastrpc_mmap and fastrpc_munmap + * @brief Types of maps with cache maintenance + */ +enum fastrpc_map_flags { + /** + * Map memory pages with RW- permission and CACHE WRITEBACK. + * Driver will clean cache when buffer passed in a FastRPC call. + * Same remote virtual address will be assigned for subsequent + * FastRPC calls. + */ + FASTRPC_MAP_STATIC, + + /** Reserved for compatibility with deprecated flag */ + FASTRPC_MAP_RESERVED, + + /** + * Map memory pages with RW- permission and CACHE WRITEBACK. + * Mapping tagged with a file descriptor. User is responsible for + * maintenance of CPU and DSP caches for the buffer. Get virtual address + * of buffer on DSP using HAP_mmap_get() and HAP_mmap_put() functions. + */ + FASTRPC_MAP_FD, + + /** + * Mapping delayed until user calls HAP_mmap() and HAP_munmap() + * functions on DSP. User is responsible for maintenance of CPU and DSP + * caches for the buffer. Delayed mapping is useful for users to map + * buffer on DSP with other than default permissions and cache modes + * using HAP_mmap() and HAP_munmap() functions. + */ + FASTRPC_MAP_FD_DELAYED, + + /** Reserved for compatibility **/ + FASTRPC_MAP_RESERVED_4, + FASTRPC_MAP_RESERVED_5, + FASTRPC_MAP_RESERVED_6, + FASTRPC_MAP_RESERVED_7, + FASTRPC_MAP_RESERVED_8, + FASTRPC_MAP_RESERVED_9, + FASTRPC_MAP_RESERVED_10, + FASTRPC_MAP_RESERVED_11, + FASTRPC_MAP_RESERVED_12, + FASTRPC_MAP_RESERVED_13, + FASTRPC_MAP_RESERVED_14, + FASTRPC_MAP_RESERVED_15, + + /** + * This flag is used to skip CPU mapping, + * otherwise behaves similar to FASTRPC_MAP_FD_DELAYED flag. + */ + FASTRPC_MAP_FD_NOMAP, + + /** + * The below two flags work the same as FASTRPC_MAP_FD and FASTRPC_MAP_FD_DELAYED + * but allow the user to map into the extended address space on DSP + */ + + FASTRPC_MAP_FD_EXTENDED, + FASTRPC_MAP_FD_DELAYED_EXTENDED, + + /** Update FASTRPC_MAP_MAX when adding new value to this enum **/ +}; + +#define MAX_DOMAIN_NAMELEN 30 + +/* Position of domain type in flags */ +#define DOMAINS_LIST_FLAGS_TYPE_POS 5 + +/* Helper macro to set domain type in flags */ +#define DOMAINS_LIST_FLAGS_SET_TYPE(flags, type) (flags | (type & ((1 << DOMAINS_LIST_FLAGS_TYPE_POS) - 1))) + +/** + * @enum fastrpc_domain_type + * @brief Indicates the type of domains (DSPs) present in the system + */ +typedef enum { + /** Flag to be used to query list of all available domains */ + ALL_DOMAINS, + NSP, + LPASS, + SDSP, + MODEM, + HPASS, +} fastrpc_domain_type; + +/** + * @struct fastrpc_domain + * @brief Describes the details of each domain + */ +typedef struct { + /** + * @param : Logical domain id of the dsp. + * This can be used to query the capabilities of the dsp and + * can change with every reboot of device depending on the order + * of domain enumeration. + * This is NOT the same as effective domain id. To get the effective + * domain id of a particular session on this domain, pass the corresponding + * domain name with the `FASTRPC_GET_EFFECTIVE_DOMAIN_ID` request. + */ + int id; + + /** + * @param : Name of domain. + * To be appended with module uri while opening remote handle, + * or for querying the effective domain id on a specific session + * on this domain. + */ + char name[MAX_DOMAIN_NAMELEN]; + + /** + * @param : Type of DSP, of 'fastrpc_domain_type'. + */ + fastrpc_domain_type type; + + /** + * @param : Status of domain: 0 if domain is down + * non-zero if domain is up + */ + int status; + + /** + * @param : Card on which domain is present (for future use). + */ + uint32_t card; + + /** + * @param : SoC on which domain is present (for future use). + */ + uint32_t soc_id; +} fastrpc_domain; + +/** + * @struct fastrpc_domain_info + * @brief Structure used with 'FASTRPC_GET_DOMAINS' request id + * to query the list of available domains in the system. + */ +typedef struct { + /** + * @param[in/out] : Domains-info array pointer. + * Array needs to be allocated by client with size of array specified + * in 'max_domains'. Array will be populated by fastrpc with list of + * available domains. + * To query number of domains first, pass NULL pointer. + */ + fastrpc_domain *domains; + + /** + * @param[in] : Size of the 'domains' array allocated by user. + * This has to be greater than or equal to the actual number of available + * domains. To query number of domains first, pass 0 in this field. + */ + int max_domains; + + /** + * @param[out] : This field will be populated with the total number + * of available domains. While reading the domains-info in the array, + * read only until 'num_domains' elements. + */ + int num_domains; + + /** + * @param[in] : Bit-mask for the type of request, to be populated by client. + * Bits 0-4 : Type of domains to be queried of 'fastrpc_domain_type'. + * Only domains of this type will be returned in the 'domains' array. + * To get list of all available domains, use 'ALL_DOMAINS' type. + * Other bits reserved for future use. + */ + uint64_t flags; +} fastrpc_domains_info; + +/** + * @enum system_req_id + * @brief Requst ID to obtain information of available domains + */ +typedef enum { + /** Query list of available domains */ + FASTRPC_GET_DOMAINS = 0 +} system_req_id; + +/** + * @struct system_req_payload + * @brief Payload for remote_system_request API + */ +typedef struct { + system_req_id id; + union { + fastrpc_domains_info sys; + }; +} system_req_payload; + +/** + * remote_system_request + * API to get system info like list of available domains + * @param req, payload containing system info and request ID + * @return, 0 on Success + */ +int remote_system_request(system_req_payload *req); + +/** + * Attributes for remote_register_buf_attr/remote_register_buf_attr2 + **/ +#define FASTRPC_ATTR_NONE 0 /** No attribute to set.*/ +#define FASTRPC_ATTR_NON_COHERENT 2 /** Attribute to map a buffer as dma non-coherent, + Driver perform cache maintenance.*/ +#define FASTRPC_ATTR_COHERENT 4 /** Attribute to map a buffer as dma coherent, + Driver skips cache maintenenace + It will be ignored if a device is marked as dma-coherent in device tree.*/ +#define FASTRPC_ATTR_KEEP_MAP 8 /** Attribute to keep the buffer persistant + until unmap is called explicitly.*/ +#define FASTRPC_ATTR_NOMAP 16 /** Attribute for secure buffers to skip + smmu mapping in fastrpc driver*/ +#define FASTRPC_ATTR_FORCE_NOFLUSH 32 /** Attribute to map buffer such that flush by driver is skipped for that particular buffer + client has to perform cache maintenance*/ +#define FASTRPC_ATTR_FORCE_NOINVALIDATE 64 /** Attribute to map buffer such that invalidate by driver is skipped for that particular buffer + client has to perform cache maintenance */ +#define FASTRPC_ATTR_TRY_MAP_STATIC 128 /** Attribute for persistent mapping a buffer + to remote DSP process during buffer registration + with FastRPC driver. This buffer will be automatically + mapped during fastrpc session open and unmapped either + at unregister or session close. FastRPC library tries + to map buffers and ignore errors in case of failure. + pre-mapping a buffer reduces the FastRPC latency. + This flag is recommended only for buffers used with + latency critical rpc calls */ + + +/** + * REMOTE_MODE_PARALLEL used with remote_set_mode + * This is the default mode for the driver. While the driver is in parallel + * mode it will try to invalidate output buffers after it transfers control + * to the dsp. This allows the invalidate operations to overlap with the + * dsp processing the call. This mode should be used when output buffers + * are only read on the application processor and only written on the aDSP. + */ +#define REMOTE_MODE_PARALLEL 0 + +/** + * REMOTE_MODE_SERIAL used with remote_set_mode + * When operating in SERIAL mode the driver will invalidate output buffers + * before calling into the dsp. This mode should be used when output + * buffers have been written to somewhere besides the aDSP. + */ +#define REMOTE_MODE_SERIAL 1 + + +#ifdef _WIN32 +#include "remote_wos_ext.h" /** For function pointers of remote APIs */ +#endif + + +/** + * remote_handle()_open + * Opens a remote_handle "name" + * returns 0 on success + **/ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle_open)(__QAIC_IN_CHAR const char* name, __QAIC_OUT remote_handle *ph) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle64_open)( __QAIC_IN_CHAR const char* name, __QAIC_OUT remote_handle64 *ph) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * invokes the remote handle + * see retrive macro's on dwScalars format + * pra, contains the arguments in the following order, inbufs, outbufs, inhandles, outhandles. + * implementors should ignore and pass values asis that the transport doesn't understand. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle_invoke)(__QAIC_IN remote_handle h, __QAIC_IN uint32_t dwScalars, __QAIC_IN remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle64_invoke)(__QAIC_IN remote_handle64 h, __QAIC_IN uint32_t dwScalars, __QAIC_IN remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_handle()_close + * closes the remote handle + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle_close)(__QAIC_IN remote_handle h) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle64_close)(__QAIC_IN remote_handle64 h) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_handle_control + * Set remote handle control parameters + * + * @param req, request ID defined by handle_control_req_id + * @param data, address of structure with parameters + * @param datalen, length of data + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle_control)(__QAIC_IN uint32_t req, __QAIC_IN_LEN(datalen) void* data, __QAIC_IN uint32_t datalen) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle64_control)(__QAIC_IN remote_handle64 h, __QAIC_IN uint32_t req, __QAIC_IN_LEN(datalen) void* data, __QAIC_IN uint32_t datalen) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_session_control + * Set remote session parameters + * + * @param req, request ID + * @param data, address of structure with parameters + * @param datalen, length of data + * @retval, 0 on success + * remote_session_control with FASTRPC_REMOTE_PROCESS_KILL req ID, possible error codes + * are AEE_ENOSUCH, AEE_EBADPARM, AEE_EINVALIDDOMAIN. Other than this errors codes treated as + * retuned from fastRPC framework. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_session_control)(__QAIC_IN uint32_t req, __QAIC_IN_LEN(datalen) void *data, __QAIC_IN uint32_t datalen) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_handle()_invoke_async + * invokes the remote handle asynchronously + * + * desc, descriptor contains type of asyncjob. context and call back function(if any) + * see retrive macro's on dwScalars format + * pra, contains the arguments in the following order, inbufs, outbufs, inhandles, outhandles. + * all outbufs need to be either allocated using rpcmem_alloc or registered ION buffers using register_buf + * implementors should ignore and pass values as is that the transport doesn't understand. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle_invoke_async)(__QAIC_IN remote_handle h, __QAIC_IN fastrpc_async_descriptor_t *desc, __QAIC_IN uint32_t dwScalars, __QAIC_IN remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_handle64_invoke_async)(__QAIC_IN remote_handle64 h, __QAIC_IN fastrpc_async_descriptor_t *desc, __QAIC_IN uint32_t dwScalars, __QAIC_IN remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * fastrpc_async_get_status + * Get status of Async job. This can be used to query the status of a Async job + * + * @param jobid, jobid returned during Async job submission. + * @param timeout_us, timeout in micro seconds + * timeout = 0, returns immediately with status/result + * timeout > 0, waits for specified time and then returns with status/result + * timeout < 0. waits indefinetely until job completes + * @param result, integer pointer for the result of the job + * 0 on success + * error code on failure + * @retval, 0 on job completion and result of job is part of @param result + * AEE_EBUSY, if job status is pending and is not returned from DSP + * AEE_EBADPARM, if job id is invalid + * AEE_EFAILED, FastRPC internal error + * + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(fastrpc_async_get_status)(__QAIC_IN fastrpc_async_jobid jobid,__QAIC_IN int timeout_us,__QAIC_OUT int *result); + + +/** + * fastrpc_release_async_job + * Release Async job after receiving status either through callback/poll + * + * @param jobid, jobid returned during Async job submission. + * @retval, 0 on success + * AEE_EBUSY, if job status is pending and is not returned from DSP + * AEE_EBADPARM, if job id is invalid + * + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(fastrpc_release_async_job)(__QAIC_IN fastrpc_async_jobid jobid); + + +/** + * remote_mmap + * map memory to the remote domain + * + * @param fd, fd assosciated with this memory + * @param flags, flags to be used for the mapping + * @param vaddrin, input address + * @param size, size of buffer + * @param vaddrout, output address + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_mmap)(__QAIC_IN int fd, __QAIC_IN uint32_t flags, __QAIC_IN uint32_t vaddrin, __QAIC_IN int size, __QAIC_OUT uint32_t* vaddrout) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_munmap + * unmap memory from the remote domain + * + * @param vaddrout, remote address mapped + * @param size, size to unmap. Unmapping a range partially may not be supported. + * @retval, 0 on success, may fail if memory is still mapped + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_munmap)(__QAIC_IN uint32_t vaddrout, __QAIC_IN int size) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_mem_map + * Map memory to the remote process on a selected DSP domain + * + * @domain: DSP domain ID. Use -1 for using default domain. + * Default domain is selected based on library lib(a/m/s/c)dsprpc.so library linked to application. + * @fd: file descriptor of memory + * @flags: enum remote_mem_map_flags type of flag + * @virtAddr: virtual address of buffer + * @size: buffer length + * @remoteVirtAddr[out]: remote process virtual address + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_mem_map)(__QAIC_IN int domain, __QAIC_IN int fd, __QAIC_IN int flags, __QAIC_IN uint64_t virtAddr, __QAIC_IN size_t size, __QAIC_OUT uint64_t* remoteVirtAddr) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_mem_unmap + * Unmap memory to the remote process on a selected DSP domain + * + * @domain: DSP domain ID. Use -1 for using default domain. Get domain from multi-domain handle if required. + * @remoteVirtAddr: remote process virtual address received from remote_mem_map + * @size: buffer length + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_mem_unmap)(__QAIC_IN int domain, __QAIC_IN uint64_t remoteVirtAddr, __QAIC_IN size_t size) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_mmap64 + * map memory to the remote domain + * + * @param fd, fd associated with this memory + * @param flags, flags to be used for the mapping + * @param vaddrin, input address + * @param size, size of buffer + * @param vaddrout, output address + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_mmap64)(__QAIC_IN int fd, __QAIC_IN uint32_t flags, __QAIC_IN __QAIC_INT64PTR vaddrin, __QAIC_IN int64_t size, __QAIC_OUT __QAIC_INT64PTR *vaddrout) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_munmap64 + * unmap memory from the remote domain + * + * @param vaddrout, remote address mapped + * @param size, size to unmap. Unmapping a range partially may not be supported. + * @retval, 0 on success, may fail if memory is still mapped + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_munmap64)(__QAIC_IN __QAIC_INT64PTR vaddrout, __QAIC_IN int64_t size) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * fastrpc_mmap + * Creates a mapping on remote process for an ION buffer with file descriptor. New fastrpc session + * will be opened if not already opened for the domain. + * + * @param domain, DSP domain ID of a fastrpc session + * @param fd, ION memory file descriptor + * @param addr, buffer virtual address on cpu + * @param offset, offset from the beginning of the buffer + * @param length, size of buffer in bytes + * @param flags, controls mapping functionality on DSP. Refer fastrpc_map_flags enum definition for more information. + * + * @return, 0 on success, error code on failure. + * AEE_EALREADY Buffer already mapped. Multiple mappings for the same buffer are not supported. + * AEE_EBADPARM Bad parameters + * AEE_EFAILED Failed to map buffer + * AEE_ENOMEMORY Out of memory (internal error) + * AEE_EUNSUPPORTED Unsupported API on the target + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(fastrpc_mmap)(__QAIC_IN int domain, __QAIC_IN int fd, __QAIC_IN void *addr, __QAIC_IN int offset, __QAIC_IN size_t length, __QAIC_IN enum fastrpc_map_flags flags)__QAIC_REMOTE_ATTRIBUTE; + + +/** + * fastrpc_munmap + * Removes a mapping associated with file descriptor. + * + * @param domain, DSP domain ID of a fastrpc session + * @param fd, file descriptor + * @param addr, buffer virtual address used for mapping creation + * @param length, buffer length + * + * @return, 0 on success, error code on failure. + * AEE_EBADPARM Bad parameters + * AEE_EINVALIDFD Mapping not found for specified fd + * AEE_EFAILED Failed to map buffer + * AEE_EUNSUPPORTED Unsupported API on the target + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(fastrpc_munmap)(__QAIC_IN int domain, __QAIC_IN int fd, __QAIC_IN void *addr, __QAIC_IN size_t length)__QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_register_buf/remote_register_buf_attr + * Register a file descriptor for a buffer. + * Users of fastrpc should register zero-copy buffer to enable + * sharing that buffer to the dsp via the SMMU. The API is limited + * to register buffer less than 2 GB only. Recommendation is to use + * remote_register_buf_attr2 instead. API remote_register_buf_attr2 + * can now accept size up to 2 power(8*sizeof(size_t)). + * + * Some versions of libcdsprpc.so lack this + * function, so users should set this symbol as weak. + * + * #pragma weak remote_register_buf + * #pragma weak remote_register_buf_attr + * + * @param buf, virtual address of the buffer + * @param size, size of the buffer + * @fd, the file descriptor, callers can use -1 to deregister. + * @attr, map buffer as coherent or non-coherent + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN void __QAIC_REMOTE(remote_register_buf)(__QAIC_IN_LEN(size) void* buf, __QAIC_IN int size, __QAIC_IN int fd) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN void __QAIC_REMOTE(remote_register_buf_attr)(__QAIC_IN_LEN(size) void* buf, __QAIC_IN int size, __QAIC_IN int fd, __QAIC_IN int attr) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_register_buf_attr2 + * Register a file descriptor for a buffer. Users of fastrpc should + * register zero-copy buffer to enable sharing that buffer to the + * dsp via the SMMU. + * + * Some versions of libcdsprpc.so lack this + * function, so users should set this symbol as weak. + * + * #pragma weak remote_register_buf_attr2 + * + * @param buf, virtual address of the buffer + * @param size, size of the buffer + * @fd, the file descriptor, callers can use -1 to deregister. + * @attr, setting attribute for the mapped buffer + * refer to "Attributes for remote_register_buf_attr/remote_register_buf_attr2" + * to set the required attribute value. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN void __QAIC_REMOTE(remote_register_buf_attr2)(__QAIC_IN_LEN(size) void* buf, __QAIC_IN size_t size, __QAIC_IN int fd, __QAIC_IN int attr) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_register_dma_handle/remote_register_dma_handle_attr + * Register a dma handle with fastrpc. + * This is only valid on Android with ION allocated memory. + * Users of fastrpc should register a file descriptor allocated with + * ION to enable sharing that memory to the dsp via the SMMU. + * + * Some versions of libadsprpc.so lack this function, + * so users should set this symbol as weak. + * + * #pragma weak remote_register_dma_handle + * #pragma weak remote_register_dma_handle_attr + * + * @fd, the file descriptor, callers can use -1 to deregister. + * @param len, size of the buffer + * @attr, map buffer as coherent or non-coherent or no-map + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_register_dma_handle)(__QAIC_IN int fd,__QAIC_IN uint32_t len) __QAIC_REMOTE_ATTRIBUTE; +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_register_dma_handle_attr)(__QAIC_IN int fd,__QAIC_IN uint32_t len,__QAIC_IN uint32_t attr) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_set_mode + * Set the mode of operation. + * + * Some versions of libadsprpc.so lack this function, + * so users should set this symbol as weak. + * + * #pragma weak remote_set_mode + * + * @param mode, the mode + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN int __QAIC_REMOTE(remote_set_mode)(__QAIC_IN uint32_t mode) __QAIC_REMOTE_ATTRIBUTE; + + +/** + * remote_register_fd + * Register a file descriptor. + * This can be used when users do not have a mapping to pass to the + * RPC layer. The generated address is a mapping with PROT_NONE, any + * access to this memory will fail, so it should only be used as an + * ID to identify this file descriptor to the RPC layer. This API is + * limited to buffer size less then 2 GB. Recommendation is to use + * remote_register_fd2 for buffer of size > 2 power(8*sizeof(size_t)). + * + * To deregister use remote_register_buf(addr, size, -1). + * + * #pragma weak remote_register_fd + * + * @param fd, the file descriptor. + * @param size, size to of the buffer + * @retval, (void*)-1 on failure, address on success. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN void *__QAIC_REMOTE(remote_register_fd)(__QAIC_IN int fd,__QAIC_IN int size) __QAIC_REMOTE_ATTRIBUTE; + +/** + * remote_register_fd2 + * Register a file descriptor. + * This can be used when users do not have a mapping to pass to + * the RPC layer. The generated address is a mapping with PROT_NONE, + * any access to this memory will fail, so it should only be used + * as an ID to identify this file descriptor to the RPC layer. + * + * To deregister use remote_register_buf(addr, size, -1). + * + * #pragma weak remote_register_fd2 + * + * @param fd, the file descriptor. + * @param size, size to of the buffer + * @retval, (void*)-1 on failure, address on success. + */ +__QAIC_REMOTE_EXPORT __QAIC_RETURN void *__QAIC_REMOTE(remote_register_fd2)(__QAIC_IN int fd,__QAIC_IN size_t size) __QAIC_REMOTE_ATTRIBUTE; + + +#ifdef __cplusplus +} +#endif + +#endif /// REMOTE_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.idl b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.idl new file mode 100755 index 0000000000000..65e5b162660b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.idl @@ -0,0 +1,32 @@ +interface remote_handle64 { + /** + * Opens the handle in the specified domain. If this is the first + * handle, this creates the session. Typically this means opening + * the device, aka open("/dev/adsprpc-smd"), then calling ioctl + * device APIs to create a PD on the DSP to execute our code in, + * then asking that PD to dlopen the .so and dlsym the skel function. + * + * @param uri, _URI"&_dom=aDSP" + * _URI is a QAIC generated uri, or + * "file:///?_skel_handle_invoke&_modver=1.0" + * If the _dom parameter is not present, _dom=DEFAULT is assumed + * but not forwarded. + * Reserved uri keys: + * [0]: first unamed argument is the skel invoke function + * _dom: execution domain name, _dom=mDSP/aDSP/DEFAULT + * _modver: module version, _modver=1.0 + * _*: any other key name starting with an _ is reserved + * Unknown uri keys/values are forwarded as is. + * @param h, resulting handle + * @retval, 0 on success + */ + long open(in string uri, rout remote_handle64 h); + /** + * Closes a handle. If this is the last handle to close, the session + * is closed as well, releasing all the allocated resources. + + * @param h, the handle to close + * @retval, 0 on success, should always succeed + */ + long close(in remote_handle64 h); +}; diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.md new file mode 100755 index 0000000000000..0c3d9daca2aca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote.md @@ -0,0 +1,120 @@ +# Remote session API to interface with FastRPC + + +## Overview + +FastRPC exposes a set of APIs enabling the following functionality: + + - open, configure and close a remote session on the DSP + - enable unsigned PD offload to the compute DSP + - enable and manage QoS mode + - make synchronous or asynchronous remote calls + - query DSP capabilities + - map or unmap pages onto the DSP + +The 64-bit version of the API (`handle64`) enables multi-domain modules. +It is recommended for applications to use the multi-domain framework, +which provides multiple benefits over the older single-domain framework. remote_handle_* +APIs should be used for single-domain applications. For more information on multi-domain support, +refer to the RPC section in the Hexagon SDK documentation. + +# `remote_handle_open`, `remote_handle64_open` +Loads the shared object on the remote process domain. + +# `remote_handle_invoke`, `remote_handle64_invoke` +Executes a process on the remote domain. + +# `remote_handle_close`, `remote_handle64_close` +Closes the remote handle opened by the remote process. + +# `remote_handle_control`, `remote_handle64_control` +Manages the remote session. +This API allows to control or query the remote session: +- Control latency + The user can vote for a specific latency requirement per session. This latency is not guaranteed by the driver. The driver will try to + meet this requirement with the options available on a given target. Based on the arguments, either PM-QoS [Power Management] or adaptive + QoS can be enabled. + + PM-QoS is recommended for latency-sensitive use cases, whereas adaptive QoS is recommended for moderately latency-sensitive use cases. + Adaptive QoS is more power-efficient than PM-QoS. + + If PM-QoS enabled, CPU low power modes will be disabled. + + If Adaptive QoS is enabled, the remote DSP starts keeping track of the method execution times for that process. Once enough data is available, + the DSP will try to predict when the method will finish executing and will send a "ping" to wake up the CPU prior to the completion of the + DSP task so that there is no extra overhead due to CPU wakeup time. + +- Enable wake lock + Keep the CPU up until a response from the remote invocation call is received. Disabling wake lock feature enables the CPU to be in suspend mode. + +- Query DSP Capabilities + Queries DSP support for: + + * domains available + * unsigned PD + * HVX, VTCM, HMX + * async FastRPC + * remote PD status notification + +- Get DSP domain + Returns the current DSP domain. + +# `remote_session_control` + +Sets remote session parameters such as thread stack size or unsigned PD mode. Enables to kill remote process, closes sessions on the DSP, +generates a PD dump, or triggers remote process exceptions. + +- [Stack thread parameters](structremote__rpc__thread__params.html)
+ Parameters to configure a thread: priority and stack size. + +- [Unsigned PD](structremote__rpc__control__unsigned__module.html)
+ Flag to configure the session as unsigned. This allows third party applications to run compute + intensive tasks on the compute DSP for better performance. + +- [Kill remote process](structremote__rpc__process__clean__params.html)
+ Kills the remote process running on the DSP. + +- [Session close](structremote__rpc__session__close.html)
+ Closes all sessions open on a given domain. + +- [PD dump](structremote__rpc__control__pd__dump.html)
+ Enables PD dump feature. + +- [Remote process exception](structremote__rpc__process__clean__params.html)
+ Introduces an exception in the remote process. + +- [Query process type](structremote__process__type.html)
+ Query the type of process (signed or unsigned) running on remote DSP. + +- [Relative thread priority](structremote__rpc__relative__thread__priority.html)
+ Set a lower or higher priority than the default thread priority, for the user threads on the DSP. + +# `fastrpc_mmap`, `fastrpc_munmap` +Creates a new mapping of an ION memory into the virtual address space of a remote process on the DSP and associates the mapping with the +provided file descriptor. The parameter `flags` of type `fastrpc_map_flags` allows the user to control the page permissions and other +properties of the memory map. These mappings can be destroyed with `fastrpc_munmap()` API using the file descriptor. APIs `fastrpc_mmap` +and `fastrpc_munmap` are available and their use is recommended for Lahaina and later chipsets. + +# `remote_mem_map`, `remote_mem_unmap` +Maps/unmaps large buffers statically on a given DSP. +Mapping the buffers statically saves the latency for the corresponding remote calls associated with these buffers. +These APIs are available only on SM8250 (Kona) or later targets. + +# `remote_handle_invoke_async`, `remote_handle64_invoke_async` +Make remote invocations asynchronous. Running asynchronously does not improve the latency but improves the throughput by enabling the DSP +to run successive tasks continuously. This feature is supported on Lahaina and onward targets. + +# `fastrpc_async_get_status` +Queries the status of the asynchronous job. + +# `fastrpc_release_async_job` +Releases the asynchronous job after receiving the status either through callback or poll. + +# `remote_register_buf`, `remote_register_buf_attr` +Registers a file descriptor for a buffer allocated with ION memory to share the memory with the DSP via SMMU. + +# `remote_register_dma_handle`, `remote_register_dma_handle_attr` +Registers a DMA handle allocated with ION memory to share the memory with the DSP via SMMU. + +Header file: @b remote.h + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote64.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote64.h new file mode 100755 index 0000000000000..07cf3d5d6e769 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/remote64.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2014, 2022 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + */ +#ifndef REMOTE64_H +#define REMOTE64_H + +#include "remote.h" + +/* +All the functions declared here are moved to remote.h, remote64.h will be deleted in future. +*/ +#endif // REMOTE64_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStd.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStd.md new file mode 100755 index 0000000000000..3a02dd209389b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStd.md @@ -0,0 +1,11 @@ +# Standard definitions and error codes + +## Standard definitions + +AEEStdDef.h contains definitions of common data types used on the Hexagon DSPs and the application processor. It also has definitions of MIN, MAX values for common data types. + +## Standard error codes + +AEEStdErr.h file contains error codes returned by functions running on the DSPs and the application processor. +The application invoking these APIs is expected to check for the error codes and implement appropriate error handling. Each API in the header files will have required documentation on the error codes it can return. + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.h new file mode 100755 index 0000000000000..fe252dd6f0590 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.h @@ -0,0 +1,464 @@ +#ifndef AEESTDDEF_H +#define AEESTDDEF_H +/* +======================================================================= + +FILE: AEEStdDef.h + +DESCRIPTION: definition of basic types, constants, + preprocessor macros + +======================================================================= +*/ +/*============================================================================== + Copyright (c) 2005,2007,2012-2013, 2020 Qualcomm Technologies, Inc. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +==============================================================================*/ + +#include + +#if defined(COMDEF_H) /* guards against a known re-definer */ +#define _BOOLEAN_DEFINED +#define _UINT32_DEFINED +#define _UINT16_DEFINED +#define _UINT8_DEFINED +#define _INT32_DEFINED +#define _INT16_DEFINED +#define _INT8_DEFINED +#define _UINT64_DEFINED +#define _INT64_DEFINED +#define _BYTE_DEFINED +#endif /* #if !defined(COMDEF_H) */ + +/* ----------------------------------------------------------------------- +** Standard Types +** ----------------------------------------------------------------------- */ + +/* The following definitions are the same accross platforms. This first +** group are the sanctioned types. +*/ +/** @defgroup stddef standard data type definitions +* @{ +*/ +#ifndef _BOOLEAN_DEFINED +typedef unsigned char boolean; /**< Boolean value type. */ +#define _BOOLEAN_DEFINED +#endif + +#ifndef _UINT32_DEFINED +typedef uint32_t uint32; /**< Unsigned 32-bit value */ +#define _UINT32_DEFINED +#endif + +#ifndef _UINT16_DEFINED +typedef unsigned short uint16; /**< Unsigned 16-bit value */ +#define _UINT16_DEFINED +#endif + +#ifndef _UINT8_DEFINED +typedef unsigned char uint8; /**< Unsigned 8-bit value */ +#define _UINT8_DEFINED +#endif + +#ifndef _INT32_DEFINED +typedef int32_t int32; /**< Signed 32-bit value */ +#define _INT32_DEFINED +#endif + +#ifndef _INT16_DEFINED +typedef signed short int16; /**< Signed 16-bit value */ +#define _INT16_DEFINED +#endif + +#ifndef _INT8_DEFINED +typedef signed char int8; /**< Signed 8-bit value */ +#define _INT8_DEFINED +#endif + +#ifndef _INT64_DEFINED +#if defined(__GNUC__) +#define __int64 long long +#endif +typedef __int64 int64; /**< Signed 64-bit value */ +#define _INT64_DEFINED +#endif + +#ifndef _UINT64_DEFINED +typedef unsigned __int64 uint64; /**< Unsigned 64-bit value */ +#define _UINT64_DEFINED +#endif + +#ifndef _BYTE_DEFINED +typedef unsigned char byte; /**< byte type */ +#define _BYTE_DEFINED +#endif + +/** + * @} + */ + + /** @defgroup stdret standard return values +* @{ +*/ + +//! @cond Doxygen_Suppress +#ifndef _AEEUID_DEFINED +typedef uint32 AEEUID; +#define _AEEUID_DEFINED +#endif + +#ifndef _AEEIID_DEFINED +typedef uint32 AEEIID; +#define _AEEIID_DEFINED +#endif + +#ifndef _AEECLSID_DEFINED +typedef uint32 AEECLSID; +#define _AEECLSID_DEFINED +#endif + +#ifndef _AEEPRIVID_DEFINED +typedef uint32 AEEPRIVID; +#define _AEEPRIVID_DEFINED +#endif + +#ifndef _AECHAR_DEFINED +typedef uint16 AECHAR; +#define _AECHAR_DEFINED +#endif +//! @endcond + +/** + * @brief Return value of functions indicating success or failure. return value 0 indicates success. A non zero value indicates a failure. Any data in rout parameters is not propagated back. + */ +#ifndef _AEERESULT_DEFINED +typedef int AEEResult; +#define _AEERESULT_DEFINED +#endif + +/** + * @} + */ + + +/* ----------------------------------------------------------------------- +** Function Calling Conventions +** ----------------------------------------------------------------------- */ + +#ifndef CDECL +#ifdef _MSC_VER +#define CDECL __cdecl +#else +#define CDECL +#endif /* _MSC_VER */ +#endif /* CDECL */ + +/* ----------------------------------------------------------------------- +** Constants +** ----------------------------------------------------------------------- */ + /** @defgroup stdminmax Standard Min and Max for all data types +* @{ +*/ + +#ifndef TRUE +#define TRUE 1 /**< Boolean true value. */ +#endif + +#ifndef FALSE +#define FALSE 0 /**< Boolean false value. */ +#endif + +#ifndef NULL +#define NULL 0 /**< NULL = 0. */ +#endif + +#ifndef MIN_INT8 +#define MIN_INT8 -128 /**< MIN 8-bit integer */ +#endif +#ifndef MIN_INT16 +#define MIN_INT16 -32768 /**< MIN 16-bit integer */ +#endif +#ifndef MIN_INT32 +#define MIN_INT32 (~0x7fffffff) /**< MIN 32-bit unsigned */ +#endif +#ifndef MIN_INT64 +#define MIN_INT64 (~0x7fffffffffffffffLL) /**< MIN 64-bit integer */ +#endif + +#ifndef MAX_INT8 +#define MAX_INT8 127 /**< MAX 8-bit integer */ +#endif +#ifndef MAX_INT16 +#define MAX_INT16 32767 /**< MAX 16-bit integer */ +#endif +#ifndef MAX_INT32 +#define MAX_INT32 2147483647 /**< MAX 32-bit integer */ +#endif +#ifndef MAX_INT64 +#define MAX_INT64 9223372036854775807LL /**< MAX 64-bit integer */ +#endif + +#ifndef MAX_UINT8 +#define MAX_UINT8 255 /**< MAX 8-bit unsigned integer */ +#endif +#ifndef MAX_UINT16 +#define MAX_UINT16 65535 /**< MAX 16-bit unsigned integer */ +#endif +#ifndef MAX_UINT32 +#define MAX_UINT32 4294967295u /**< MAX 32-bit unsigned integer */ +#endif +#ifndef MAX_UINT64 +#define MAX_UINT64 18446744073709551615uLL /**< MAX 64-bit unsigned integer */ +#endif + +//! @cond Doxygen_Suppress +#ifndef MIN_AECHAR +#define MIN_AECHAR 0 +#endif + +#ifndef MAX_AECHAR +#define MAX_AECHAR 65535 +#endif + +//! @endcond + +/** + * @} + */ + +/* ----------------------------------------------------------------------- +** Preprocessor helpers +** ----------------------------------------------------------------------- */ +#define __STR__(x) #x +#define __TOSTR__(x) __STR__(x) +#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__) + +/* ----------------------------------------------------------------------- +** Types for code generated from IDL +** ----------------------------------------------------------------------- */ + + /** @defgroup QIDL data types +* @{ +*/ +//! @cond Doxygen_Suppress +#ifndef __QIDL_WCHAR_T_DEFINED__ +#define __QIDL_WCHAR_T_DEFINED__ +typedef uint16 _wchar_t; +#endif + + +/* __STRING_OBJECT__ will be deprecated in the future */ + + +#if !defined(__QIDL_STRING_OBJECT_DEFINED__) && !defined(__STRING_OBJECT__) +#define __QIDL_STRING_OBJECT_DEFINED__ +#define __STRING_OBJECT__ + +/** + * @brief This structure is used to represent an IDL string when used inside a + sequence or union. + */ +typedef struct _cstring_s { + char* data; + int dataLen; + int dataLenReq; +} _cstring_t; + +/** + * @brief This structure is used to represent an IDL wstring when used inside a + sequence or union. + */ + +typedef struct _wstring_s { + _wchar_t* data; + int dataLen; + int dataLenReq; +} _wstring_t; +#endif /* __QIDL_STRING_OBJECT_DEFINED__ */ +//! @endcond +/** + * @} + */ +/* +======================================================================= + DATA STRUCTURES DOCUMENTATION +======================================================================= + +======================================================================= + +AEEUID + +Description: + This is a BREW unique ID. Used to express unique types, interfaces, classes + groups and privileges. The BREW ClassID Generator generates + unique IDs that can be used anywhere you need a new AEEIID, AEECLSID, + or AEEPRIVID. + +Definition: + typedef uint32 AEEUID + +======================================================================= + +AEEIID + +Description: + This is an interface ID type, used to denote a BREW interface. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEEIID + +======================================================================= + +AEECLSID + +Description: + This is a classe ID type, used to denote a BREW class. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEECLSID + +======================================================================= + +AEEPRIVID + +Description: + This is a privilege ID type, used to express a privilege. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEEPRIVID + +======================================================================= + +AECHAR + +Description: + This is a 16-bit character type. + +Definition: + typedef uint16 AECHAR + +======================================================================= + +AEEResult + +Description: + This is the standard result type. + +Definition: + typedef int AEEResult + +======================================================================= + +_wchar_t + +Description: + This is a 16-bit character type corresponding to the IDL 'wchar' + type. + +Definition: + typedef uint16 _wchar_t + +See Also: + _cstring_t + _wstring_t + +======================================================================= + +_cstring_t + +Description: + This structure is used to represent an IDL string when used inside a + sequence or union. + +Definition: + typedef struct _cstring_s { + char* data; + int dataLen; + int dataLenReq; + } _cstring_t; + +Members: + data : A pointer to the NULL-terminated string. + dataLen : The size, in chars, of the buffer pointed to by 'data', + including the NULL terminator. This member is only used + when the structure is part of an rout or inrout + parameter, but must be supplied by the caller as an + input in these cases. + dataLenReq : The size that would have been required to store the + entire result string. This member is only used when the + structure is part of an rout or inrout parameter, when + it is an output value set by the callee. The length of + the returned string (including the NULL terminator) + after a call is the minimum of dataLen and dataLenReq. + +See Also: + _wchar_t + _wstring_t + +======================================================================= + +_wstring_t + +Description: + This structure is used to represent an IDL wstring when used inside a + sequence or union. + +Definition: + typedef struct _wstring_s { + _wchar_t* data; + int dataLen; + int dataLenReq; + } _wstring_t; + +Members: + data : A pointer to the NULL-terminated wide string. + dataLen : The size, in 16-bit characters, of the buffer pointed to + by 'data', including the NULL terminator. This member + is only used when the structure is part of an rout or + inrout parameter, but must be supplied by the caller as + an input in these cases. + dataLenReq : The number of 16-bit characters that would have been + required to store the entire result string. This member + is only used when the structure is part of an rout or + inrout parameter, when it is an output value set by the + callee. The length of the returned wstring (including + the NULL terminator) after a call is the minimum of + dataLen and dataLenReq. + +See Also: + _cstring_t + _wchar_t + +======================================================================= +*/ + +#endif /* #ifndef AEESTDDEF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.idl b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.idl new file mode 100755 index 0000000000000..ac224152bcaf9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdDef.idl @@ -0,0 +1,91 @@ +#ifndef AEESTDDEF_IDL +#define AEESTDDEF_IDL +//============================================================================ +/// @file AEEStdDef.idl +/// +/// This file contains definitions of primitive types. + //qidl copyright +//% Copyright (c) 2006-2014, 2020 Qualcomm Technologies, Inc. + //qidl nested=false +//% All Rights Reserved. +//% Redistribution and use in source and binary forms, with or without +//% modification, are permitted provided that the following conditions are met: +//% +//% 1. Redistributions of source code must retain the above copyright notice, +//% this list of conditions and the following disclaimer. +//% +//% 2. Redistributions in binary form must reproduce the above copyright notice, +//% this list of conditions and the following disclaimer in the documentation +//% and/or other materials provided with the distribution. +//% +//% 3. Neither the name of the copyright holder nor the names of its contributors +//% may be used to endorse or promote products derived from this software without +//% specific prior written permission. +//% +//% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +//% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//% POSSIBILITY OF SUCH DAMAGE. +//============================================================================ + +/* NOTE: THIS FILE SHOULD NEVER BE COMPILED DIRECTLY. That is, code should + * never be generated from these definitions, as they will conflict with the + * "real" hand-written AEEStdDef.h. Note also that if the definitions here + * become out of sync with the hand-written AEEStdDef.h, bad things will + * happen. + */ + +/** + * @name Primitive Types + */ +/*@{*/ + +typedef octet byte; ///< Alternate alias for an unsigned + ///< 8-bit integer +/*@}*/ + +/** + * @name Types + */ +/*@{*/ + +/** + * This is a unique ID type. Used to express types, + * interfaces, classes, and privileges. The class ID generator generates + * unique IDs that can be used anywhere a new #AEEIID, #AEECLSID, or + * #AEEPRIVID is needed. + */ +typedef uint32 AEEUID; + +/** + * This is an interface ID type, used to denote an interface. It is a special + case of #AEEUID. + */ +typedef uint32 AEEIID; + +/** + * This is a class ID type, used to denote a class. It is a special case of + #AEEUID. + */ +typedef uint32 AEECLSID; + +/** + * This is a privilege ID type, used to express a privilege. It is a special + * case of #AEEUID. + */ +typedef uint32 AEEPRIVID; + +typedef wchar AECHAR; ///< Wide character type + +typedef long AEEResult; ///< Common return type + +/*@}*/ + +#endif /* #ifndef AEESTDDEF_IDL */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdErr.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdErr.h new file mode 100755 index 0000000000000..bc1706abe5886 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stddef/AEEStdErr.h @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2005-2007, 2012-2013, 2019-2020 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AEESTDERR_H +#define AEESTDERR_H +// +// Basic Error Codes +// +// +#if defined(__hexagon__) + #define AEE_EOFFSET 0x80000400 +#else + #define AEE_EOFFSET 0x00000000 +#endif +/** @defgroup stdbasicerror Basic error codes + * @{ + */ +#define AEE_SUCCESS 0 ///< No error +#define AEE_EUNKNOWN -1 ///< Unknown error (should not use this) + +#define AEE_EFAILED (AEE_EOFFSET + 0x001) ///< General failure +#define AEE_ENOMEMORY (AEE_EOFFSET + 0x002) ///< Memory allocation failed because of insufficient RAM +#define AEE_ECLASSNOTSUPPORT (AEE_EOFFSET + 0x003) ///< Specified class unsupported +#define AEE_EVERSIONNOTSUPPORT (AEE_EOFFSET + 0x004) ///< Version not supported +#define AEE_EALREADYLOADED (AEE_EOFFSET + 0x005) ///< Object already loaded +#define AEE_EUNABLETOLOAD (AEE_EOFFSET + 0x006) ///< Unable to load object/applet +#define AEE_EUNABLETOUNLOAD (AEE_EOFFSET + 0x007) ///< Unable to unload + ///< object/applet +#define AEE_EALARMPENDING (AEE_EOFFSET + 0x008) ///< Alarm is pending +#define AEE_EINVALIDTIME (AEE_EOFFSET + 0x009) ///< Invalid time +#define AEE_EBADCLASS (AEE_EOFFSET + 0x00A) ///< NULL class object +#define AEE_EBADMETRIC (AEE_EOFFSET + 0x00B) ///< Invalid metric specified +#define AEE_EEXPIRED (AEE_EOFFSET + 0x00C) ///< App/Component Expired +#define AEE_EBADSTATE (AEE_EOFFSET + 0x00D) ///< Process or thread is not in expected state +#define AEE_EBADPARM (AEE_EOFFSET + 0x00E) ///< Invalid parameter +#define AEE_ESCHEMENOTSUPPORTED (AEE_EOFFSET + 0x00F) ///< Invalid URL scheme +#define AEE_EBADITEM (AEE_EOFFSET + 0x010) ///< Value out of range +#define AEE_EINVALIDFORMAT (AEE_EOFFSET + 0x011) ///< Invalid format +#define AEE_EINCOMPLETEITEM (AEE_EOFFSET + 0x012) ///< Incomplete item, like length of a string is less that expected +#define AEE_ENOPERSISTMEMORY (AEE_EOFFSET + 0x013) ///< Insufficient flash +#define AEE_EUNSUPPORTED (AEE_EOFFSET + 0x014) ///< API not implemented +#define AEE_EPRIVLEVEL (AEE_EOFFSET + 0x015) ///< Privileges are insufficient + ///< for this operation +#define AEE_ERESOURCENOTFOUND (AEE_EOFFSET + 0x016) ///< Unable to find specified + ///< resource +#define AEE_EREENTERED (AEE_EOFFSET + 0x017) ///< Non re-entrant API + ///< re-entered +#define AEE_EBADTASK (AEE_EOFFSET + 0x018) ///< API called in wrong task + ///< context +#define AEE_EALLOCATED (AEE_EOFFSET + 0x019) ///< App/Module left memory + ///< allocated when released. +#define AEE_EALREADY (AEE_EOFFSET + 0x01A) ///< Operation is already in + ///< progress +#define AEE_EADSAUTHBAD (AEE_EOFFSET + 0x01B) ///< ADS mutual authorization + ///< failed +#define AEE_ENEEDSERVICEPROG (AEE_EOFFSET + 0x01C) ///< Need service programming +#define AEE_EMEMPTR (AEE_EOFFSET + 0x01D) ///< bad memory pointer, expected to be NULL +#define AEE_EHEAP (AEE_EOFFSET + 0x01E) ///< An internal heap error was detected +#define AEE_EIDLE (AEE_EOFFSET + 0x01F) ///< Context (system, interface, + ///< etc.) is idle +#define AEE_EITEMBUSY (AEE_EOFFSET + 0x020) ///< Context (system, interface, + ///< etc.) is busy +#define AEE_EBADSID (AEE_EOFFSET + 0x021) ///< Invalid subscriber ID +#define AEE_ENOTYPE (AEE_EOFFSET + 0x022) ///< No type detected/found +#define AEE_ENEEDMORE (AEE_EOFFSET + 0x023) ///< Need more data/info +#define AEE_EADSCAPS (AEE_EOFFSET + 0x024) ///< ADS Capabilities do not + ///< match those required for phone +#define AEE_EBADSHUTDOWN (AEE_EOFFSET + 0x025) ///< App failed to close properly +#define AEE_EBUFFERTOOSMALL (AEE_EOFFSET + 0x026) ///< Destination buffer given is + ///< too small + ///< or service exists or is + ///< valid +#define AEE_EACKPENDING (AEE_EOFFSET + 0x028) ///< ACK pending on application +#define AEE_ENOTOWNER (AEE_EOFFSET + 0x029) ///< Not an owner authorized to + ///< perform the operation +#define AEE_EINVALIDITEM (AEE_EOFFSET + 0x02A) ///< Current item is invalid, it can be a switch case or a pointer to memory +#define AEE_ENOTALLOWED (AEE_EOFFSET + 0x02B) ///< Not allowed to perform the + ///< operation +#define AEE_EINVHANDLE (AEE_EOFFSET + 0x02C) ///< Invalid handle - adding here as its defined in vendor AEEStdErr.h - needed to check valid handle in stub.c +#define AEE_EOUTOFHANDLES (AEE_EOFFSET + 0x02D) ///< Out of handles (Handle list is already full) +//Hole here +#define AEE_ENOMORE (AEE_EOFFSET + 0x02F) ///< No more items available -- + ///< reached end +#define AEE_ECPUEXCEPTION (AEE_EOFFSET + 0x030) ///< A CPU exception occurred +#define AEE_EREADONLY (AEE_EOFFSET + 0x031) ///< Cannot change read-only + ///< object or parameter ( Parameter is in protected mode) +#define AEE_ERPC (AEE_EOFFSET + 0x200) ///< Error due to fastrpc implementation +#define AEE_EFILE (AEE_EOFFSET + 0x201) ///= 200000 && !defined(__APCS_ADSABI)) || \ + (defined(__GNUC__) && defined(__arm__) && defined(__ARM_EABI__)) + +# define __AEEVA_ATPCS 0 + +#else + +# define __AEEVA_ATPCS 1 + +#endif + +typedef void* AEEVaList; + +#define __AEEVA_ARGALIGN(t) (((char*)(&((struct{char c;t x;}*)1)->x))-((char*)1)) +#define __AEEVA_ARGSIZE(t) ((sizeof(t)+sizeof(int)-1) & ~(sizeof(int)-1)) + +static __inline void __cpy(char*d, const char*s, int len) +{ + while (len-- > 0) *d++ = *s++; +} + +static __inline AEEVaList __AEEVa_Arg(AEEVaList args, void* pv, int nVSize, + int nArgSize, int nArgAlign) +{ + int nArgs = (int)args & ~1; + char* pcArgs = (char*)args; + int bATPCS = (int)args & 1; + int nArgsOffset = 0; + int nVOffset = 0; + + if (!bATPCS) { /* caller was compiled with AAPCS */ + + if (nArgAlign > (int)sizeof(int)) { + nArgAlign--; /* make a mask */ + pcArgs += ((nArgs + nArgAlign) & (int)~(unsigned)nArgAlign) - nArgs; + /* move pv to next alignment */ + } + } + +#if defined(AEE_BIGENDIAN) + if (nArgSize < (int)sizeof(int)) { + nArgsOffset = (int)sizeof(int) - nArgSize; + } + nVOffset = nVSize - nArgSize; +#else + (void)nVSize; +#endif /* AEE_BIGENDIAN */ + + __cpy((char*)pv + nVOffset, (pcArgs - bATPCS) + nArgsOffset, nArgSize); + + /* round up */ + nArgSize = (nArgSize+(int)sizeof(int)-1) & ~((int)sizeof(int)-1); + + return pcArgs + nArgSize; /* increment va */ +} + +#define AEEVA_START(va,v) ((va) = (char*)&(v) + __AEEVA_ARGSIZE(v) + __AEEVA_ATPCS) +#define AEEVA_ARG(va,v,t) ((void)((va) = __AEEVa_Arg(va,&v,sizeof(v),sizeof(t),__AEEVA_ARGALIGN(t)))) +#define AEEVA_END(va) ((va) = (AEEVaList)0) +#define AEEVA_COPY(dest, src) ((void)((dest) = (src))) + +#else /* !defined(__clang__) && (defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__))) */ + +#include + +typedef va_list AEEVaList; + +#define AEEVA_START(va,v) (va_start((va), (v))) +#define AEEVA_ARG(va,v,t) ((v) = va_arg((va),t)) +#define AEEVA_END(va) (va_end((va))) +#define AEEVA_COPY(dest, src) (va_copy((dest),(src))) + +#endif/* !defined(__clang__) && (defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__))) */ + +#endif /* #ifndef AEEVALIST_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.h new file mode 100755 index 0000000000000..94bcba0a701a4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.h @@ -0,0 +1,695 @@ +/* + * $Header: //components/rel/core.qdsp6/8.2/api/common/kernel/libstd/stringl/stringl.h#1 $ + * $DateTime: 2023/05/10 09:48:16 $ + */ + +/* $OpenBSD: string.h,v 1.17 2006/01/06 18:53:04 millert Exp $ */ +/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)string.h 5.10 (Berkeley) 3/9/91 + */ + +#ifndef _STRINGL_H_ +#define _STRINGL_H_ + +#include +#include +#include + +/** @defgroup error_codes Error Codes + * @{ + */ +// +// AEEstd.h header error codes +// +#ifndef STD_NODIGITS + #define STD_NODIGITS 1 /**< See std_scanul(). */ +#endif + +#ifndef STD_NEGATIVE + #define STD_NEGATIVE 2 /**< See std_scanul(). */ +#endif + +#ifndef STD_OVERFLOW + #define STD_OVERFLOW 3 /**< See std_scanul(). */ +#endif + +#ifndef STD_BADPARAM + #define STD_BADPARAM 4 /**< See std_scanul(). */ +#endif + +/** + * @} + */ + +/**< UTF-16 2-byte wide char type */ +typedef unsigned short wchar; + +#ifdef __cplusplus +namespace std +{ + extern "C" + { +#endif //__cplusplus + +/** +Added these macros for supporting compilation on Win based +software dev environments like VC, .Net etc. +*/ +#ifdef _WIN32 + #define snprintf _snprintf + #define vsnprintf _vsnprintf +#endif + +/** @defgroup str_apis String Operation APIs + * @{ + */ + +/** + strlcat - Size bounded string concatenation. + + Concatenates the source string to destination string. + + This function ensures that the destination string will + not be improperly terminated and that there will be + no concatenation beyond the size of the destination buffer. + + @param[in,out] dst Destination buffer. + @param[in] src Source string. + @param[in] siz Size of the destination buffer in bytes. + + @return + The length of the string that was attempted to be created, + i.e. the sum of the source and destination strings. + + @dependencies + None. +*/ +size_t strlcat(char *dst, const char *src, size_t siz); + +/** + * @} + */ + + /** @defgroup wstr_apis Wide Char String Operation APIs + * @{ + */ +/** + wcslcat - Size bounded wide string concatenation using + C standard wide character data type wchar_t. + + Concatenates the source string to destination string. + + This function ensures that the destination string will + not be improperly terminated and that there will be + no concatenation beyond the size of the destination buffer. + + @param[in,out] dst Destination buffer. + @param[in] src Source string. + @param[in] siz Size of the destination buffer in units of wchar_t. + + @return + The length of the string that was attempted to be created, + i.e. the sum of the source and destination strings. + + @note It has been observed that wchar_t on some platforms is + 2 bytes wide (UTF-16) and on others is 4 bytes wide (UTF-32). + So carefully consider this when using the data type wchar_t + and this API in your application. + + @dependencies + None. +*/ + +size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz); + +/** + wstrlcat - Size bounded wide string concatenation using 2 byte + wide (UTF-16) character data type wchar. + + Concatenates the source string to destination string. + + This function ensures that the destination string will + not be improperly terminated and that there will be + no concatenation beyond the size of the destination buffer. + + @param[in,out] dst Destination buffer. + @param[in] src Source string. + @param[in] siz Size of the destination buffer in units of wchar. + + @return + The length of the string that was attempted to be created, + i.e. the sum of the source and destination strings. + + @dependencies + None. +*/ +size_t wstrlcat(wchar* dst, const wchar* src, size_t siz); + +/** + * @} + */ + + /** @addtogroup str_apis + @{ */ + +/** + strlcpy - Size bounded string copy. + + Copies the source string to the destination buffer. + + This function ensures that the destination buffer will always + be NULL terminated and that there will not be a copy beyond + the size of the destination buffer. + + @param[out] dst Destination buffer. + @param[in] src Source String. + @param[in] siz Size of the destination buffer in bytes. + + @return + The length of the source string. + + @dependencies + None. +*/ +size_t strlcpy(char *dst, const char *src, size_t siz); + +/** @} */ + + /** @addtogroup wstr_apis + @{ */ +/** + wcslcpy - Size bounded wide string copy using + C standard wide character data type wchar_t. + + Copies the source string to the destination buffer. + + This function ensures that the destination buffer will always + be NULL terminated and that there will not be a copy beyond + the size of the destination buffer. + + @param[out] dst Destination buffer. + @param[in] src Source String. + @param[in] siz Size of the destination buffer in units of wchar_t. + + @return + The length of the source string. + + @note It has been observed that wchar_t on some platforms is + 2 bytes wide (UTF-16) and on others is 4 bytes wide (UTF-32). + So carefully consider this when using the data type wchar_t + and this API in your application. + + @dependencies + None. +*/ + +size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz); + +/** + wstrlcpy - Size bounded wide string copy using 2 byte + wide (UTF-16) character data type wchar. + + Copies the source string to the destination buffer. + + This function ensures that the destination buffer will always + be NULL terminated and that there will not be a copy beyond + the size of the destination buffer. + + @param[out] dst Destination buffer. + @param[in] src Source String. + @param[in] siz Size of the destination buffer in units of wchar. + + @return + The length of the source string. + + @dependencies + None. +*/ +size_t wstrlcpy(wchar* dst, const wchar* src, size_t siz); + +/** + wstrlen - Returns the number of characters in the source string. + Used for strings based on wchar data type i.e. 2 byte wide (UTF-16) + characters. + + @param[in] src Source String. + + @return + The number of characters in the source string. + + @dependencies + None. +*/ +size_t wstrlen(const wchar *src); + +/** + wstrcmp - Compares wchar (UTF-16) string s1 to the wchar string s2. + + This function starts comparing the first character of each string. + If they are equal to each other, it continues with the following + pairs until the characters differ or until a terminating + null-character is reached. + + @param[in] s1 String to be compared. + @param[in] s2 String to be compared against. + + @return + 0 - Indicates that the strings are equal. + >0 - Indicates that the strings are not equal and a character in s1 is + greater than the corresponding character in s2. + <0 - Indicates that the strings are not equal and a character in s1 is + lesser than the corresponding character in s2. + + @dependencies + None. +*/ +int wstrcmp(const wchar *s1, const wchar *s2); + +/** + wstrncmp - Compares upto n wchar (UTF-16) characters in string s1 + to the wchar string s2. + + This function starts comparing the first character of each string. + If they are equal to each other, it continues with the following + pairs until the characters differ or until a terminating + null-character is reached or n comparisons have been performed. + + @param[in] s1 String to be compared. + @param[in] s2 String to be compared against. + @param[in] n Nmber of character to be compared. + + @return + 0 - Indicates that the strings are equal. + >0 - Indicates that the strings are not equal and a character in s1 is + greater than the corresponding character in s2. + <0 - Indicates that the strings are not equal and a character in s1 is + lesser than the corresponding character in s2. + + @dependencies + None. +*/ +int wstrncmp(const wchar *s1, const wchar *s2, size_t n); + +/** @} */ + + /** @addtogroup str_apis + @{ */ + +/** + strcasecmp - compare two strings ignoring case. + + @param[in] s1 First string. + @param[in] s2 Second string. + + @return + The strcasecmp() and strncasecmp() functions return an integer + less than, equal to, or greater than zero if s1 (or the first + n bytes thereof) is found, respectively, to be less than, to + match, or be greater than s2. + + @dependencies + None. +*/ +int strcasecmp(const char * s1, const char * s2); + +/** + strncasecmp - compare two strings ignoring case (sized). + + @param[in] s1 First string. + @param[in] s2 Second string. + @param[in] n The number of characters to compare (from the + beginning). + + @return + The strcasecmp() and strncasecmp() functions return an integer + less than, equal to, or greater than zero if s1 (or the first + n bytes thereof) is found, respectively, to be less than, to + match, or be greater than s2. + + @dependencies + None. +*/ +int strncasecmp(const char * s1, const char * s2, size_t n); + +/** +std_scanul() + +Description: + + The std_scanul() converts an ASCII representation of a number + to an unsigned long. It expects strings that match the + following pattern: + + spaces [+|-] digits + + + 'Spaces' is zero or more ASCII space or tab characters. + + 'Digits' is any number of digits valid in the radix. Letters + 'A' through 'Z' are treated as digits with values 10 through + 35. 'Digits' may begin with "0x" when a radix of 0 or 16 is + specified. + + Upper and lower case letters can be used interchangeably. + + @param[in] pchBuf The start of the string to scan. + + @param[in] nRadix The numeric radix (or base) of the + number. Valid values are 2 through 36 or zero, + which implies auto-detection. Auto-detection + examines the digits field. If it begins with + "0x", radix 16 is selected. Otherwise, if it + begins with "0" radix 8 is selected. + Otherwise, radix 10 is selected. + + @param[out] ppchEnd If ppchEnd is not NULL, *ppchEnd + points to the first character that did not + match the expected pattern shown above, + except on STD_BADPARAM and STD_OVERFLOW when + it is set to the start of the string. + + @param[out] pnError If pnError is not NULL, *pnError + holds the error code, which is one of the + following: + + 0 : Numeric value is from 0 to + MAX_UINT32. + + STD_NEGATIVE : The scanned value was negative and its absolute value was + from 1 to MAX_UINT32. The result is the negated value + (cast to a uint32). + + STD_NODIGITS : No digits were found. The result is zero. + + STD_OVERFLOW : The absolute value exceeded MAX_UINT32. The result + is set to MAX_UINT32 and *ppchEnd is set to pchBuf. + + STD_BADPARAM : An improper value for nRadix was received. The result + is set to zero, and *ppchEnd is set to pchBuf. + + @return + The converted numeric result. + + @dependencies + None. + +*/ +unsigned int std_scanul(const char * pchBuf, int nRadix, const char ** ppchEnd, int *pnError); + +/** @} */ + +/** @defgroup mem_ops Memory Operation APIs + * @{ + */ + +/** + memscpy - Size bounded memory copy. + + Copies bytes from the source buffer to the destination buffer. + + This function ensures that there will not be a copy beyond + the size of the destination buffer. + + The result of calling this on overlapping source and destination + buffers is undefined. + + @param[out] dst Destination buffer. + @param[in] dst_size Size of the destination buffer in bytes. + @param[in] src Source buffer. + @param[in] src_size Number of bytes to copy from source buffer. + + @return + The number of bytes copied to the destination buffer. It is the + caller's responsibility to check for trunction if it cares about it - + truncation has occurred if the return value is less than src_size. + + @dependencies + None. +*/ + +size_t memscpy(void *dst, size_t dst_size, const void *src, size_t src_size); + +/** + memscpy_i - Inline function for size bounded memory copy. + + @see memscpy() +*/ + +static __inline size_t memscpy_i +( + void *dst, + size_t dst_size, + const void *src, + size_t src_size +) +{ + size_t copy_size = (dst_size <= src_size)? dst_size : src_size; + + memcpy(dst, src, copy_size); + + return copy_size; +} + +/** + memsmove - Size bounded memory move. + + Moves bytes from the source buffer to the destination buffer. + + This function ensures that there will not be a copy beyond + the size of the destination buffer. + + This function should be used in preference to memscpy() if there + is the possiblity of source and destination buffers overlapping. + The result of the operation is defined to be as if the copy were from + the source to a temporary buffer that overlaps neither source nor + destination, followed by a copy from that temporary buffer to the + destination. + + @param[out] dst Destination buffer. + @param[in] dst_size Size of the destination buffer in bytes. + @param[in] src Source buffer. + @param[in] src_size Number of bytes to copy from source buffer. + + @return + The number of bytes copied to the destination buffer. It is the + caller's responsibility to check for trunction if it cares about it - + truncation has occurred if the return value is less than src_size. + + @dependencies + None. +*/ + +size_t memsmove(void *dst, size_t dst_size, const void *src, size_t src_size); + +/** + memsmove_i - Inline function for size bounded memory move. + + @see memsmove() +*/ + +static __inline size_t memsmove_i +( + void *dst, + size_t dst_size, + const void *src, + size_t src_size +) +{ + size_t copy_size = (dst_size <= src_size)? dst_size : src_size; + + memmove(dst, src, copy_size); + + return copy_size; +} + +/** + secure_memset - Memset functionality that won't be optimized by the compiler + + Memsets a memory location to a given value in a way that is unlikely to be + removed by the compiler + + A classic compiler optimization is to remove references to instructions that + assign a value to a variable where that variable is never used after the + assignment. However, this means that compilers will often remove memset + instructions which are used to "zero" sensitive information in stack or heap + memory, which can cause a security risk. This function performs a basic + memset operation, but should always be instantiated in its own file, this + will mean file optimizers will not be able to optimize its use and linkers + do not have sufficient intelligence to optimize calls between files. + + This function should be used when clearing sensitive information in memory. + + @param[in] ptr Points to the memory area to be set. + @param[in] value The value to be set. + @param[in] len The number of bytes to be set. + + @return + This function returns the pointer to the memory area ptr. + + @dependencies + None. +*/ + +void* secure_memset(void* ptr, int value, size_t len); + +/** + * @} + */ + + +/** @defgroup time_safe_ops Time Safe Memory Operation APIs + * @{ + */ + +/** + timesafe_memcmp - Constant-time memory comparison + + Compares bytes at two different sections in memory in constant time + + This function compares the len bytes starting at ptr1 with the len + bytes starting at ptr2. The function returns 1 if the two sections + of memory are different and 0 if the two sections of memory are + identical. The function always scans the entire range of memory to + ensure the function runs in constant time. + + This function should be used when comparing confidential information + in memory as it prevents timing attacks. A traditional memcmp() exits + after finding non-equal bytes and this can be used to determine the value + of confidential data in memory. Examples uses include password checks, + MACs checks, decryption checks, and checks on private user information. + + @param[in] ptr1 Points to the first memory bytes to be compared. + @param[in] ptr2 Points to the second memory bytes to be compared. + @param[in] len The number of bytes to be compared. + + @return + This function returns 1 if the two buffers are different and + 0 if the two buffers are identical. + + @dependencies + None. +*/ + +int timesafe_memcmp(const void* ptr1, const void* ptr2, size_t len); + +/** + timesafe_strncmp - Constant-time string comparison + + Compares bytes in two different string buffers in constant time + + This function compares the contents of the string buffer at ptr1 with + the string buffer at ptr2 up to a maximum of len bytes. The function + does not compare bytes beyond the first occurrence of a NULL byte. The + function returns 1 if the two strings are different and 0 if the strings + are identical. The function always scans the entire range of memory to + ensure the function runs in constant time. + + This function shuld be used when comparing strings that contain confidential + information as it prevents timing attacks. A traditional strncmp() exits + after finding non-equal bytes or a NULL byte and this can be used to + determine the value of confidential data in memory. + + @param[in] ptr1 Points to the first string to be compared. + @param[in] ptr2 Points to the second string to be compared. + @param[in] len The number of bytes to be compared. + + @return + This function returns 1 if the strings are different and + 0 if the strings are the same. + + @dependencies + None. +*/ + +int timesafe_strncmp(const char* ptr1, const char* ptr2, size_t len); +/** + * @} + */ + + /** @addtogroup str_apis + @{ */ +/** + strnlen - Determine the length of a fixed size string + + This function takes a maxlen length parameter and stops looking for a NULL + character if it passes the maxlen length. It is considered safer than + strlen because it will not enter an endless loop if the source string + is a bad string without NULL termination. + + @param[in] str Points to the source string. + @param[in] maxlen The maximum number of bytes to count. + + @return + This function returns the number of bytes in string pointed to by str, + excluding the terminating NULL byte ('\0'), but at most maxlen. + + @dependencies + None. +*/ +#ifndef _WIN32 +size_t strnlen(const char *str, size_t maxlen); +#endif + +/** + * @} + */ +#ifdef __cplusplus + } //extern "C" +} //namespace std +#endif //__cplusplus + +//Explicit export of the libstd implemented functions +#ifdef __cplusplus +#ifdef _WIN32 + using std::strlcat; + using std::strlcpy; + using std::strcasecmp; + using std::strncasecmp; +#endif + using std::wcslcat; + using std::wstrlcat; + using std::wcslcpy; + using std::wstrlcpy; + using std::wstrcmp; + using std::wstrncmp; + using std::wstrlen; + using std::memscpy; + using std::memsmove; + using std::secure_memset; + using std::timesafe_memcmp; + using std::timesafe_strncmp; +#ifndef _WIN32 + using std::strnlen; +#endif +#endif //__cplusplus + +#endif /* _STRINGL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.md new file mode 100755 index 0000000000000..a80878d828e28 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/stringl.md @@ -0,0 +1,51 @@ +# Prototypes for string manipulation functions + +## Introduction {#introduction} + +`stringl.h` contains function prototypes for various string manipulation functions. These are considered safer than the standard C string manipulation functions and were developed as part of the [OpenBSD project](https://www.openbsd.org/). + +## API Overview {#api-overview} + +The stringl.h APIs include the following functions: + +* ::strlcat + +* ::wcslcat + +* ::wstrlcat + +* ::strlcpy + +* ::wcslcpy + +* ::wstrlcpy + +* ::wstrlen + +* ::wstrcmp + +* ::wstrncmp + +* ::strcasecmp + +* ::strncasecmp + +* ::std_scanul + +* ::memscpy + +* ::memscpy_i + +* ::memsmove + +* ::memsmove_i + +* ::secure_memset + +* ::timesafe_memcmp + +* ::timesafe_strncmp + +* ::strnlen + +Header file: @b stringl.h diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/synx.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/synx.md new file mode 100755 index 0000000000000..21bc9a9a18386 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/synx.md @@ -0,0 +1,7 @@ +## Overview + +Heterogeneous Systems involve more than one core to efficiently process a task. Nowadays, there are lot of new advanced use cases that require computation across multiple cores. One example of such use case is for the camera core to capture an image, pass it on to DSP and/or GPU cores for post processing and send the final output to the display subsystem for rendering. Such use cases involve transferring of control points and sharing of buffers across multiple cores. This type of application use case drives the need for a generic synchronization framework which explicitly describes dependencies between different asynchronous operations across the SoC. + +The synx framework helps to capture such dependencies across cores. It notifies task completions and /or buffer ready information between a producer and consumers. + +***Note***: There are many synchronization/fence mechanisms available today but those work best within a single core/device. In Android systems, buffers are usually allocated as ION buffers so that these buffer can be shared across various components (UMD, KMD, and HW). If another core needs to access such buffers, we need to synchronously transfer control (along with data payload) from one core to the other. This explicit transfer of control from one core to the other eliminates the possibilities of optimization and hence drives the idea of introducing synx handle for synchronization. diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.h new file mode 100755 index 0000000000000..e46e7d7f25a29 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.h @@ -0,0 +1,109 @@ +/*----------------------------------------------------------------------------- + Copyright (c) 2017-2020 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------------*/ + +#ifndef SYSMON_CACHELOCK_H_ +#define SYSMON_CACHELOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file sysmon_cachelock.h + * @brief CDSP L2 cache locking manager API + */ + +/** + * Allocates a memory buffer, locks it in L2 cache, and returns the locked + * virtual address. + * + * @param[in] size Memory size (in bytes) to lock. + * @param[out] paddr_ptr Pointer to @c unsigned @c long @c long + * variable to get the locked 64-bit physical address upon + * success. NULL if the allocation and cache lock failed. + * + * @return + * @c void* Virtual address of the locked memory region. \n + * 0 if the requested buffer size could not be allocated and locked in the L2 cache. + */ +void* HAP_cache_lock(unsigned int size, unsigned long long *paddr_ptr); + + +/** + * Unlocks cache and deallocates memory for a virtual address returned by + * the corresponding HAP_cache_lock() call. + * + * @param[in] vaddr_ptr Virtual address of the memory block to unlock. + * + * @return + * 0 upon success. \n + * Other values upon failure. + */ +int HAP_cache_unlock(void* vaddr_ptr); + +/** + * Locks the cache for a given virtual address and memory size (in bytes). + * + * Align the address and size to 32 bytes. The size should not be more + * than 64 KB, and at any point of time, only one such request is honored + * (this restriction has been removed from SM8250 onwards). + * + * Use this function to lock an existing memory block, for example, + * to lock a code segment or data buffer. Note that whenever possible, it is + * preferable to let the driver allocate the memory to be locked in L2 via the + * HAP_cache_lock API, as it can often avoid the fragmentation likely to occur + * when the user provides the memory ranges to be locked. + * + * @param[in] vaddr_ptr Virtual address of the memory block to lock; should be + * 32-byte aligned. + * @param[in] size Memory size (in bytes) to lock; should be 32-byte aligned. + * The maximum size limit is 64 KB. From SM8250, this size limit is + * the same as HAP_cache_lock(). + * + * @return + * 0 upon success. \n + * Others values upon failure. + */ +int HAP_cache_lock_addr(void* vaddr_ptr, unsigned int size); + +/** + * Unlocks the cache for a given virtual address. + * + * Use this function together with HAP_cache_lock_addr(). + * + * @param[in] vaddr_ptr Virtual address of the memory block to unlock. + * + * @return + * 0 upon success. \n + * Other values upon failure. + */ +int HAP_cache_unlock_addr(void* vaddr_ptr); + +/** + * Queries the API to get the size of largest contiguous memory block available for + * cache locking. + * + * @return + * Available size in bytes upon success. \n + * -1 upon failure. + */ +int HAP_query_avail_cachelock(void); + +/** + * Queries the API to get the total locked cache size. + * + * @return + * Total locked cache size in bytes upon success. \n + * -1 upon failure. + */ +int HAP_query_total_cachelock(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* SYSMON_CACHELOCK_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.md new file mode 100755 index 0000000000000..44efd95724811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_cachelock.md @@ -0,0 +1,25 @@ +# Cache locking manager + +The cache locking manager locks a section of the L2 cache from the +cDSP, and subsequently releases this lock. + +The cache locking manager replaces the HAP_power_set APIs that are now deprecated. +This new cache locking manager utilizes available L2 cache by +allocating memory with appropriately aligned address based on L2 cache +availability and the request size. The cache locking manager also limits +maximum cache that can be locked to guarantee performance of the guest OS and +FastRPC threads. + +The cache locking manager monitors cache locking usage by providing +APIs to get the maximum available cache size for locking and the total +currently locked cache. + +Finally, a set of APIs passes the address of the memory to lock +along with its size information. These APIs are useful for applications where a +linker-defined section (code/library) must be locked into cache. + +The cache locking manager APIs are not accessible from unsigned PD. + +## Framework APIs + +Header file: @b sysmon_cachelock.h diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.h new file mode 100755 index 0000000000000..bcf34d1f80059 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.h @@ -0,0 +1,46 @@ +/*----------------------------------------------------------------------- + Copyright (c) 2017-2020 QUALCOMM Technologies, Incorporated. + All Rights Reserved. + QUALCOMM Proprietary. +-----------------------------------------------------------------------*/ +#ifndef SYSMON_MARKER_H +#define SYSMON_MARKER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file sysmon_marker.h + * @brief Sysmon profiling marker API + * Allows the user to profile a piece of code or + * algorithm of interest. + */ + +/** + * Enables or disables a profiling marker. + + * @param[in] marker Any unique, customer-defined, unsigned number to identify profiling + data mapped to a section of code. + * @param[in] enable Flag to enable (1) or disable (1) the profiling marker. + * + * For example: + * @code + * #include + * // or, alternatively, + * // extern HP_profile(unsigned int marker, unsigned char enable); + * + * HP_profile(10, 1); + * // ... + * // User code to profile + * // ... + * HP_profile(10, 0); + * @endcode + */ +void HP_profile(unsigned int marker, unsigned char enable); + +#ifdef __cplusplus +} +#endif + +#endif /*SYSMON_MARKER_H*/ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.md b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.md new file mode 100755 index 0000000000000..d25fbdd30f102 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/sysmon_marker.md @@ -0,0 +1,36 @@ +# sysMon marker + +The sysMon marker API profiles a specific code region to study its own load on the processor compute resources and the bus bandwidth, and captures various other profiling metrics associated to that specific code region. +This approach is useful when measuring performance, debugging performance-related issues or identifying possible optimizations for a specific code region instead of profiling the entire application. + +This API is not supported in unsigned PD and CPZ. + +## Collect profiling data + +Once the code has been instrumented with the sysMon marker APIs to enable and disable profiling of specific code regions, the [sysMonApp profiler](../../tools/sysmon_app.html#profiler-service) +must run to collect sysMon marker data. + +If DCVS is enabled by the user, the decisions taken by DCVS with profiling markers enabled might not be the same as without markers. + +## Parsing profiling data with sysMon marker + +Profiling data captured using the [sysMonApp profiler](../../tools/sysmon_app.html#profiler-service) can be parsed using the [sysMon parser](../../tools/sysmon_parser.html). +Refer [STID and markers data](../../tools/sysmon_parser.html#stid-and-markers-data) section for the output files generated by the sysMon parser when sysMon markers are enabled. + +## Limitations + +* Nested markers are not supported + + For example, the following piece of code does not produce the expected profiling data; its behavior is undefined. + + HP_profile(10, 1); + // ... user code ... + HP_profile(11, 1); + // ... user code ... + HP_profile(11, 0); + // ... user code ... + HP_profile(10, 0); + +* Enabling profiling markers forces collection of profiling data on all hardware threads. + + Profiling statistics are collected for any entity running in parallel with the piece of code where markers are defined. diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/utils.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/utils.h new file mode 100755 index 0000000000000..57a5dd96b2930 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/utils.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020 QUALCOMM Technologies Inc. All Rights Reserved. + * Qualcomm Technologies Confidential and Proprietary + * + */ + +#ifdef __cplusplus +extern "C" { +#endif +size_t memscpy(void* dst, size_t dst_size, const void* src, size_t src_size); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/verify.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/verify.h new file mode 100755 index 0000000000000..dea9f22172089 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/verify.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012-2013, 2020 QUALCOMM Technologies Inc. + * All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef VERIFY_H +#define VERIFY_H + + +#ifndef _WIN32 +#define C_ASSERT(test) \ + switch(0) {\ + case 0:\ + case test:;\ + } +#endif // _WIN32 + +#ifndef __V_STR__ + #define __V_STR__(x) #x ":" +#endif //__STR__ +#ifndef __V_TOSTR__ + #define __V_TOSTR__(x) __V_STR__(x) +#endif // __TOSTR__ +#ifndef __V_FILE_LINE__ + #define __V_FILE_LINE__ __FILE__ ":" __V_TOSTR__(__LINE__) +#endif /*__FILE_LINE__*/ + + +#ifdef __ANDROID__ +/*android */ +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) __android_log_print(ANDROID_LOG_DEBUG , "adsprpc", __V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) __android_log_print(ANDROID_LOG_ERROR , "adsprpc", __V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +/* end android */ +#elif (defined __hexagon__) || (defined __qdsp6__) +/* q6 */ + +#ifdef VERIFY_PRINT_INFO + #define FARF_VERIFY_LOW 1 + #define FARF_VERIFY_LOW_LEVEL HAP_LEVEL_LOW + #define VERIFY_IPRINTF(args...) FARF(VERIFY_LOW, args) +#endif + +#ifdef VERIFY_PRINT_ERROR + #define FARF_VERIFY_ERROR 1 + #define FARF_VERIFY_ERROR_LEVEL HAP_LEVEL_ERROR + #define VERIFY_EPRINTF(args...) FARF(VERIFY_ERROR, args) +#endif + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) + #include "HAP_farf.h" +#endif + +/* end q6 */ +#elif (defined USE_SYSLOG) +/* syslog */ +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) syslog(LOG_USER|LOG_INFO, __V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) syslog(LOG_USER|LOG_ERR, __V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +/* end syslog */ +#else +/* generic */ + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#endif + +/* end generic */ +#endif + +#ifndef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFYC + #define VERIFYC(val,err_code) \ + do {\ + VERIFY_IPRINTF(":info: calling: %s", #val);\ + if(0 == (val)) {\ + nErr = err_code;\ + VERIFY_EPRINTF(":error: %d: %s", nErr, #val);\ + goto bail;\ + } else {\ + VERIFY_IPRINTF(":info: passed: %s", #val);\ + }\ + } while(0) +#endif //VERIFYC + +#ifndef VERIFY + #define VERIFY(val) \ + do {\ + VERIFY_IPRINTF(":info: calling: %s", #val);\ + if(0 == (val)) {\ + nErr = nErr == 0 ? -1 : nErr;\ + VERIFY_EPRINTF(":error: %d: %s", nErr, #val);\ + goto bail;\ + } else {\ + VERIFY_IPRINTF(":info: passed: %s", #val);\ + }\ + } while(0) +#endif //VERIFY + +#endif //VERIFY_H + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/version.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/version.h new file mode 100755 index 0000000000000..2e3f0ad3278ff --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/version.h @@ -0,0 +1,91 @@ +#ifndef VERSION_H +#define VERSION_H +/*=========================================================================== + +FILE: version.h + +SERVICES: Hexagon Access Program (HAP) SDK version_string + +GENERAL DESCRIPTION: + Definitions for versioning + + Copyright 2012 QUALCOMM Incorporated. + All Rights Reserved. + QUALCOMM Proprietary/GTDR +===========================================================================*/ + +#define VERSION_MAJOR 6 +#define VERSION_MINOR 2 +#define VERSION_MAINT 0 +#define VERSION_BUILD 1 + +#define VERSION_STRING "HAP SDK 6.2.0.1 (srvr=qtcp406;br=main;cl=1242374)" + + +/* +======================================================================= +MACROS DOCUMENTATION +======================================================================= + +VERSION_MAJOR + +Description: + Defines the major release number + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_MINOR + +Description: + Defines the minor release number + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_MAINT + +Description: + Defines the maintenance release + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_BUILD + +Description: + Defines the build ID + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_STRING + +Description: + Defines the version string + +Definition: + + #define VERSION_STRING "a.b.c.d (name=value;name=value;...)" + where a=major release number + b=minor release number + c=maintenance release number + d=build number + + name=value pair provides additional information about the build. + Example: + patch/feature=comma separated list of features/patches that have been installed. + br=p4 branch that was used for the build + cl=p4 change list number + machine=hostname of the machine that was used for the build. + +Comments: + +======================================================================= +*/ + +#endif // VERSION_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/incs/version_note.h b/prebuilts/Hexagon_SDK/6.2.0.1/incs/version_note.h new file mode 100755 index 0000000000000..10e498546cc98 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/incs/version_note.h @@ -0,0 +1,19 @@ +/*============================================================================== + Copyright (c) 2022, 2023 Qualcomm Technologies, Inc. + All rights reserved. Qualcomm Proprietary and Confidential. +==============================================================================*/ + +#ifndef VERSION_NOTE_H +#define VERSION_NOTE_H +#define VERSION_NOTE_LENGTH 100 + + typedef struct { + int sizename; //Size of the NOTE section + int sizedesc; // Size of the descriptor(unused) + int type; // Type of section(unused)//stores version and library name + char name[VERSION_NOTE_LENGTH]; // Name of NOTE section(version of shared object) + int desc[3]; // used for labeling note segment version (lib.ver.V1.V2.V3) + } lib_ver_note_t; + +#endif //VERSION_NOTE_H + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/incs/mmdefs.h b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/incs/mmdefs.h new file mode 100755 index 0000000000000..3fdc11dcb810e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/incs/mmdefs.h @@ -0,0 +1,48 @@ +#ifndef _MMDEFS_H +#define _MMDEFS_H +/*============================================================================== + Copyright (c) 2012-2013 Qualcomm Technologies Incorporated. + All Rights Reserved Qualcomm Technologies Proprietary + + Export of this technology or software is regulated by the U.S. + Government. Diversion contrary to U.S. law prohibited. +==============================================================================*/ + +/*------------------------------------------------------------------------------ + Standard Integer Types +------------------------------------------------------------------------------*/ + +#include "stdint.h" + +/*------------------------------------------------------------------------------ + Constants +------------------------------------------------------------------------------*/ + +#undef TRUE +#undef FALSE + +#define TRUE (1) /* Boolean true value */ +#define FALSE (0) /* Boolean false value */ + +#ifndef NULL + #define NULL (0) +#endif + +/*------------------------------------------------------------------------------ + Character and boolean +------------------------------------------------------------------------------*/ + +typedef char char_t; /* Character type */ +typedef unsigned char bool_t; /* Boolean value type */ + +/*============================================================================== + FUNCTION : align_to_8_byte + DESCRIPTION: Ceil to the next multiple of 8 +==============================================================================*/ +static inline uint32_t align_to_8_byte(const uint32_t num) +{ + return ((num + 7) & (0xFFFFFFF8)); +} + +#endif /* _MMDEFS_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc.so new file mode 100755 index 0000000000000..572796d03718b Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc_system.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc_system.so new file mode 100755 index 0000000000000..e6b5daae76dbb Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libadsprpc_system.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc.so new file mode 100755 index 0000000000000..266cb63c8ded7 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc_system.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc_system.so new file mode 100755 index 0000000000000..c9a05c047d815 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libcdsprpc_system.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc.so new file mode 100755 index 0000000000000..78fa7b7e84b9d Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc_system.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc_system.so new file mode 100755 index 0000000000000..3b9783f2bc1d3 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libmdsprpc_system.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc.so new file mode 100755 index 0000000000000..d7e3d46f9b141 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc_system.so b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc_system.so new file mode 100755 index 0000000000000..588ed0b72f2fb Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/remote/ship/android_aarch64/libsdsprpc_system.so differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/inc/rpcmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/inc/rpcmem.h new file mode 100755 index 0000000000000..281890ef5fbf0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/inc/rpcmem.h @@ -0,0 +1,248 @@ +/*============================================================================== + Copyright (c) 2012-2013, 2020 Qualcomm Technologies, Inc. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +==============================================================================*/ + +#ifndef RPCMEM_H +#define RPCMEM_H + +#include "AEEStdDef.h" +#include "stddef.h" + +/** + * @file rpcmem.h + * @brief APIs used to manage memory allocated by the application processor and shared with the DSP. + */ + +/** @defgroup rpcmem_const RPCMEM API macros and enumerations + * @{ + */ + +/** + * Allocate memory with the same properties as the ION_FLAG_CACHED flag. + */ +#ifdef ION_FLAG_CACHED +#define RPCMEM_DEFAULT_FLAGS ION_FLAG_CACHED +#else +#define RPCMEM_DEFAULT_FLAGS 1 +#endif + +/** + * The FastRPC library tries to map buffers allocated with this flag to the remote process of all current and new + * FastRPC sessions. In case of failure to map, the FastRPC library ignores the error and continues to open the session + * without pre-mapping the buffer. In case of success, buffers allocated with this flag will be pre-mapped to reduce + * the latency of upcoming FastRPC calls. This flag is recommended only for buffers that are used with latency-critical + * FastRPC methods. Pre-mapped buffers will be unmapped during either buffer free or session close. + */ +#define RPCMEM_TRY_MAP_STATIC 0x04000000 + +/** + * Supported RPCMEM heap IDs. + * + * If you are not using any of the RPCMEM-defined heap IDs, + * you are responsible for ensuring that you are passing + * a valid ION heap ID. + */ +enum rpc_heap_ids { +/** + * Memory for secure use cases only. + * * Secure heap is to be used only by clients migrating to CPZ + */ + RPCMEM_HEAP_ID_SECURE = 9, +/** + * Contiguous physical memory: + * * Very limited memory is available (< 8 MB) + * * Recommended for subsystems without SMMU (sDSP and mDSP) + * * Contiguous heap memory will be deprecated from archs after v73 + */ + RPCMEM_HEAP_ID_CONTIG = 22, +/** + * Non-contiguous system physical memory. + * * Recommended for all use cases that do not require using a specific heap + * * Used with subsystems with SMMU (cDSP and aDSP) + */ + RPCMEM_HEAP_ID_SYSTEM = 25, + }; + +/** + * Use uncached memory. + */ +#define RPCMEM_FLAG_UNCACHED 0 + +/** + * Use cached memory. + */ +#define RPCMEM_FLAG_CACHED RPCMEM_DEFAULT_FLAGS + +/** + * @} + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup rpcmem_api RPCMEM API functions + * @{ + */ + +/** + * Initialize the RPCMEM Library. + * + * Only call this function once before using the RPCMEM Library. + * + * This API is mandatory on pre-Lahaina targets IF the client has linked to the + * rpcmem.a static library. If the client has only linked libadsprpc.so, + * libcdsprpc.so, or libsdsprpc.so, then the rpcmem_init call is not required + * on any target and other rpcmem APIs such as rpcmem_alloc can be called + * directly. + * + * NOTE: This function is not thread safe. + */ +void rpcmem_init(void); + +/** + * Deinitialize the RPCMEM Library. + * + * Only call this function once when the RPCMEM Library is no longer required. + * + * This API is mandatory on pre-Lahaina targets IF the client has linked to the + * rpcmem.a static library. If the client has only linked libadsprpc.so, + * libcdsprpc.so, or libsdsprpc.so, then the rpcmem_deinit call is not required + * on any target. + * + * NOTE: This function is not thread safe. + */ +void rpcmem_deinit(void); + +/** + * Allocate a zero-copy buffer for size upto 2 GB with the FastRPC framework. + * Buffers larger than 2 GB must be allocated with rpcmem_alloc2 + * @param[in] heapid Heap ID to use for memory allocation. + * @param[in] flags ION flags to use for memory allocation. + * @param[in] size Buffer size to allocate. + * @return Pointer to the buffer on success; NULL on failure. + * + * Examples: + * + * * Default memory attributes, 2 KB + * @code + * rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, 2048); + * @endcode + * Or + * @code + * rpcmem_alloc_def(2048); + * @endcode + * + * * Heap 22, uncached, 1 KB + * @code + * rpcmem_alloc(22, 0, 1024); + * @endcode + * Or + * @code + * rpcmem_alloc(22, RPCMEM_FLAG_UNCACHED, 1024); + * @endcode + * + * * Heap 21, cached, 2 KB + * @code + * rpcmem_alloc(21, RPCMEM_FLAG_CACHED, 2048); + * @endcode + * Or + * @code + * #include + * rpcmem_alloc(21, ION_FLAG_CACHED, 2048); + * @endcode + * + * * Default memory attributes but from heap 18, 4 KB + * @code + * rpcmem_alloc(18, RPCMEM_DEFAULT_FLAGS, 4096); + * @endcode + */ +void* rpcmem_alloc(int heapid, uint32 flags, int size); + +/** + * Allocate a zero-copy buffer with the FastRPC framework. + * @param[in] heapid Heap ID to use for memory allocation. + * @param[in] flags ION flags to use for memory allocation. + * @param[in] size Buffer size to allocate. + * @return Pointer to the buffer on success; NULL on failure. + * + * Examples: + * + * * The usage examples are same as rpcmem_alloc. + */ +void* rpcmem_alloc2(int heapid, uint32 flags, size_t size); + +/** + * Allocate a buffer with default settings. + * @param[in] size Size of the buffer to be allocated. + * @return Pointer to the allocated memory buffer. + */ + #if !defined(WINNT) && !defined (_WIN32_WINNT) +__attribute__((unused)) +#endif +static __inline void* rpcmem_alloc_def(int size) { + return rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, size); +} + +/** + * Free a buffer and ignore invalid buffers. + */ +void rpcmem_free(void* po); + +/** + * Return an associated file descriptor. + * @param[in] po Data pointer for an RPCMEM-allocated buffer. + * @return Buffer file descriptor. + */ +int rpcmem_to_fd(void* po); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +//! @cond Doxygen_Suppress +/** These macros are deprecated. + */ +#define RPCMEM_DEFAULT_HEAP -1 +#define RPCMEM_HEAP_DEFAULT 0x80000000 +#define RPCMEM_HEAP_NOREG 0x40000000 +#define RPCMEM_HEAP_UNCACHED 0x20000000 +#define RPCMEM_HEAP_NOVA 0x10000000 +#define RPCMEM_HEAP_NONCOHERENT 0x08000000 +#define RPCMEM_FORCE_NOFLUSH 0x01000000 +#define RPCMEM_FORCE_NOINVALIDATE 0x02000000 +// Use macros from libion instead +#define ION_SECURE_FLAGS ((1 << 31) | (1 << 19)) +//! @endcond + +#endif //RPCMEM_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/src/verify.h b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/src/verify.h new file mode 100755 index 0000000000000..71b37828c0646 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/ipc/fastrpc/rpcmem/src/verify.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2012-2020 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef VERIFY_H +#define VERIFY_H + + +//#define VERIFY_PRINT_ERROR +//#define VERIFY_PRINT_INFO + + +#ifndef _WIN32 +#define C_ASSERT(test) \ + switch(0) {\ + case 0:\ + case test:;\ + } +#endif // _WIN32 + +#ifndef __V_STR__ + #define __V_STR__(x) #x ":" +#endif //__STR__ +#ifndef __V_TOSTR__ + #define __V_TOSTR__(x) __V_STR__(x) +#endif // __TOSTR__ +#ifndef __V_FILE_LINE__ + #define __V_FILE_LINE__ __FILE__ ":" __V_TOSTR__(__LINE__) +#endif /*__FILE_LINE__*/ + + +// TODO:sunny - enabled extra prints +#define VERIFY_PRINT_INFO +#define VERIFY_PRINT_ERROR + + +#ifdef __ANDROID__ +/*android */ +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include +#endif + +extern const char* __progname; +#ifdef VERIFY_PRINT_INFO +#ifdef __ANDROID__ +#define VERIFY_IPRINTF(format, ...) __android_log_print(ANDROID_LOG_DEBUG , __progname, __V_FILE_LINE__ format, ##__VA_ARGS__) +#else /* !__ANDROID__ */ +#define VERIFY_IPRINTF(format, ...) fprintf(stderr,"%s:%d " _fmt "\n", __func__, __LINE__ , ##__VA_ARGS__) +#endif /* __ANDROID__ */ +#endif + +#ifdef VERIFY_PRINT_ERROR +#ifdef __ANDROID__ +#define VERIFY_EPRINTF(format, ...) __android_log_print(ANDROID_LOG_ERROR , __progname, __V_FILE_LINE__ format, ##__VA_ARGS__) +#else /* !__ANDROID__ */ +#define VERIFY_EPRINTF(format, ...) fprintf(stderr,"%s:%d " _fmt "\n", __func__, __LINE__ , ##__VA_ARGS__) +#endif /* __ANDROID__ */ +#endif + +/* end android */ +#elif (defined __hexagon__) || (defined __qdsp6__) +/* q6 */ + +#ifdef VERIFY_PRINT_INFO + #define FARF_VERIFY_LOW 1 + #define FARF_VERIFY_LOW_LEVEL HAP_LEVEL_LOW + #define VERIFY_IPRINTF(args...) FARF(VERIFY_LOW, args) +#endif + +#ifdef VERIFY_PRINT_ERROR + #define FARF_VERIFY_ERROR 1 + #define FARF_VERIFY_ERROR_LEVEL HAP_LEVEL_ERROR + #define VERIFY_EPRINTF(args...) FARF(VERIFY_ERROR, args) +#endif + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) + #include "HAP_farf.h" +#endif + +/* end q6 */ +#else +/* generic */ + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +/* end generic */ +#endif + +#ifndef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFY + #define VERIFY(val) \ + do {\ + VERIFY_IPRINTF(":info: calling: " #val "\n");\ + if(0 == (val)) {\ + nErr = nErr == 0 ? -1 : nErr;\ + VERIFY_EPRINTF(":error: %d: " #val "\n", nErr);\ + goto bail;\ + } else {\ + VERIFY_IPRINTF(":info: passed: " #val "\n");\ + }\ + } while(0) +#endif //VERIFY + +#ifndef VERIFYC + #define VERIFYC(val,err_code) \ + do {\ + VERIFY_IPRINTF(":info: calling: " #val "\n");\ + if(0 == (val)) {\ + nErr = err_code;\ + VERIFY_EPRINTF(":Error: %x: " #val "\n", nErr);\ + goto bail;\ + } else {\ + VERIFY_IPRINTF(":info: passed: " #val "\n");\ + }\ + } while(0) +#endif //VERIFYC + + +#endif /* VERIFY_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/libs/atomic/inc/AEEatomic.h b/prebuilts/Hexagon_SDK/6.2.0.1/libs/atomic/inc/AEEatomic.h new file mode 100755 index 0000000000000..0b4a7b9cb6be9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/libs/atomic/inc/AEEatomic.h @@ -0,0 +1,173 @@ +#ifndef AEEATOMIC_H +#define AEEATOMIC_H +/* +======================================================================= + +FILE: AEEatomic.h + +SERVICES: atomic + +DESCRIPTION: Fast Atomic ops + +======================================================================= + Copyright 2005, 2007 Qualcomm Technologies Incorporated. + All Rights Reserved. + QUALCOMM Confidential and Proprietary +======================================================================= +*/ + +#include "AEEStdDef.h" + +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ + +uint32 atomic_Add(uint32 * volatile puDest, int nAdd); +uint32 atomic_Exchange(uint32 * volatile puDest, uint32 uVal); +uint32 atomic_CompareAndExchange(uint32 * volatile puDest, uint32 uExchange, uint32 uCompare); +uint32 atomic_CompareOrAdd(uint32 * volatile puDest, uint32 uCompare, int nAdd); + +uint64 atomic_CompareAndExchange64(uint64 * volatile puDest, uint64 uExchange, uint64 uCompare); +uintptr_t atomic_CompareAndExchangeUP(uintptr_t * volatile puDest, uintptr_t uExchange, uintptr_t uCompare); +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ + +/*===================================================================== +INTERFACE DOCUMENTATION +======================================================================= +atomic Interface + + The atomic interface provides fast "atomic" operations. The + operations are defined to be atomic with respect to each other. + +======================================================================= + +======================================================================= + +atomic_Add() + +Description: + + Performs an atomic sum operation. + +Prototype: + + uint32 atomic_Add(uint32* puDest, int nInc); + +Parameters: + puDest [in|out] : Points to unsigned number to add nInc and save + nInc : increment + +Return Value: + result. + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= + +atomic_Exchange() + +Description: + + Atomic exchange of 32bit value. Performs an atomic operation of : + write uVal to *puDest + return the previous value in *puDest + +Prototype: + + uint32 atomic_Exchange(uint32* puDest, uint32 uVal); + +Parameters: + puDest [in|out] : Points to unsigned number to be exchanged + uVal : new value to write. + +Return Value: + previous value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None +======================================================================= + +atomic_CompareAndExchange() + +Description: + + Performs an atomic operation of : + if (*puDest == uCompare) { + *puDest = uExchange; + } + + returns the previous value in *puDest + +Prototype: + + uint32 atomic_CompareAndExchange(uint32 *puDest, uint32 uExchange, + uint32 uCompare); + +Parameters: + puDest [in|out] : Points to unsigned number. + uExchange : A new value to write to *puDest + uCompare : Comparand + +Return Value: + previous value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None + +======================================================================= +atomic_CompareOrAdd() + +Description: + + Performs an atomic operation of : + if (*puDest != uCompare) { + *puDest += nAdd; + } + + returns the new value in *puDest + +Prototype: + + uint32 atomic_CompareOrAdd(uint32 *puDest, uint32 uCompare, int nAdd); + +Parameters: + puDest [in|out] : Points to unsigned number. + uCompare : Comparand + nAdd : Add to *puDest + +Return Value: + new value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None +=======================================================================*/ + +#endif /* #ifndef AEEATOMIC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf.h b/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf.h new file mode 100755 index 0000000000000..cfa7b98d050bc --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf.h @@ -0,0 +1,170 @@ +/**============================================================================= + +@file + qprintf.h + +@brief + API, macros and struct definitions for qprintf utilities available from C. + +Copyright (c) 2017, 2020 QUALCOMM Technologies Incorporated. +All Rights Reserved Qualcomm Proprietary +=============================================================================**/ + +#ifndef qprintf_H +#define qprintf_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "hexagon_types.h" +#include "stdlib.h" + +#ifdef BUILDING_SO +/// MACRO enables function to be visible in shared-library case. +#define qprintf_API __attribute__ ((visibility ("default"))) +#else +/// MACRO empty for non-shared-library case. +#define qprintf_API +#endif + +/** + * @defgroup Masks Common masks controlling which bytes to display. + * @{ + */ + +/// Display all bytes +#define QPRINTF_MASK_ALL -1ull + +/// Display no bytes +#define QPRINTF_MASK_NONE 0ull + +/// Display even bytes +#define QPRINTF_MASK_EVEN_8 0x5555555555555555ull + +/// Display odd bytes +#define QPRINTF_MASK_ODD_8 0xaaaaaaaaaaaaaaaaull + +/// Display even 16-bit elements +#define QPRINTF_MASK_EVEN_16 0x3333333333333333ull + +/// Display odd 16-bit elements +#define QPRINTF_MASK_ODD_16 0xccccccccccccccccull + +/// Display even 32-bit elements +#define QPRINTF_MASK_EVEN_32 0x0f0f0f0f0f0f0f0full + +/// Display odd 32-bit elements +#define QPRINTF_MASK_ODD_32 0xf0f0f0f0f0f0f0f0ull + +/** + * @} + */ + +/** + * @defgroup C_functions qprintf functions + * @{ + */ +//--------------------------------------------------------------------------- +/// @brief +/// Set the mask controlling which bytes to display when printing out an HVX +/// register. +/// +/// If the nth bit of mask is set, the nth byte of HVX will be displayed. +/// When printing HVX as 16-bit or 32-bit elements, only the bit corresponding +/// to the lowest byte of the element controls whether the element will be +/// printed out or not. +/// +/// @param high +/// Mask for upper 64 bytes of HVX vector. +/// +/// @param low +/// Mask for lower 64 bytes of HVX vector. +/// +/// @return +/// None. +/// +/// Example: +/// +/// * Display the 32-bit odd elements of the 64 most significant bytes and the even +/// bytes of the 64 least significant bytes of HVX vectors printed with option %%m. +/// @code +/// // From C before invoking your assembly routine +/// qprintf_set_mask(QPRINTF_MASK_ODD_32,QPRINTF_MASK_EVEN_8); +/// +/// // From assembly +/// qprintf("v0: %mx",v0); +/// @endcode +/// +/// See also \ref assembly-hvx-registers for more assembly examples using %%m. +//--------------------------------------------------------------------------- +qprintf_API void qprintf_set_mask(unsigned long long high, unsigned long long low); + +//--------------------------------------------------------------------------- +/// @brief +/// Print a V register. +/// +/// @param msg +/// Character string used to display V register. +/// +/// @param V +/// HVX vector register to display. +/// +/// @return +/// None. +/// +/// Example: See \ref c-hvx-registers for usage examples. +//--------------------------------------------------------------------------- +void qprintf_V(const char* msg, HVX_Vector V); + +//--------------------------------------------------------------------------- +/// @brief +/// Print a Q register. see documentation for details on supported format. +/// +/// @param msg +/// Character string used to display Q register. +/// +/// @param Q +/// HVX predicate register to display. +/// +/// @return +/// None. +/// +/// Example: See \ref c-predicate-registers for usage examples. +//--------------------------------------------------------------------------- +void qprintf_Q(const char* msg, HVX_VectorPred Q); + +//--------------------------------------------------------------------------- +/// @brief +/// Display all HVX registers. +/// +/// @return +/// None. +/// +/// Example: See \ref c-register-dump for usage examples. +//--------------------------------------------------------------------------- +extern qprintf_API void qprintf_V_all(void); + + +//--------------------------------------------------------------------------- +/// @brief +/// Display all scalar registers. +/// +/// @return +/// None. +/// +/// Example: See \ref c-register-dump for usage examples. +//--------------------------------------------------------------------------- +extern qprintf_API void qprintf_R_all(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef qprintf_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf_asm.h b/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf_asm.h new file mode 100755 index 0000000000000..9fb27cc8ff8d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/libs/qprintf/inc/qprintf_asm.h @@ -0,0 +1,73 @@ +/**============================================================================= + +@file + qprintf_asm.h + +@brief + Extend printf support to assembly. + +Copyright (c) 2017,2020 QUALCOMM Technologies Incorporated. +All Rights Reserved Qualcomm Proprietary +=============================================================================**/ + +/** + * @defgroup ASM_function qprintf routine assembly-callable + * @{ + */ + +//--------------------------------------------------------------------------- +/// @brief +/// Assembly macro for displaying registers along with a message and +/// filename[linenumber]. +/// +/// @param MSG +/// Message to display. +/// +/// @return +/// none. +/// +/// Example: See \ref assembly-support for usage examples. +//--------------------------------------------------------------------------- +#define qprintf(MSG,...) qprintf_macro #__FILE__, #__LINE__, MSG, #__VA_ARGS__ + +/** + * @} + */ + +//! @cond Doxygen_Suppress + +.set STACK_SIZE, 24 +.macro qprintf_macro FILE_NAME LINE_NUMBER MSG ARGS +.data +1: +.string "\MSG\()\0" +2: +.string "\ARGS\()\0" +3: +.string "\LINE_NUMBER\()\0" +4: +.string "\FILE_NAME\()\0" +.text + { + allocframe(#STACK_SIZE) // sp[STACK_SIZE]=r31:30 (sp refering to sp after stack allocation) + memd(r29 + #(-STACK_SIZE-8)) = r29:28 // sp[0]=r29:28 + r28 = ADD(PC,##1b@PCREL) + } { + memw(r29 + #8) = r28 // sp[8]=&msg + r28 = ADD(PC,##2b@PCREL) + } { + memw(r29 + #12) = r28 // sp[12]=&args + r28 = #\LINE_NUMBER\() + } { + memw(r29 + #16) = r28 // sp[12]=line_number + r28 = ADD(PC,##4b@PCREL) + } { + memw(r29 + #20) = r28 // sp[16]=&file_name + call qprintf_asm + } { + r28 = memw(r29 + #0) + deallocframe + } +.endm + +//! @endcond \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/confname.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/confname.h new file mode 100755 index 0000000000000..d9ca3135501e3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/confname.h @@ -0,0 +1,528 @@ +#ifndef CONFNAME_H +#define CONFNAME_H +/** + @file confname.h + @brief Named literals for 'name' argument of sysconf, pathconf + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly. Instead include unistd.h. For now since + toolchain doesnt provide a hook by including bits/confname.h, we stick this + header in QuRT's sys/types.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum +{ + _PC_LINK_MAX, +#define _PC_LINK_MAX _PC_LINK_MAX + _PC_MAX_CANON, +#define _PC_MAX_CANON _PC_MAX_CANON + _PC_MAX_INPUT, +#define _PC_MAX_INPUT _PC_MAX_INPUT + _PC_NAME_MAX, +#define _PC_NAME_MAX _PC_NAME_MAX + _PC_PATH_MAX, +#define _PC_PATH_MAX _PC_PATH_MAX + _PC_PIPE_BUF, +#define _PC_PIPE_BUF _PC_PIPE_BUF + _PC_CHOWN_RESTRICTED, +#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED + _PC_NO_TRUNC, +#define _PC_NO_TRUNC _PC_NO_TRUNC + _PC_VDISABLE, +#define _PC_VDISABLE _PC_VDISABLE + _PC_SYNC_IO, +#define _PC_SYNC_IO _PC_SYNC_IO + _PC_ASYNC_IO, +#define _PC_ASYNC_IO _PC_ASYNC_IO + _PC_PRIO_IO, +#define _PC_PRIO_IO _PC_PRIO_IO + _PC_SOCK_MAXBUF, +#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF + _PC_FILESIZEBITS, +#define _PC_FILESIZEBITS _PC_FILESIZEBITS + _PC_REC_INCR_XFER_SIZE, +#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE + _PC_REC_MAX_XFER_SIZE, +#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE + _PC_REC_MIN_XFER_SIZE, +#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE + _PC_REC_XFER_ALIGN, +#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN + _PC_ALLOC_SIZE_MIN, +#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN + _PC_SYMLINK_MAX, +#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX + _PC_2_SYMLINKS +#define _PC_2_SYMLINKS _PC_2_SYMLINKS +}; + +/* Values for the argument to `sysconf'. */ +enum +{ + _SC_ARG_MAX, +#define _SC_ARG_MAX _SC_ARG_MAX + _SC_CHILD_MAX, +#define _SC_CHILD_MAX _SC_CHILD_MAX + _SC_CLK_TCK, +#define _SC_CLK_TCK _SC_CLK_TCK + _SC_NGROUPS_MAX, +#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX + _SC_OPEN_MAX, +#define _SC_OPEN_MAX _SC_OPEN_MAX + _SC_STREAM_MAX, +#define _SC_STREAM_MAX _SC_STREAM_MAX + _SC_TZNAME_MAX, +#define _SC_TZNAME_MAX _SC_TZNAME_MAX + _SC_JOB_CONTROL, +#define _SC_JOB_CONTROL _SC_JOB_CONTROL + _SC_SAVED_IDS, +#define _SC_SAVED_IDS _SC_SAVED_IDS + _SC_REALTIME_SIGNALS, +#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + _SC_PRIORITY_SCHEDULING, +#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + _SC_TIMERS, +#define _SC_TIMERS _SC_TIMERS + _SC_ASYNCHRONOUS_IO, +#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + _SC_PRIORITIZED_IO, +#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO + _SC_SYNCHRONIZED_IO, +#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + _SC_FSYNC, +#define _SC_FSYNC _SC_FSYNC + _SC_MAPPED_FILES, +#define _SC_MAPPED_FILES _SC_MAPPED_FILES + _SC_MEMLOCK, +#define _SC_MEMLOCK _SC_MEMLOCK + _SC_MEMLOCK_RANGE, +#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + _SC_MEMORY_PROTECTION, +#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + _SC_MESSAGE_PASSING, +#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING + _SC_SEMAPHORES, +#define _SC_SEMAPHORES _SC_SEMAPHORES + _SC_SHARED_MEMORY_OBJECTS, +#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + _SC_AIO_LISTIO_MAX, +#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX + _SC_AIO_MAX, +#define _SC_AIO_MAX _SC_AIO_MAX + _SC_AIO_PRIO_DELTA_MAX, +#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX + _SC_DELAYTIMER_MAX, +#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX + _SC_MQ_OPEN_MAX, +#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX + _SC_MQ_PRIO_MAX, +#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX + _SC_VERSION, +#define _SC_VERSION _SC_VERSION + _SC_PAGESIZE, +#define _SC_PAGESIZE _SC_PAGESIZE +#define _SC_PAGE_SIZE _SC_PAGESIZE + _SC_RTSIG_MAX, +#define _SC_RTSIG_MAX _SC_RTSIG_MAX + _SC_SEM_NSEMS_MAX, +#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX + _SC_SEM_VALUE_MAX, +#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX + _SC_SIGQUEUE_MAX, +#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX + _SC_TIMER_MAX, +#define _SC_TIMER_MAX _SC_TIMER_MAX + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, +#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX + _SC_BC_DIM_MAX, +#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX + _SC_BC_SCALE_MAX, +#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX + _SC_BC_STRING_MAX, +#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX + _SC_COLL_WEIGHTS_MAX, +#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX + _SC_EQUIV_CLASS_MAX, +#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX + _SC_EXPR_NEST_MAX, +#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX + _SC_LINE_MAX, +#define _SC_LINE_MAX _SC_LINE_MAX + _SC_RE_DUP_MAX, +#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX + _SC_CHARCLASS_NAME_MAX, +#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX + + _SC_2_VERSION, +#define _SC_2_VERSION _SC_2_VERSION + _SC_2_C_BIND, +#define _SC_2_C_BIND _SC_2_C_BIND + _SC_2_C_DEV, +#define _SC_2_C_DEV _SC_2_C_DEV + _SC_2_FORT_DEV, +#define _SC_2_FORT_DEV _SC_2_FORT_DEV + _SC_2_FORT_RUN, +#define _SC_2_FORT_RUN _SC_2_FORT_RUN + _SC_2_SW_DEV, +#define _SC_2_SW_DEV _SC_2_SW_DEV + _SC_2_LOCALEDEF, +#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF + + _SC_PII, +#define _SC_PII _SC_PII + _SC_PII_XTI, +#define _SC_PII_XTI _SC_PII_XTI + _SC_PII_SOCKET, +#define _SC_PII_SOCKET _SC_PII_SOCKET + _SC_PII_INTERNET, +#define _SC_PII_INTERNET _SC_PII_INTERNET + _SC_PII_OSI, +#define _SC_PII_OSI _SC_PII_OSI + _SC_POLL, +#define _SC_POLL _SC_POLL + _SC_SELECT, +#define _SC_SELECT _SC_SELECT + _SC_UIO_MAXIOV, +#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV + _SC_IOV_MAX = _SC_UIO_MAXIOV, +#define _SC_IOV_MAX _SC_IOV_MAX + _SC_PII_INTERNET_STREAM, +#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM + _SC_PII_INTERNET_DGRAM, +#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM + _SC_PII_OSI_COTS, +#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS + _SC_PII_OSI_CLTS, +#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS + _SC_PII_OSI_M, +#define _SC_PII_OSI_M _SC_PII_OSI_M + _SC_T_IOV_MAX, +#define _SC_T_IOV_MAX _SC_T_IOV_MAX + + /* Values according to POSIX 1003.1c (POSIX threads). */ + _SC_THREADS, +#define _SC_THREADS _SC_THREADS + _SC_THREAD_SAFE_FUNCTIONS, +#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + _SC_GETGR_R_SIZE_MAX, +#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX + _SC_GETPW_R_SIZE_MAX, +#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX + _SC_LOGIN_NAME_MAX, +#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX + _SC_TTY_NAME_MAX, +#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX + _SC_THREAD_DESTRUCTOR_ITERATIONS, +#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + _SC_THREAD_KEYS_MAX, +#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + _SC_THREAD_STACK_MIN, +#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN + _SC_THREAD_THREADS_MAX, +#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + _SC_THREAD_ATTR_STACKADDR, +#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + _SC_THREAD_ATTR_STACKSIZE, +#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + _SC_THREAD_PRIORITY_SCHEDULING, +#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + _SC_THREAD_PRIO_INHERIT, +#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + _SC_THREAD_PRIO_PROTECT, +#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + _SC_THREAD_PROCESS_SHARED, +#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + + _SC_NPROCESSORS_CONF, +#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF + _SC_NPROCESSORS_ONLN, +#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN + _SC_PHYS_PAGES, +#define _SC_PHYS_PAGES _SC_PHYS_PAGES + _SC_AVPHYS_PAGES, +#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES + _SC_ATEXIT_MAX, +#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX + _SC_PASS_MAX, +#define _SC_PASS_MAX _SC_PASS_MAX + + _SC_XOPEN_VERSION, +#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION + _SC_XOPEN_XCU_VERSION, +#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION + _SC_XOPEN_UNIX, +#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX + _SC_XOPEN_CRYPT, +#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT + _SC_XOPEN_ENH_I18N, +#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + _SC_XOPEN_SHM, +#define _SC_XOPEN_SHM _SC_XOPEN_SHM + + _SC_2_CHAR_TERM, +#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM + _SC_2_C_VERSION, +#define _SC_2_C_VERSION _SC_2_C_VERSION + _SC_2_UPE, +#define _SC_2_UPE _SC_2_UPE + + _SC_XOPEN_XPG2, +#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2 + _SC_XOPEN_XPG3, +#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3 + _SC_XOPEN_XPG4, +#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4 + + _SC_CHAR_BIT, +#define _SC_CHAR_BIT _SC_CHAR_BIT + _SC_CHAR_MAX, +#define _SC_CHAR_MAX _SC_CHAR_MAX + _SC_CHAR_MIN, +#define _SC_CHAR_MIN _SC_CHAR_MIN + _SC_INT_MAX, +#define _SC_INT_MAX _SC_INT_MAX + _SC_INT_MIN, +#define _SC_INT_MIN _SC_INT_MIN + _SC_LONG_BIT, +#define _SC_LONG_BIT _SC_LONG_BIT + _SC_WORD_BIT, +#define _SC_WORD_BIT _SC_WORD_BIT + _SC_MB_LEN_MAX, +#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX + _SC_NZERO, +#define _SC_NZERO _SC_NZERO + _SC_SSIZE_MAX, +#define _SC_SSIZE_MAX _SC_SSIZE_MAX + _SC_SCHAR_MAX, +#define _SC_SCHAR_MAX _SC_SCHAR_MAX + _SC_SCHAR_MIN, +#define _SC_SCHAR_MIN _SC_SCHAR_MIN + _SC_SHRT_MAX, +#define _SC_SHRT_MAX _SC_SHRT_MAX + _SC_SHRT_MIN, +#define _SC_SHRT_MIN _SC_SHRT_MIN + _SC_UCHAR_MAX, +#define _SC_UCHAR_MAX _SC_UCHAR_MAX + _SC_UINT_MAX, +#define _SC_UINT_MAX _SC_UINT_MAX + _SC_ULONG_MAX, +#define _SC_ULONG_MAX _SC_ULONG_MAX + _SC_USHRT_MAX, +#define _SC_USHRT_MAX _SC_USHRT_MAX + + _SC_NL_ARGMAX, +#define _SC_NL_ARGMAX _SC_NL_ARGMAX + _SC_NL_LANGMAX, +#define _SC_NL_LANGMAX _SC_NL_LANGMAX + _SC_NL_MSGMAX, +#define _SC_NL_MSGMAX _SC_NL_MSGMAX + _SC_NL_NMAX, +#define _SC_NL_NMAX _SC_NL_NMAX + _SC_NL_SETMAX, +#define _SC_NL_SETMAX _SC_NL_SETMAX + _SC_NL_TEXTMAX, +#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX + + _SC_XBS5_ILP32_OFF32, +#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32 + _SC_XBS5_ILP32_OFFBIG, +#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG + _SC_XBS5_LP64_OFF64, +#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64 + _SC_XBS5_LPBIG_OFFBIG, +#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG + + _SC_XOPEN_LEGACY, +#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY + _SC_XOPEN_REALTIME, +#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME + _SC_XOPEN_REALTIME_THREADS, +#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + _SC_ADVISORY_INFO, +#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO + _SC_BARRIERS, +#define _SC_BARRIERS _SC_BARRIERS + _SC_BASE, +#define _SC_BASE _SC_BASE + _SC_C_LANG_SUPPORT, +#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT + _SC_C_LANG_SUPPORT_R, +#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R + _SC_CLOCK_SELECTION, +#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION + _SC_CPUTIME, +#define _SC_CPUTIME _SC_CPUTIME + _SC_THREAD_CPUTIME, +#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME + _SC_DEVICE_IO, +#define _SC_DEVICE_IO _SC_DEVICE_IO + _SC_DEVICE_SPECIFIC, +#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC + _SC_DEVICE_SPECIFIC_R, +#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R + _SC_FD_MGMT, +#define _SC_FD_MGMT _SC_FD_MGMT + _SC_FIFO, +#define _SC_FIFO _SC_FIFO + _SC_PIPE, +#define _SC_PIPE _SC_PIPE + _SC_FILE_ATTRIBUTES, +#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES + _SC_FILE_LOCKING, +#define _SC_FILE_LOCKING _SC_FILE_LOCKING + _SC_FILE_SYSTEM, +#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM + _SC_MONOTONIC_CLOCK, +#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + _SC_MULTI_PROCESS, +#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS + _SC_SINGLE_PROCESS, +#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS + _SC_NETWORKING, +#define _SC_NETWORKING _SC_NETWORKING + _SC_READER_WRITER_LOCKS, +#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + _SC_SPIN_LOCKS, +#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS + _SC_REGEXP, +#define _SC_REGEXP _SC_REGEXP + _SC_REGEX_VERSION, +#define _SC_REGEX_VERSION _SC_REGEX_VERSION + _SC_SHELL, +#define _SC_SHELL _SC_SHELL + _SC_SIGNALS, +#define _SC_SIGNALS _SC_SIGNALS + _SC_SPAWN, +#define _SC_SPAWN _SC_SPAWN + _SC_SPORADIC_SERVER, +#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER + _SC_THREAD_SPORADIC_SERVER, +#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + _SC_SYSTEM_DATABASE, +#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE + _SC_SYSTEM_DATABASE_R, +#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R + _SC_TIMEOUTS, +#define _SC_TIMEOUTS _SC_TIMEOUTS + _SC_TYPED_MEMORY_OBJECTS, +#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + _SC_USER_GROUPS, +#define _SC_USER_GROUPS _SC_USER_GROUPS + _SC_USER_GROUPS_R, +#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R + _SC_2_PBS, +#define _SC_2_PBS _SC_2_PBS + _SC_2_PBS_ACCOUNTING, +#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + _SC_2_PBS_LOCATE, +#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE + _SC_2_PBS_MESSAGE, +#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE + _SC_2_PBS_TRACK, +#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK + _SC_SYMLOOP_MAX, +#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX + _SC_STREAMS, +#define _SC_STREAMS _SC_STREAMS + _SC_2_PBS_CHECKPOINT, +#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + + _SC_V6_ILP32_OFF32, +#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + _SC_V6_ILP32_OFFBIG, +#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + _SC_V6_LP64_OFF64, +#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + _SC_V6_LPBIG_OFFBIG, +#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + + _SC_HOST_NAME_MAX, +#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX + _SC_TRACE, +#define _SC_TRACE _SC_TRACE + _SC_TRACE_EVENT_FILTER, +#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + _SC_TRACE_INHERIT, +#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT + _SC_TRACE_LOG, +#define _SC_TRACE_LOG _SC_TRACE_LOG + + _SC_LEVEL1_ICACHE_SIZE, +#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE + _SC_LEVEL1_ICACHE_ASSOC, +#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC + _SC_LEVEL1_ICACHE_LINESIZE, +#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE + _SC_LEVEL1_DCACHE_SIZE, +#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE + _SC_LEVEL1_DCACHE_ASSOC, +#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC + _SC_LEVEL1_DCACHE_LINESIZE, +#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE + _SC_LEVEL2_CACHE_SIZE, +#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE + _SC_LEVEL2_CACHE_ASSOC, +#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC + _SC_LEVEL2_CACHE_LINESIZE, +#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE + _SC_LEVEL3_CACHE_SIZE, +#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE + _SC_LEVEL3_CACHE_ASSOC, +#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC + _SC_LEVEL3_CACHE_LINESIZE, +#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE + _SC_LEVEL4_CACHE_SIZE, +#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE + _SC_LEVEL4_CACHE_ASSOC, +#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC + _SC_LEVEL4_CACHE_LINESIZE, +#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE + /* Leave room here, maybe we need a few more cache levels some day. */ + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, +#define _SC_IPV6 _SC_IPV6 + _SC_RAW_SOCKETS, +#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS + + _SC_V7_ILP32_OFF32, +#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32 + _SC_V7_ILP32_OFFBIG, +#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG + _SC_V7_LP64_OFF64, +#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64 + _SC_V7_LPBIG_OFFBIG, +#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG + + _SC_SS_REPL_MAX, +#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX + + _SC_TRACE_EVENT_NAME_MAX, +#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + _SC_TRACE_NAME_MAX, +#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + _SC_TRACE_SYS_MAX, +#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + _SC_TRACE_USER_EVENT_MAX, +#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + + _SC_XOPEN_STREAMS, +#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS + + _SC_THREAD_ROBUST_PRIO_INHERIT, +#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT + _SC_THREAD_ROBUST_PRIO_PROTECT +#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT + +}; +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/posix1_lim.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/posix1_lim.h new file mode 100755 index 0000000000000..0739958c5a6c4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/bits/posix1_lim.h @@ -0,0 +1,34 @@ +#ifndef POSIX1_LIM_H +#define POSIX1_LIM_H +/** + @file posix1_lim.h + @brief POSIX Minimum values + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +TODO + This header should be ideally relocated under api/posix/bits (something that + doesnt exist today) and be included from api/posix/bits/limits.h which inturn + should be included from toolchain's limits.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +#ifndef _POSIX_PATH_MAX +/** @brief Maximum number of bytes in a pathname, including the terminating + nul character */ +#define _POSIX_PATH_MAX 256 +#endif + +#ifndef _POSIX_SEM_NSEMS_MAX +/** @brief Maximum number of semaphores that a process may have */ +#define _POSIX_SEM_NSEMS_MAX 16 +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/common/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/common/time.h new file mode 100755 index 0000000000000..76b0d39ab7039 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/common/time.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/fcntl.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/fcntl.h new file mode 100755 index 0000000000000..c80ec98a449b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/fcntl.h @@ -0,0 +1,51 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/*========================================================================== + * FILE: fcntl.h + * + * SERVICES: POSIX fcntl.h + * + * DESCRIPTION: The header is needed by the open() and fcntl() + * system calls, which have a variety of parameters and + * flags. They are described here. + * + * The formats of the calls to each of these are: + * + * open(path, oflag [,mode]) open a file + * fcntl(fd, cmd [,arg]) get or set file attributes + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Oflag values for open(). POSIX Table 6-4. */ +#define POSIX_O_CREAT 0x100 /* creat file if it doesn't exist */ +#define POSIX_O_EXCL 0x200 /* exclusive use flag */ +#define POSIX_O_NOCTTY 0x400 /* do not assign a controlling terminal */ +#define POSIX_O_TRUNC 0x1000 /* truncate flag */ + +/* File status flags for open() and fcntl(). POSIX Table 6-5. */ +#define POSIX_O_APPEND 0x2000 /* set append mode */ +#define POSIX_O_NONBLOCK 0x4000 /* no delay */ + +/* File access modes for open() and fcntl(). POSIX Table 6-6. */ +#define POSIX_O_RDONLY 0 /* open(name, POSIX_O_RDONLY) opens read only */ +#define POSIX_O_WRONLY 1 /* open(name, POSIX_O_WRONLY) opens write only */ +#define POSIX_O_RDWR 2 /* open(name, POSIX_O_RDWR) opens read/write */ + +/* Mask for use with file access modes. POSIX Table 6-7. */ +#define POSIX_O_ACCMODE 0x3 /* mask for file access modes */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FCNTL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/hooks/unistd.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/hooks/unistd.h new file mode 100755 index 0000000000000..1c618bfe36b4f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/hooks/unistd.h @@ -0,0 +1,115 @@ +#ifndef UNISTD_H +#define UNISTD_H +/** + @file posix/hooks/unistd.h + @brief POSIX related declarations in that are missing in toolchain + header + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly! Instead include unistd.h. + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include /* For various POSIX ID types from toolchain headers */ + +#ifdef __cplusplus +extern "C" { +#endif +extern long pathconf (char const * path, int name); + +/* Process*/ + +/** The getppid() function shall return the parent process ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the parent process ID + */ +pid_t getppid(void); + +/** The getpgid() function shall return the process group ID of the process whose process ID is equal to pid + * Please refer to POSIX standard for details. + * @param thread [in] process ID + * @param value_ptr [out] process group ID + */ +pid_t getpgid(pid_t pid); + +/** The getpgrp() function shall return the process group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] process group ID of the calling process + */ +pid_t getpgrp(void); + +/**The getuid() function shall return the real user ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the real user ID of the calling process. + */ +uid_t getuid(void); + +/** The geteuid() function shall return the effective user ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective user ID of the calling process + */ +uid_t geteuid(void); + +/** The getegid() function shall return the effective group ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective group ID of the calling process. + */ +gid_t getegid(void); + +/** The getgid() function shall return the real group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] real group ID of the calling process. + */ + gid_t getgid(void); + +/** seteuid set effective user ID + * Please refer to POSIX standard for details. + * @param thread [in] effective user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int seteuid(uid_t uid); + +/** setpgrp - set the process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setpgrp(void); + +/** setuid - set user ID + * Please refer to POSIX standard for details. + * @param thread [in] user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setuid(uid_t uid); + +/** setpgid - set process group ID for job control + * Please refer to POSIX standard for details. + * @param thread [in] PID of process, PGID to be set + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setpgid(pid_t pid, pid_t pgid); + +/** setsid - create session and set process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setsid(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/mqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/mqueue.h new file mode 100755 index 0000000000000..74dcc2fa202c6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/mqueue.h @@ -0,0 +1,203 @@ +#ifndef _POSIX_MQUEUE_H_ +#define _POSIX_MQUEUE_H_ + +/*========================================================================== + * FILE: mqueue.h + * + * SERVICES: POSIX Message Queue API interface + * + * DESCRIPTION: POSIX Message Queue API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technlogies, Inc. + *==========================================================================*/ + +#include /*ssize_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MQ_PRIO_MAX 255 /* max priority */ +#define MQ_PRIO_DEFAULT 0 /* default priority */ + +typedef int mqd_t; + +struct mq_attr +{ + long mq_flags; /* message queue flags */ + long mq_maxmsg; /* maximum number of messages */ + long mq_msgsize; /* maximum message size */ + long mq_curmsgs; /* number of messages currently queued */ +}; + +typedef struct mq_attr mqueue_attr; + +/** \details + * This provides POSIX Message Queue API. + * + * mq_notify is not supported. + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * it only supports Message sending and receiving within one process. + * Message sending and receiving among processes are not supported. + */ + +/** \defgroup mqueue POSIX Message Queue API */ +/** \ingroup mqueue */ +/** @{ */ + +/** Open a message queue. + * Please refer to POSIX standard for details. + */ +mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */...); + +/** Close a message queue. + * Please refer to POSIX standard for details. + */ +int mq_close(mqd_t mq_desc); + +/** Remove a message queue. + * Please refer to POSIX standard for details. + */ +int mq_unlink(const char *name); + +/** Send a message to a message queue. + * Please refer to POSIX standard for details. + * + * If the queue is full, instead of blocking the sender, this function + * will return -1 with errno EAGAIN, in this implementation. This behavior + * may change in the future. + */ +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); + +/** Send a message to a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); + +/** Receive a message from a message queue. + * Please refer to POSIX standard for details. + */ +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); + +/** Receive a message from a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msg_prio, const struct timespec *restrict abs_timeout); + +/** Get message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); + +/** Set message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, struct mq_attr *restrict omqstat); + +/** @} */ + +#define NBBY 8U /* number of bits in a byte */ + +/* + * Select uses bit masks of file descriptors in longs. These macros + * manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here should + * be enough for most uses. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256U +#endif + +typedef unsigned long fd_mask; +#define NFDBITS (sizeof(fd_mask) * (unsigned int)NBBY) /* bits per mask */ + +#ifndef howmany +#define howmany(x, y) (((x) + ((y) - 1U)) / (y)) +#endif + +//equivalent of fd_set fpr WINNT env +typedef struct fd_set +{ + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +/** \addtogroup mqueue */ +/** @{ */ + +/** Sets the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_SET(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] |= (1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Clears the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_CLR(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] &= ~(1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise. + */ +#define FD_ISSET(n, p) ((unsigned long)(p)->fds_bits[((unsigned int) (n)) / NFDBITS] & (unsigned long)((unsigned)1U << (((unsigned int) (n)) % NFDBITS))) + +/** Copies the file descriptor set. + */ +#define FD_COPY(f, t) (void)(memcpy)((t), (f), sizeof(*(f))) + +/** Initializes the file descriptor set fdset to have zero bits for all file descriptors. + */ +#define FD_ZERO(p) (void)memset((p), 0, sizeof(*(p))) + +/** Error check the file descriptor set. + */ +#define FD_BAD(fd) ((fd) < 0 /*|| fd >= fd_arraylen || fd_array[fd].obj == 0*/) + +/*! Wait for both message queues and signals. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int pselect(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict sigmask); + +/*! Wait for multiple message queues. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout); + +/** @} */ + +/* this function is needed for test framework which needs to clean up memory when teardown */ +void _mq_teardown(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread.h new file mode 100755 index 0000000000000..f64242e8dc683 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread.h @@ -0,0 +1,287 @@ +#ifndef QURT_PTHREAD_H +#define QURT_PTHREAD_H + +/*========================================================================== + * FILE: pthread.h + * + * SERVICES: POSIX pthread API interface + * + * DESCRIPTION: POSIX pthread API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016,2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *========================================================================== + * + * EDIT HISTORY FOR MODULE + * + * This section contains comments describing changes made to the module. + * Notice that changes are listed in reverse chronological order. + * + * + * + * when who what, where, why + * -------- --- ------------------------------------------------------- + * 10/13/08 cz Initial version. + *==========================================================================*/ + +#include +#include "sys/sched.h" /* For struct sched_param */ +#include "sys/errno.h" /* error values */ +#include +#include +#include +#include +#include +#include "pthread_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* the range of the set supported by the kernel data type used to represent CPU sets. */ +#define CONFIG_NR_CPUS QURT_THREAD_CFG_BITMASK_ALL + +#define UNIMPLEMENTED(FUNC, RETURNTYPE, ARGS) static inline RETURNTYPE FUNC ARGS { qurt_printf("Unimplemented: %s... exiting\n", __FUNCTION__); exit(1); } + +/** @brief Magic (non-portable) value for a stack's address to enable usage + of auto-stack feature (if available) */ +#define PTHREAD_AUTO_STACK_MAGIC_ADDR_NP ((void *)0xFFF) + +/** \details + * This provides POSIX thread API. + * + */ + +/** \defgroup pthread POSIX pthread API */ +/** \ingroup pthread */ +/** @{ */ + +/** Compare Two Threads. + * Please refer to POSIX standard for details. + */ +static inline int pthread_equal(pthread_t t1, pthread_t t2) +{ + return (t1 == t2) ? 1 : 0; +} + +/** Create Thread. + * Please refer to POSIX standard for details. + */ +int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void *(*start)(void *), void *arg); + +/** Terminate Calling Thread. + * Please refer to POSIX standard for details. + */ +void pthread_exit(void *value_ptr); + +/** Wait for thread termination. + * Please refer to POSIX standard for details. + * @param thread [in] the thread to be joined + * @param value_ptr [out] the pointer of the exit status + */ +int pthread_join(pthread_t thread, void **value_ptr); + +/** Detach a joinable thread. + * Please refer to POSIX standard for details. + * @param id [in] id of the tread the thread to be detached. + */ +int pthread_detach(pthread_t id); + +/** Dynamic package initialisation + * Please refer to POSIX standard for details. + */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + +pthread_t pthread_self(void); +int pthread_cancel(pthread_t thread); +static inline void pthread_yield(void) +{ + return; +} + +int pthread_kill(pthread_t thread, int sig); + +/** + * @brief Return name of thread + * @warning Donot call this in the error handling path as it may cause deadlock + * due to underlying OS calls + * @param thread [in] thread Thread whose name is to be retrieved + * @param name [out] name Buffer used to return thread name + * @param len [in] len Number of bytes available in name + * @return 0 on success, ESRCH, ERANGE on failure + */ +extern int pthread_getname_np (pthread_t thread, char * name, size_t len); + +int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param); +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); +int pthread_setschedprio(pthread_t thread, int prio); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); + +/* Attribute functions */ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const sched_param *restrict param); +int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, sched_param *restrict param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr); +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void ** stackaddr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); +int pthread_attr_setscope(pthread_attr_t *attr, int scope); +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_getguardsize(const pthread_attr_t * attr, size_t * guardsize); +int pthread_attr_setautostack(pthread_attr_t *attr); +int pthread_attr_setbuspriority(pthread_attr_t *attr, unsigned short bus_priority); + +/* Qualcomm additions to pthread get/set attribute functions */ +int pthread_attr_setthreadname(pthread_attr_t *attr, const char * name); +int pthread_attr_getthreadname(const pthread_attr_t *attr, char * name, int size); +int pthread_attr_settimetestid(pthread_attr_t *attr, unsigned int tid); +int pthread_attr_gettimetestid(const pthread_attr_t *attr, unsigned int* tid); + +/* Mutexes */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling); +int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling); + +/* For Mutex with type PTHREAD_MUTEX_NORMAL, Priority Inheritance is not + * supported even PTHREAD_PRIO_INHERIT is defined since QURT does not support + * this kind of Mutex */ +int pthread_mutexattr_init(pthread_mutexattr_t *attr); +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling); + +/* Spinlocks */ +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); + +/* Condition variables */ +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); +int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); +int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock); +int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock); +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *time); + +/* Barriers */ +int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); +int pthread_barrier_destroy(pthread_barrier_t *barrier); +int pthread_barrier_wait(pthread_barrier_t *barrier); +int pthread_barrierattr_init(pthread_barrierattr_t *attr); +int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); + + +/*Read-Write locks*/ +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +int pthread_rwlock_rdlock(pthread_rwlock_t *); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *); +int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); +int pthread_rwlock_unlock(pthread_rwlock_t *); + + +/** please refer to POSIX standard document + */ +int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/** set CPU affinity attribute in thread attributes object. + + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [in] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpuset specified a CPU that was outside the set supported + by the kernel. (The kernel configuration option + CONFIG_NR_CPUS defines the range of the set supported by + the kernel data type used to represent CPU sets.) + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); + +/** get CPU affinity attribute in thread attributes object. + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [out] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpusetsize is smaller than the size of the affinity mask + used by the kernel. + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset); + +/* TLS */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_getattr_np(pthread_t thread, pthread_attr_t * restrict attr); + +/** @} */ + +/* Calling non-pthread calls this function to create pthred tcb w/o creating actual thread */ +int pthread_fake(pthread_t * restrict thread, const pthread_attr_t * restrict attr); +int pthread_fake_destroy(pthread_t thread); + +//amitkulk: move these to unistd.h after we move that header within qurt +int posix_memalign(void **memptr, size_t alignment, size_t size); +void exit(int status); +#ifdef __cplusplus +} +#endif + +#endif /* QURT_PTHREAD_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread_types.h new file mode 100755 index 0000000000000..51c3b9dbca243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/pthread_types.h @@ -0,0 +1,193 @@ +#ifndef _PTHREAD_TYPES_H_ +#define _PTHREAD_TYPES_H_ + +/*========================================================================== + * FILE: pthread_types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2016, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif + +#define _SSIZE_T + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PTHREAD_MAX_THREADS 512U + +#define PTHREAD_NAME_LEN 16 +#define PTHREAD_MIN_STACKSIZE 512 //4096 +#define PTHREAD_MAX_STACKSIZE 1048576 +#define PTHREAD_DEFAULT_STACKSIZE 16384 + +#define PTHREAD_STACK_MIN (4096U*2U) +#define PTHREAD_MIN_PRIORITY 0U +#define PTHREAD_MAX_PRIORITY 255U +#define PTHREAD_DEFAULT_PRIORITY 1 + +/*Mutex initialization status*/ +#define PTHREAD_MUTEX_ATTR_UNINITIALIZED 0 +#define PTHREAD_MUTEX_ATTR_INITIALIZED 1 + +/*Conditional attributes initialization status*/ +#define PTHREAD_COND_ATTR_UNINITIALIZED 0 +#define PTHREAD_COND_ATTR_INITIALIZED 1 + +#define PTHREAD_DEFAULT_NAME "Anonymous" + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFFU) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFFU) + +/* mutex and cond_var shared */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* mutex type */ +#define PTHREAD_MUTEX_ERRORCHECK 0 +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT 3 + +/* mutex protocol */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_SPINLOCK_UNLOCKED 0 +#define PTHREAD_SPINLOCK_LOCKED 1 + +#define PTHREAD_ONCE_INIT (0) + +#define PTHREAD_MUTEX_OPAQUE //ToDo: amitkulk: debug + +typedef signed int ssize_t; + +/*detatchstate of a pthread*/ +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 0 + +/*contention scope*/ +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 + +/*scheduler*/ +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Types and structure definitions + * + */ +typedef unsigned int cpu_set_t; + +typedef unsigned int pthread_t; + +typedef struct pthread_attr_t +{ + void *stackaddr; + int internal_stack; /* this flag==1 means the stack needs to be freed by posix */ + size_t stacksize; + int priority; + unsigned short timetest_id; + /* This flag indicate if thread will be autostack thread*/ + unsigned short autostack:1; + /* This flag is to indicate thread's bus_priority high/low + bus_priority = 0 -- Bus_priority is low + bus_priority = 1 -- Bus_priority is high + bus_priority = 3 -- Bus_priority is default (takes the default set for the process) + */ + unsigned short bus_priority:2; + unsigned short reserved:13; + cpu_set_t cpumask; + char name[PTHREAD_NAME_LEN]; + /* This flag indicates whether pthread lib should create thread contexts for other OSALs */ + /* This is used internally by POSIX and not available for general usage */ + int ext_context; + int detachstate; +} pthread_attr_t; + +//mutex attr +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +struct pthread_mutexattr_t +{ + int is_initialized; + int type; + int pshared; + int protocol; +}; + +typedef unsigned int pthread_mutex_t; + +typedef unsigned int pthread_spinlock_t; + +typedef struct pthread_condattr_t +{ + int is_initialized; + int pshared; + clockid_t clock_id; +} pthread_condattr_t; + +typedef unsigned int pthread_cond_t; + +typedef struct pthread_barrierattr_t +{ + int is_initialized; + int pshared; +} pthread_barrierattr_t; + +typedef unsigned int pthread_barrier_t; + +typedef int pthread_key_t; + +typedef int pthread_once_t; + + +/*Read-Write locks*/ +#define PTW32_RWLOCK_MAGIC 0xfacade2 +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +#ifdef __cplusplus +} +#endif + +#endif /* _PTHERAD_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sched.h new file mode 100755 index 0000000000000..faf3365be9f82 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sched.h @@ -0,0 +1,21 @@ +/*============================================================================= + + sched.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include "sys/sched.h" + +#endif //__SCHED_H__ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/semaphore.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/semaphore.h new file mode 100755 index 0000000000000..d9145b295ae62 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/semaphore.h @@ -0,0 +1,114 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +/*========================================================================== + * FILE: semaphore.h + * + * SERVICES: POSIX semaphore API interface + * + * DESCRIPTION: POSIX semaphore API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ +#include // Get all C sys types - includes POSIX specific +#include "sys/errno.h" // error values + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** User facing semaphore container with opaque pointer to implementation */ +typedef struct +{ + unsigned int *opaque; +} sem_t; +#define _SEM_T + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* constant definitions */ +#define SEM_FAILED ((sem_t*) 0) + +/* @todo siqbal Should we put such configuration items in a common place + instead of this user-facing header? */ +#define SEM_VALUE_MAX ((unsigned int) 30) // If need be increase this + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/** \details + * POSIX standard comes with two kinds of semaphores: named and unnamed + * semaphores. + * + * This implementation of POSIX kernel API provide unnamed & named semaphore. + * + * + * sem_timedwait() is not provided. + */ + +/** \defgroup semaphore POSIX Semaphore API */ + +/** \ingroup semaphore */ +/** @{ */ + +/** Initialize an unnamed semaphore. + * Please refer to POSIX standard for details. + * @param pshared [in] This implementation does not support non-zero value, + * i.e., semaphore cannot be shared between processes in this implementation. + */ +int sem_init(sem_t *sem, int pshared, unsigned int value); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_wait(sem_t *sem); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_trywait(sem_t *sem); + +/** Unlock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_post(sem_t *sem); + +/** Get the value of a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_getvalue(sem_t *sem, int *value); + +/** Destroy an unnamed semaphore. + * Please refer to POSIX standard for details. + */ +int sem_destroy(sem_t *sem); + +/** creates and initializes a named semaphore. + * Please refer to POSIX standard for details. + */ +sem_t * sem_open(const char* name , int oflag , ...); + +/** closes a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_close(sem_t *sem); + +/** unlinkes a named semaphore. + * Please refer to POSIX standard for details. + */ +int sem_unlink(const char *name); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SEMAPHORE_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/signal.h new file mode 100755 index 0000000000000..35cb1f1a9a319 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/signal.h @@ -0,0 +1,201 @@ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/*========================================================================== + * FILE: signal.h + * + * SERVICES: POSIX Signal API interface + * + * DESCRIPTION: POSIX Signal API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX signal bits */ + +#define POSIX_MSG 7 /* POSIX msg type used in Qube API */ +#define POSIX_NOTIF 8 /* POSIX msg type used in Qube API */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ + +#define SIGRTMIN 10 +#define SIGRTMAX 32 + +/* Notification Types. */ +/* No asynchronous notification is delivered when the event of interest occurs. */ +#define SIGEV_NONE 0 +/* The signal specified in sigev_signo shall be generated for the process when + the event of interest occurs. */ +#define SIGEV_SIGNAL 1 +/* A notification function is called to perform notification. */ +#define SIGEV_THREAD 2 +#define SA_SIGINFO 1 + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +typedef unsigned long int sigset_t; + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent sigevent; +struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; +}; + +typedef struct siginfo_t siginfo_t; +struct siginfo_t +{ + int si_signo; + int si_code; + union sigval si_value; +/* int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band;*/ +}; +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_sigaction)(int, siginfo_t *, void *); +}; + +/* Signal functions */ + +/** \details + * This provides POSIX Signal API. Please note that this + * implementation does not fully comply with POSIX standard. + * + * In POSIX standard, Signal can be used as 'interrupt', which means + * an incoming signal will interrupt a running thread. After the + * registered signal handler is executed, the thread will resume. + * This behavior cannot be implemented w/o modifying L4 or QURT kernel. + * On the ohter hand, appliation need to be carefully written to avoid + * problems caused by 'interrupting' signals. + * + * Therefore, in this implementation of POSIX signal, thread will + * only receive signals when it explicitly waits for signals, i.e., when + * the thread calls either sigwait() or sigsuspend(). + * + * Therefore, pthread_sigmask(), which set or get signal mask for a thread, + * is not supported, since the signal mask will be set by sigwait() and + * sigsuspend(). + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * only threads can send and receive signals. The functions related to + * signal operations with processes, such as kill(), sigqueue(), + * sigprocmask(), are not provided. + * + * Queued signal is not supported. + * + * Applications will use signals from SIGRTMIN to SIGRTMAX. + * + * SIGEV_SIGNAL and SIGEV_THREAD are supported. SIGEV_NONE is not + * supported. + * + */ + +/** \defgroup signal POSIX Signal API */ +/** \ingroup signal */ +/** @{ */ + +/** Wait for signals. This implementation does not support queued signals. + * + * Please refer to POSIX standard for details. + */ +int sigwait(const sigset_t *restrict set, int *restrict sig); + +/** Examine and Change Signal Action. + * Please refer to POSIX standard for details. + * + * @param act [in] A pointer to the sigaction structure that describes the + * action to be taken for the signal. Can be NULL. + * The following flags for sa_flags field in struct sigaction are not + * supported: SA_NOCLDSTOP, SA_ONSTACK, SA_RESETHAND, SA_RESTART, + * SA_NOCLDWAIT and SA_NODEFER. Only flag SA_SIGINFO is supported. + * + * @note Define sigaction as macro to avoid a warning when included from + * C++ code - it's causing a "sigaction(...) hides constructor for + * 'struct sigaction'" warning. + */ +/*lint -esym(123,sigaction) Suppress "macro used with no arguments" */ +#define sigaction(sig,act,oact) _sigaction((sig),(act),(oact)) + +/** Wait for signals. + * Please refer to POSIX standard for details. + */ +int sigsuspend(const sigset_t *sigmask); + +/** Add Signal to Signal Set. + * Please refer to POSIX standard for details. + */ +int sigaddset(sigset_t *set, int signo); + +/** Delete Signal from Signal Set. + * Please refer to POSIX standard for details. + */ +int sigdelset(sigset_t *set, int signo); + +/** Initialize and Empty Signal Set. + * Please refer to POSIX standard for details. + */ +int sigemptyset(sigset_t *set); + +/** Initialize and Fill Signal Set. + * Please refer to POSIX standard for details. + */ +int sigfillset(sigset_t *set); + +/** Test for Signal in Signal Set. + * Please refer to POSIX standard for details. + */ +int sigismember(const sigset_t *set, int signo); + +/** @} */ + +/* this is not a public api function */ +int _sigaction(int sig, const struct sigaction *act, struct sigaction *oact); + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +/** Wait for the time interval specified in the timespec structure referenced + * by timeout. This implementation does not support queued signals. + * For struct siginfo_t, si_code and si_value are ignored in this implementation. + * + * Please refer to POSIX standard for details. + */ +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SIGNAL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/errno.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/errno.h new file mode 100755 index 0000000000000..b9edf57bab6c3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/errno.h @@ -0,0 +1,20 @@ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +/*========================================================================== + * FILE: errno.h + * + * SERVICES: POSIX errno header file + * + * DESCRIPTION: POSIX errno based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#ifndef EOK +#define EOK 0 +#endif + +#endif /* _SYS_ERRNO_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/sched.h new file mode 100755 index 0000000000000..2acc34d821725 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/sched.h @@ -0,0 +1,67 @@ +#ifndef _POSIX_SCHED_H_ +#define _POSIX_SCHED_H_ + +/*========================================================================== + * FILE: sched.c + * + * SERVICES: POSIX Thread sched API interface + * + * DESCRIPTION: POSIX Thread sched API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCHED_FIFO 0 /* First in, first out (FIFO) scheduling policy. */ +#define SCHED_RR 1 /* Round robin scheduling policy. */ +#define SCHED_SPORADIC 2 /* Sporadic server scheduling policy. */ +#define SCHED_OTHER 3 /* Another scheduling policy. */ + +typedef struct sched_param sched_param; +struct sched_param +{ + void *unimplemented; + int sched_priority; +}; + +/** \details + * This provides POSIX sched API. + */ + +/** \defgroup sched POSIX sched API */ +/** \ingroup sched */ +/** @{ */ + +/** Relinquish the CPU. + * Please refer to POSIX standard for details. + */ +static inline int sched_yield(void) +{ + return 0; +} + +/** Get the maximum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_max(int policy); + +/** Get the minimum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_min(int policy); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SCHED_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/types.h new file mode 100755 index 0000000000000..700026f9f9e4e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/sys/types.h @@ -0,0 +1,35 @@ +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/*========================================================================== + * FILE: types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#if !defined( _PID_T ) || !defined( __pid_t_defined ) +/* POSIX defines pid_t as signed 32-bit type. Hexagon toolchain's header + defines it as unsigned 32-bit type citing conflict with QuRT POSIX + compatibility later. If any such conflicts exist, we should fix them. + pid_t is being defined *BEFORE* inclusion of generic/sys/types.h + *INTENTIONALLY* to fix this */ +typedef int pid_t; +#define _PID_T +#define __pid_t_defined +#endif +#include +#include +#include +#include + +#ifndef __DEFINED_off_t +typedef long off_t; +#define __DEFINED_off_t +#endif + +#endif /* _SYS_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/time.h new file mode 100755 index 0000000000000..13aeb1ea9920d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/posix/time.h @@ -0,0 +1,142 @@ +#ifndef _POSIX_TIME_H_ +#define _POSIX_TIME_H_ + +/*========================================================================== + * FILE: time.h + * + * SERVICES: POSIX Timer API interface + * + * DESCRIPTION: POSIX Timer API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *==========================================================================*/ + + +#include + +typedef int clockid_t; /* ignored */ +#define _CLOCKID_T +#define _PROVIDE_POSIX_TIME_DECLS 1 +#include +/* @todo anandj sys/time.h has definition for struct timeval but is not + included by generic/time.h */ +#include + +#define CLOCK_FREQ_NOT_DEFINED -1 +/* Frequency of Sclk used */ +#define TIME_CONV_SCLK_FREQ 19200000 + +#define RES_CONV_FACTOR1 1 +#define RES_CONV_FACTOR2 1000000000 + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +#endif + +#if !defined(CLOCK_MONOTONIC) +# define CLOCK_MONOTONIC 1 +#endif + +#if !defined(CLOCK_THREAD_CPUTIME_ID) +# define CLOCK_THREAD_CPUTIME_ID 2 +#endif + +#if !defined(CLOCK_PROCESS_CPUTIME_ID) +# define CLOCK_PROCESS_CPUTIME_ID 3 +#endif + +#if !defined(CLOCK_MONOTONIC_RAW) +# define CLOCK_MONOTONIC_RAW 4 +#endif + +#if !defined(CLOCK_REALTIME_COARSE) +# define CLOCK_REALTIME_COARSE 5 +#endif + +#if !defined(CLOCK_MONOTONIC_COARSE) +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +#if !defined(CLOCK_BOOTTIME) +# define CLOCK_BOOTTIME 7 +#endif + +struct itimerspec +{ + struct timespec it_interval; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer functions */ + +/** \details + * POSIX timers can be either of two types: a one-shot type or a periodic + * type. + * + * A one-shot is an armed timer that is set to an expiration time relative + * to either a current time or an absolute time. The timer expires once and + * is disarmed. + * + * A periodic timer is armed with an initial expiration time and a repetition + * interval. Every time the interval timer + * expires, the timer is reloaded with the repetition interval. The timer + * is then rearmed. + */ + +/** \defgroup timer POSIX Timer API */ + +/** \ingroup timer */ +/** @{ */ + +/** Create a POSIX timer. + * Please refer to POSIX standard for details. + * @param clockid [in] ignored in this implementation + * @param evp [in] if non-NULL, points to a sigevent structure. This + * structure, allocated by the application, defines the asynchronous + * notification to occur when the timer expires. If the evp argument is + * NULL, the effect is as if the evp argument pointed to a sigevent + * structure with the sigev_notify member having the value SIGEV_SIGNAL, + * the sigev_signo having a default signal number (SIGALRM), and the + * sigev_value member having the value of the timer ID. + */ +int timer_create(clockid_t clockid, struct sigevent *restrict evp, + timer_t *restrict timerid); + +/** Delete a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_delete(timer_t timerid); + +/** Get the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_gettime(timer_t timerid, struct itimerspec *value); + + +/** Set the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + * @param flags [in] ignored in this implementation + */ +int timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); +/** Obtain ID of a process CPU-time clock + * @param pid [in] Process ID + * @param clock_id [out] Clock ID + * @return Error values as per POSIX standard + */ +int clock_getcpuclockid (pid_t pid, clockid_t * clock_id); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_TIME_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qube/qube.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qube/qube.h new file mode 100755 index 0000000000000..1e31e2deedb38 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qube/qube.h @@ -0,0 +1,51 @@ +#ifndef QUBE_H +#define QUBE_H +/*============================================================================= + + qube.h -- H E A D E R F I L E + +GENERAL DESCRIPTION + Prototypes of qpd API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Define Error codes as QuRT error codes preceed with QURT_ */ +#ifndef EOK +#define EOK QURT_EOK +#endif /* EOK */ +#ifndef EVAL +#define EVAL QURT_EVAL +#endif /* EVAL */ +#ifndef EMEM +#define EMEM QURT_EMEM +#endif /* EMEM */ +#ifndef EINVALID +#define EINVALID QURT_EINVALID +#endif /* EINVALID */ + + +/*============================================================================= + FUNCTION DECLARATIONS +=============================================================================*/ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QUBE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops.h new file mode 100755 index 0000000000000..0a9a9f8ba7db5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops.h @@ -0,0 +1,197 @@ +#ifndef ATOMIC_OPS_H +#define ATOMIC_OPS_H +/** + @file atomic_ops.h + + @brief Type definitions backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * Author: Carlos Dyonisio + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_plain_word_t; + +/*-------------------------------------------------------------------------*/ + /* Atomic Ops API. */ + +/* + * IMPORTANT! + * If you plan to change the structure atomic_word_t, please add the new + * elements after value. For more information, read the comment in + * arch/arm/libs/atomic_ops/v5/src/arm_atomic_ops.spp:66 + */ + +typedef struct { + volatile atomic_plain_word_t value; +} atomic_word_t; + +#define ATOMIC_INIT(i) { (i) } + +static inline void +atomic_init(atomic_word_t *a, atomic_plain_word_t v) +{ + a->value = v; +} + +#if defined(ARCH_ARM) && defined(ARCH_VER) && (ARCH_VER < 6) && \ + (!defined(__ATOMIC_OPS_IN_KERNEL__) || defined(MACHINE_SMP)) + +/* + * If it is ARMv4/v5, the function declarations may change + * and are defined in the arch specific header file, + * as some of then cannot be declared static because of + * the assembler implementation. + */ + +#else + +/* Arithmetic operations. */ + +void atomic_sub(atomic_word_t *target, atomic_plain_word_t v); + +/* Architecture independent definitions. */ + +static inline atomic_plain_word_t atomic_read(atomic_word_t *target) +{ + return target->value; +} + +typedef unsigned long long atomic64_plain_word_t; + +typedef struct { + volatile atomic64_plain_word_t value; +} atomic64_word_t; + +static inline void +atomic64_init(atomic64_word_t *a, atomic64_plain_word_t v) +{ + a->value = v; +} + +/********************* + Support 64-bit + *********************/ + +atomic64_plain_word_t atomic64_set(atomic64_word_t* target, + atomic64_plain_word_t value); + +void atomic64_xor(atomic64_word_t* target, + atomic64_plain_word_t mask); + +/*---------------------------------------------------------------------------*/ + +/* Architecture independent definitions. */ + +static inline atomic64_plain_word_t atomic64_read(atomic64_word_t *target) +{ + return target->value; +} + +#endif + + +/* Architecture dependent definitions. */ +#include + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops_plat.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops_plat.h new file mode 100755 index 0000000000000..b54b3ff83d978 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/atomic_ops_plat.h @@ -0,0 +1,86 @@ +#ifndef ATOMIC_OPS_PLAT_H +#define ATOMIC_OPS_PLAT_H +/** + @file atomic_ops_plat.h + + @brief Prototypes of atomic operations API backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define atomic_set(a,b) qurt_atomic_set((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and(a,b) qurt_atomic_and((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and_return(a,b) qurt_atomic_and_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or(a,b) qurt_atomic_or((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or_return(a,b) qurt_atomic_or_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor(a,b) qurt_atomic_xor((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor_return(a,b) qurt_atomic_xor_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_set_bit(a,b) qurt_atomic_set_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_clear_bit(a,b) qurt_atomic_clear_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_change_bit(a,b) qurt_atomic_change_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add(a,b) qurt_atomic_add((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_return(a,b) qurt_atomic_add_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_unless(a,b,c) qurt_atomic_add_unless((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_sub(a,b) qurt_atomic_sub((unsigned int *)(a),(unsigned int)(b)) +#define atomic_sub_return(a,b) qurt_atomic_sub_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_inc(a) qurt_atomic_inc((unsigned int *)(a)) +#define atomic_inc_return(a) qurt_atomic_inc_return((unsigned int *)(a)) +#define atomic_dec(a) qurt_atomic_dec((unsigned int *)(a)) +#define atomic_dec_return(a) qurt_atomic_dec_return((unsigned int *)(a)) +#define atomic_compare_and_set(a,b,c) qurt_atomic_compare_and_set((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_barrier qurt_atomic_barrier +#define atomic_barrier_write qurt_atomic_barrier_write +#define atomic_barrier_write_smp qurt_atomic_barrier_write_smp +#define atomic_barrier_read_smp qurt_atomic_barrier_read_smp +#define atomic_barrier_smp qurt_atomic_barrier_smp + +/*============================ + * 64 bits support + *============================ */ +#define atomic64_set(a,b) qurt_atomic64_set((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and(a,b) qurt_atomic64_and((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and_return(a,b) qurt_atomic64_and_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or(a,b) qurt_atomic64_or((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or_return(a,b) qurt_atomic64_or_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor(a,b) qurt_atomic64_xor((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor_return(a,b) qurt_atomic64_xor_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_set_bit(a,b) qurt_atomic64_set_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_clear_bit(a,b) qurt_atomic64_clear_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_change_bit(a,b) qurt_atomic64_change_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add(a,b) qurt_atomic64_add((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add_return(a,b) qurt_atomic64_add_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub(a,b) qurt_atomic64_sub((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub_return(a,b) qurt_atomic64_sub_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_inc(a) qurt_atomic64_inc((unsigned long long *)(a)) +#define atomic64_inc_return(a) qurt_atomic64_inc_return((unsigned long long *)(a)) +#define atomic64_dec(a) qurt_atomic64_dec((unsigned long long *)(a)) +#define atomic64_dec_return(a) qurt_atomic64_dec_return((unsigned long long *)(a)) +#define atomic64_compare_and_set(a,b,c) qurt_atomic64_compare_and_set((unsigned long long *)(a),(unsigned long long )(b),(unsigned long long )(c)) +#define atomic64_barrier qurt_atomic64_barrier +#define atomic64_barrier_write qurt_atomic64_barrier_write +#define atomic64_barrier_write_smp qurt_atomic64_barrier_write_smp +#define atomic64_barrier_read_smp qurt_atomic64_barrier_read_smp +#define atomic64_barrier_smp qurt_atomic64_barrier_smp + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_PLAT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt.h new file mode 100755 index 0000000000000..4d25c9b2b6243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt.h @@ -0,0 +1,111 @@ +#ifndef QURT_H +#define QURT_H + +/** + @file qurt.h + @brief Contains kernel header files that provide kernel OS API functions, constants, and + definitions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013,2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +/*====================================================================== + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Notice that changes are listed in reverse chronological + * order. + * + * + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------ + * 2011-02-25 op Add Header file + 2012-12-16 cm (Tech Pubs) Edited/added Doxygen comments and markup. + ======================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "qurt_consts.h" +#include "qurt_api_version.h" +#include "qurt_alloc.h" +#include "qurt_futex.h" +#include "qurt_mutex.h" +#include "qurt_pipe.h" +#include "qurt_printf.h" +#include "qurt_assert.h" +#include "qurt_thread.h" +#include "qurt_trace.h" +#include "qurt_cycles.h" +#include "qurt_profile.h" +#include "qurt_sem.h" +#include "qurt_cond.h" +#include "qurt_barrier.h" +#include "qurt_fastint.h" +#include "qurt_allsignal.h" +#include "qurt_anysignal.h" +#include "qurt_signal.h" +#include "qurt_rmutex.h" +#include "qurt_pimutex.h" +#include "qurt_signal2.h" +#include "qurt_rmutex2.h" +#include "qurt_pimutex2.h" +#include "qurt_int.h" +#include "qurt_lifo.h" +#include "qurt_power.h" +#include "qurt_event.h" +#include "qurt_pmu.h" +#include "qurt_stid.h" +//#include "qurt_version.h" +#include "qurt_tlb.h" +#include "qurt_vtlb.h" +#include "qurt_memory.h" +#include "qurt_qdi.h" +#include "qurt_sclk.h" +#include "qurt_space.h" +#include "qurt_process.h" +#include "qurt_timer.h" +#include "qurt_tls.h" +#include "qurt_thread_context.h" +#include "qurt_hvx.h" +#include "qurt_hmx.h" +#include "qurt_mailbox.h" +#include "qurt_island.h" +#include "qurt_qdi_proxy.h" +#include "qurt_l2cfg.h" +#include "qurt_mmap.h" +#include "qurt_isr.h" +#include "qurt_busywait.h" +#include "qurt_ecc.h" +#include "qurt_callback.h" +#include "qurt_error.h" +#include "qurt_except.h" +#include "qurt_mq.h" +#include "qurt_user_dma.h" +#include "qurt_fs_hub.h" +#include "qurt_os_services.h" + +#ifndef MAIN_ONLY +#define INCLUDE_ISLAND_CONTENTS +#endif +#ifndef ISLAND_ONLY +#define INCLUDE_MAIN_CONTENTS +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_alloc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_alloc.h new file mode 100755 index 0000000000000..da37a4c0a714e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_alloc.h @@ -0,0 +1,145 @@ +#ifndef QURT_ALLOC_H +#define QURT_ALLOC_H + +/** + @file qurt_alloc.h + @brief Prototypes of kernel memory allocation API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_malloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated memory area. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] size Size (in bytes) of the memory area. + + @return + Nonzero -- Pointer to the allocated memory area. \n + 0 -- Not enough memory in heap to allocate memory area. + + @dependencies + None. + + */ +/* ======================================================================*/ +void *qurt_malloc( unsigned int size); + +/*======================================================================*/ +/**@ingroup func_qurt_calloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated array. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] elsize Size (in bytes) of each array element. + @param[in] num Number of array elements. + + @return + Nonzero -- Pointer to allocated array.\n + Zero -- Not enough memory in heap to allocate array. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_calloc(unsigned int elsize, unsigned int num); + +/*======================================================================*/ +/**@ingroup func_qurt_realloc + Reallocates memory on the heap. \n + Changes the size of a memory area that is already allocated on the QuRT system heap. + The reallocate memory operation is functionally similar to realloc. It accepts a pointer + to an existing memory area on the heap, and resizes the memory area to the specified size + while preserving the original contents of the memory area. + + @note1hang This function might change the address of the memory area. + If the value of ptr is NULL, this function is equivalent to + qurt_malloc(). + If the value of new_size is 0, it is equivalent to qurt_free(). + If the memory area is expanded, the added memory is not initialized. + + @param[in] *ptr Pointer to the address of the memory area. + @param[in] newsize Size (in bytes) of the reallocated memory area. + + @return + Nonzero -- Pointer to reallocated memory area. \n + 0 -- Not enough memory in heap to reallocate the memory area. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_realloc(void *ptr, int newsize); + +/*======================================================================*/ +/**@ingroup func_qurt_free + Frees allocated memory from the heap.\n + Deallocates the specified memory from the QuRT system heap. + + @param[in] *ptr Pointer to the address of the memory to deallocate. + + @return + None. + + @dependencies + The memory item that the ptr value specifies must have been previously + allocated using one of the qurt_calloc(), + qurt_malloc(), or qurt_realloc() memory allocation functions. + Otherwise the behavior of QuRT is undefined. + + */ + /* ======================================================================*/ +void qurt_free( void *ptr); + + +void *qurt_memalign(unsigned int alignment, unsigned int size); + +/* +|| Macro to define a static heap for a QuRT program. +|| +|| Usage: +|| Declare at the top-level of any C source file that +|| is part of the build (and is guaranteed +|| to actually be pulled into the build). Place +|| it in the same function with main(): +|| +|| QURT_DECLARE_STATIC_HEAP(512000); +|| +|| The only argument is the size in bytes, and it is +|| rounded up to the nearest 64 bytes (size of an +|| L2 cache block). +|| +*/ + +#define QURT_DECLARE_STATIC_HEAP(sz) \ + static struct qurt_static_heap { \ + char space[(sz)] __attribute__((aligned(64))); \ + } static_heap[1]; \ + void * const override_heap_Base = &static_heap[0]; \ + void * const override_heap_Limit = &static_heap[1] + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLOC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_allsignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_allsignal.h new file mode 100755 index 0000000000000..5dc89e495130d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_allsignal.h @@ -0,0 +1,176 @@ + +#ifndef QURT_ALLSIGNAL_H +#define QURT_ALLSIGNAL_H + +/** + @file qurt_allsignal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup all_signal_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** +qurt_signal_t supersedes qurt_allsignal_t. This type definition was added for backwards compatibility. */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int waiting; /**< */ + unsigned int signals_in; /**< */ + unsigned int queue; /**< */ + unsigned int reserved; /**< */ + }X; + /** @endcond */ +} qurt_allsignal_t; +/** @} */ /* end_addtogroup all_signal_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_init + Initializes an all-signal object.\n + The all-signal object is initially cleared. + + @datatypes + #qurt_allsignal_t + + @param[out] signal Pointer to the all-signal object to initialize. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_init(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_destroy + Destroys the specified all-signal object.\n + @note1hang All-signal objects must be destroyed when they are no longer in use. + Failure to do this causes resource leaks in the QuRT kernel. \n + @note1cont All-signal objects must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_destroy(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_get + Gets signal values from the all-signal object. + + Returns the current signal values of the specified all-signal object. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to access. + + @return + Bitmask with current signal values. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_allsignal_get(qurt_allsignal_t *signal) +{ return signal->X.signals_in; } + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_wait + Waits on the all-signal object.\n + Suspends the current thread until all of the specified signals are set. + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 that it is not to be waited on. + + If a signal is set in an all-signal object, and a thread is waiting on the all-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + Unlike any-signals, all-signals do not need to explicitly clear any set signals in an all-signal + object before waiting on them again -- clearing is done automatically by the wait + operation. + + @note1hang At most, one thread can wait on an all-signal object at any given time. + Because signal clearing is done by the wait operation, no clear operation is + defined for all-signals. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to wait on. + @param[in] mask Signal mask value, which identifies the individual signals in the all-signal object + to wait on. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_wait(qurt_allsignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_set + Set signals in the specified all-signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit + value of 1 indicates that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the all-signal object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_set(qurt_allsignal_t *signal, unsigned int mask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLSIGNAL_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_anysignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_anysignal.h new file mode 100755 index 0000000000000..9619e2de562b4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_anysignal.h @@ -0,0 +1,225 @@ +#ifndef QURT_ANYSIGNAL_H +#define QURT_ANYSIGNAL_H +/** + @file qurt_anysignal.h + Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +Copyright (c) 2021 Qualcomm Technologies, Inc. +All rights reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== +Typedefs +======================================================================*/ + +/**@ingroup anysignals_types + qurt_signal_t supersedes qurt_anysignal_t. This type definition was added for backwards compatibility. */ +typedef qurt_signal_t qurt_anysignal_t; + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_init + Initializes an any-signal object.\n + The any-signal object is initially cleared. + + @datatypes + #qurt_anysignal_t + + @param[out] signal Pointer to the initialized any-signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_init(qurt_anysignal_t *signal) +{ + qurt_signal_init(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_destroy + Destroys the specified any-signal object. + + @note1hang Any-signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Any-signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_destroy(qurt_anysignal_t *signal) +{ + qurt_signal_destroy(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait + Wait on the any-signal object. \n + Suspends the current thread until any one of the specified signals is set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread is waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + + @return + Bitmask of current signal values. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_wait(qurt_anysignal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_set + Sets signals in the specified any-signal object. \n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be set, and 0 indicates not to set the sigmal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the any-signal object. + + @return + Bitmask of old signal values (before set). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_set(qurt_anysignal_t *signal, unsigned int mask); + + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_get + Gets signal values from the any-signal object.\n + Returns the current signal values of the specified any-signal object. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to access. + + @return + A bitmask with the current signal values of the specified any-signal object. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_get(qurt_anysignal_t *signal) +{ + return qurt_signal_get(signal); +} + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_clear + @xreflabel{sec:anysignal_clear} + Clears signals in the specified any-signal object.\n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object, which specifies the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + clear in the any-signal object. + + @return + Bitmask -- Old signal values (before clear). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_clear(qurt_anysignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait_timed + Waits on the any-signal object. \n + Suspends the current thread until any of the specified signals is set or timeout expires. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread was waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + @param[out] signals Bitmask of current signal values. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- timeout + #QURT_EINVALID -- Duration out of range + + @dependencies + None. + */ +/* ======================================================================*/ + +int qurt_anysignal_wait_timed(qurt_anysignal_t *signal, unsigned int mask, unsigned int *signals, unsigned long long int duration); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ANYSIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_api_version.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_api_version.h new file mode 100755 index 0000000000000..dfe53ae755054 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_api_version.h @@ -0,0 +1,77 @@ +#ifndef QURT_API_VERSION_H +#define QURT_API_VERSION_H +/*============================================================================== + +qurt_api_version.h + +GENERAL DESCRIPTION + API version file + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +/*============================================================================== + CONSTANTS AND DEFINITIONS +==============================================================================*/ +/** + * Each field of the QURT_API_VERSION definitions is an 8-bit unsigned integer. + * Main release has first 3 fields updated - Major, Minor and Release. + * - QURT_API_VERSION = Major, Minor, Release. + * Patch releases are supported by adding the extra field. + * - QURT_API_VERSION = Major, Minor, Release, Patch. + */ +// Major version is incremented for incompatible API changes. +#define QURT_API_VER_MAJOR 1 + +// Minor version is incremented for backward-compatible enhancements in the API +// set. +#define QURT_API_VER_MINOR 4 + +// RELEASE version is incremented for each release within a `MAJOR.MINOR` +// release. +#define QURT_API_VER_RELEASE 1 + +// Patch version is incremented when new API content is introduced on older LTS +// release. +#define QURT_API_VER_PATCH 0 + +/* Update the QURT_API_VERSION function macro. */ +#define QURT_API_VERSION_ENCODE(major, minor, release, patch) \ + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | \ + (((release) & 0xFF) << 8) | ((patch) & 0xFF)) + +/* Update the QURT_API_VERSION Macro. */ +#define QURT_API_VERSION \ + QURT_API_VERSION_ENCODE(QURT_API_VER_MAJOR, QURT_API_VER_MINOR, \ + QURT_API_VER_RELEASE, QURT_API_VER_PATCH) + +/** Usage: + * + * #if QURT_API_VERSION >= QURT_API_VERSION_ENCODE(1,4,0,0) + * qurt_func_2(a,b,c); + * #else + * qurt_func(a); + * #endif + * + */ +/* + Gets the QuRT API version. + + @return + QuRT API version. + + @dependencies + None. + */ +unsigned int qurt_api_version(void); + +#endif /* QURT_API_VERSION_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_assert.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_assert.h new file mode 100755 index 0000000000000..13cc2afd2e973 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_assert.h @@ -0,0 +1,51 @@ +#ifndef QURT_ASSERT_H +#define QURT_ASSERT_H +/** + @file qurt_assert.h + @brief Prototypes of qurt_assert API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@ingroup func_qurt_assert_error + Writes diagnostic information to the debug buffer, and raises an error to the QuRT kernel. + + @datatypes + None. + + @param[in] filename Pointer to the file name string. + @param[in] lineno Line number. + + @return + None. + + @dependencies + None. + */ +void qurt_assert_error(const char *filename, int lineno) __attribute__((noreturn)); + +#define qurt_assert(cond) ((cond)?(void)0:qurt_assert_error(__QURTFILENAME__,__LINE__)) + +/** @} */ /* end_ingroup func_qurt_assert */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ASSERT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_atomic_ops.h new file mode 100755 index 0000000000000..d9b2cff7d737c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_atomic_ops.h @@ -0,0 +1,1298 @@ +#ifndef QURT_ATOMIC_OPS_H +#define QURT_ATOMIC_OPS_H +/** + @file qurt_atomic_ops.h + @brief Prototypes of kernel atomic operations API. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * + * This file is only included by the main atomic_ops.h, so all of that + * file's definitions are available. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +///* Sanity check to ensure the smp flag is set in machines.py */ +//#if defined(__ATOMIC_OPS_IN_KERNEL__) && !defined(MACHINE_SMP) && CONFIG_NUM_UNITS > 1 +//#error CONFIG_NUM_UNITS > 1 but smp not defined in machines.py. +//#endif +#define QURT_INLINE __attribute__((always_inline)) + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_atomic_set + Sets the atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value Value to set. + + @return + Value successfuly set. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_set(unsigned int* target, unsigned int value) +{ + unsigned long tmp; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " memw_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic_and + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + None + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_and(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_and_return + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + AND result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_and_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_or + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_or(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_or_return + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + Returns the OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_or_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_xor + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_xor(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_xor_return + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_xor_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_set_bit + Sets a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_set_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_clear_bit + Clears a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_clear_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_change_bit + Toggles a bit in a atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_change_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1fU; + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_add(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add_return + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_add_unless + Adds the delta value to an atomic variable unless the current value in the target + matches the unless variable. + + @note1hang The function retries until load lock and store conditional + are successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] delta Value to add to the current value. + @param[in] unless Perform the addition only when the current value is not + equal to this unless value. + @return + TRUE -- 1 - Addition was performed. \n + FALSE -- 0 - Addition was not done. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_unless(unsigned int* target, + unsigned int delta, + unsigned int unless) +{ + unsigned int current_val; + unsigned int new_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%3)\n" + " p0 = cmp.eq(%0, %5)\n" + " if p0 jump 2f\n" + " %1 = add(%0, %4)\n" + " memw_locked(%3, p0) = %1\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"=&r" (new_val),"+m" (*target) + : "r" (target), "r" (delta), "r" (unless) + : "p0"); + + return (unsigned int)(current_val != unless); +} + +/**@ingroup func_qurt_atomic_sub + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_sub(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_sub_return + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_sub_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_inc + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_inc(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_inc_return + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_inc_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_dec + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_dec(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_dec_return + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_dec_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_compare_and_set + Compares the current value of the atomic variable with the + specified value and set to a new value when compare is successful. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val Old value to compare. + @param[in] new_val New value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE --Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_compare_and_set(unsigned int* target, + unsigned int old_val, + unsigned int new_val) +{ + unsigned int current_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memw_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (unsigned int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic_barrier + Allows the compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_barrier(void) +{ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); +} + + +/**@ingroup func_qurt_atomic64_set + Sets the 64-bit atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value 64-bit value to set. + + @return + Successfuly set value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_set(unsigned long long* target, unsigned long long value) +{ + unsigned long long tmp; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " memd_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic64_and_return + Bitwise AND operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise AND. + + @return + AND result of 64-bit atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_and_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_or + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_or(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_or_return + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_or_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_xor_return + Bitwise XOR operation of 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_xor_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_set_bit + Sets a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_set_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_clear_bit + Clears a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_clear_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_change_bit + Toggles a bit in a 64-bit atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_change_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_add(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add_return + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_add_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_sub_return + Subtracts a 64-bit integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_sub_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_inc + Increments a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_inc(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_inc_return + Increments a 64-bit atomic variable by one + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_inc_return(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_dec_return + Decrements a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_dec_return(unsigned long long *target) +{ + unsigned long long result; + long long minus1 = 0xFFFFFFFFFFFFFFFFLL; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (minus1) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_compare_and_set + Compares the current value of an 64-bit atomic variable with + the specified value and sets to a new value when compare is successful. + + @note1hang The function keep retrying until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val 64-bit old value to compare. + @param[in] new_val 64-bit new value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE -- Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE int +qurt_atomic64_compare_and_set(unsigned long long *target, + unsigned long long old_val, + unsigned long long new_val) +{ + unsigned long long current_val; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memd_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic64_barrier + Allows compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_barrier(void) +{ + /** @cond */ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); + /** @endcond */ +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_barrier.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_barrier.h new file mode 100755 index 0000000000000..7c6f787d43bc2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_barrier.h @@ -0,0 +1,140 @@ +#ifndef QURT_BARRIER_H +#define QURT_BARRIER_H + +/** + @file qurt_barrier.h + @brief Prototypes of Kernel barrier API functions. + + EXTERNALIZED FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup barrier_types +@{ */ +/*===================================================================== + Constants and macros +======================================================================*/ +#define QURT_BARRIER_SERIAL_THREAD 1 /**< Serial thread. */ +#define QURT_BARRIER_OTHER 0 /**< Other. */ + +#ifndef ASM +#include + +/*===================================================================== +Typedefs +======================================================================*/ + +/** QuRT barrier type. + */ +typedef union { + /** @cond */ + struct { + unsigned short threads_left; + unsigned short count; + unsigned int threads_total; + unsigned int queue; + unsigned int reserved; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_barrier_t; + +/** @} */ /* end_addtogroup barrier_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_init + Initializes a barrier object. + + @datatypes + #qurt_barrier_t + + @param[out] barrier Pointer to the barrier object to initialize. + @param[in] threads_total Total number of threads to synchronize on the barrier. + + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_init(qurt_barrier_t *barrier, unsigned int threads_total); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_destroy + Destroys the specified barrier. + + @note1hang Barriers must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Barriers must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to destroy. + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_destroy(qurt_barrier_t *barrier); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_wait + Waits on the barrier.\n + Suspends the current thread on the specified barrier. \n + The function return value indicates whether the thread was the last one to + synchronize on the barrier. + When a thread waits on a barrier, it is suspended on the barrier: \n + - If the total number of threads waiting on the barrier is less than the assigned value + of the barrier, no other action occurs. \n + - If the total number of threads waiting on the barrier equals the assigned value of the + barrier, all threads currently waiting on the barrier are awakened, allowing them to + execute past the barrier. + + @note1hang After its waiting threads are awakened, a barrier is automatically reset + and can be used again in the program without the need for re-initialization. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to wait on. + + @return + #QURT_BARRIER_OTHER -- Current thread awakened from barrier. \n + #QURT_BARRIER_SERIAL_THREAD -- Current thread is last caller of barrier. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_wait(qurt_barrier_t *barrier); + + +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BARRIER_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_busywait.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_busywait.h new file mode 100755 index 0000000000000..a4dab80a2520a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_busywait.h @@ -0,0 +1,62 @@ +#ifndef QURT_BUSYWAIT_H +#define QURT_BUSYWAIT_H + +/** + @file qurt_busywait.h + @brief Implementation of the busywait() function for + hardware based blocking waits that use the QTIMER as a reference. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ============================================================================*/ +/*============================================================================= + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Changes are listed in reverse chronological + * order. + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------------- + * 2018-03-20 pg Add Header file + ============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_busywait + Pauses the execution of a thread for a specified time.\n + Use for small microsecond delays. + + @note1hang The function does not return to the caller until + the time duration has expired. + + @param[in] pause_time_us Time to pause in microseconds. + + @return + None. + + @dependencies + None. + */ +void qurt_busywait (unsigned int pause_time_us); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BUSYWAIT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_callback.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_callback.h new file mode 100755 index 0000000000000..dc9b896c63454 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_callback.h @@ -0,0 +1,235 @@ +#ifndef QURT_CALLBACK_H +#define QURT_CALLBACK_H + +/** + @file qurt_callback.h + Definitions, macros, and prototypes for QuRT callback framework. + + QDI framework allows the development of root process drivers and services that + a user process client can interact with in a secure manner. QDI framework does + this by elevating the priviledge of user process thread, temporarily allowing + the thread execute in root context and letting it fall back to user context once + the QDI invocation is finished. + + The QuRT callback framework provides a safe mechanism for root process drivers + to execute callback functions in a user process. The framework hosts + dedicated worker threads in corresponding processes that handle the execution + of the callback function. This ensures that the callbacks occur in context of + the appropriate process thread, in result maintaining privilege boundaries. + + Prerequisites for use of this framework are: + 1. Driver is a QDI driver and client communicates with drivers using QDI + invocations. + 2. Appropriate callback configuration is specified in cust_config.xml for + the user process that intends to use this framework. + + qurt_cb_data_t is the public data structure that allows client to store all + the required information about the callback, including the callback function + and the arguments to pass to this function when it executes. + The client uses QDI interface to register this structure with root driver. + + Callback framework provides following APIs that a root driver can use to invoke callback. + These functions are described in qurt_qdi_driver.h header file. + + qurt_qdi_cb_invoke_async() triggers an asynchronous callback wherein the + invoking thread does not wait for the callback to finish executing. + + qurt_qdi_cb_invoke_sync() triggers a synchronous callback. Upon invocation + the invoking thread gets suspended till the callback function finishes execution. + + qurt_qdi_cb_invoke_sync_with_data() invokes a synchronous callback similar to + qurt_qdi_cb_invoke_sync(). It allows user to pass large data along with + the callback invocation to be utlized during the callback execution. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int qurt_cb_result_t; + +/* Callback framework error codes. + Callback framework returns a nonzero value if callback invocation is unsuccessful. + Following macros highlight cause of failure in more detail. +*/ +#define QURT_CB_ERROR -1 /* Callback registration failed.\n*/ +#define QURT_CB_OK 0 /* Success.\n*/ +#define QURT_CB_MALLOC_FAILED -2 /* QuRTOS malloc failure.\n*/ +#define QURT_CB_WAIT_CANCEL -3 /* Process exit cancelled wait operation.\n*/ +#define QURT_CB_CONFIG_NOT_FOUND -4 /* Callback configuration for process was not found.\n*/ +#define QURT_CB_QUEUE_FULL -5 /* Callback queue is serving at maximum capacity.*/ +/** @addtogroup cb_types +@{ */ +/** Callback registration data structure. + This data structure is used by a client attempting to register a callback with a QDI driver. + It holds the address of callback function and the argument supplied to the callback + function when it executes. +*/ +typedef struct { + /** @cond */ + void* cb_func; /*< Pointer to the callback function. */ + unsigned cb_arg; /*< Not interpreted by the framework.*/ + /** @endcond */ +} qurt_cb_data_t; + +/** @cond */ +/* Defines used as default if cust_config does not specify them. */ +#define CALLBACK_WORKER_STACK_SIZE 0x2000 +/** @endcond */ +/** @} */ /* end_addtogroup cb_typess */ +/**@ingroup func_qurt_cb_data_init + Initializes the callback data structure. + Entity registering a callback with the root process driver must call this function + to initialize callback registration data structure to the default value. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_init (qurt_cb_data_t* cb_data){ + cb_data->cb_func = NULL; + cb_data->cb_arg = 0; +} + +/**@ingroup func_qurt_cb_data_set_cbfunc + Sets up the callback function in the callback registration data structure. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_func Pointer to the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbfunc (qurt_cb_data_t* cb_data, void* cb_func){ + cb_data->cb_func = cb_func; +} + +/**@ingroup func_qurt_cb_data_set_cbarg + Sets up the callback argument. + This function sets up the argument passed to the callback function when it executes. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_arg Argument for the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbarg (qurt_cb_data_t* cb_data, unsigned cb_arg){ + cb_data->cb_arg = cb_arg; +} + +/** @cond */ +/**@ingroup driver_support_functions + Invokes an asynchronous callback for a specified process. + A driver that resides in the root process calls this API to launch a callback in + a process described by the client_handle. + After the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is not suspended during the callback execution period. + The API returns immediately with a success/failure error code. + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_async(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process. + A driver that resides in a root process calls this API to launch a sync callback in + a process described by the client_handle. + AFter the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is suspended during the callback execution period. + If the process in which to execute the callback exits or terminates, the caller is + woken up with error code #QURT_CB_WAIT_CANCEL (refer to qurt_callback.h). + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process, passing driver data to the user PD. + This function is similar to qurt_qdi_cb_invoke_sync() and allows the driver to pass arbitrary data to + the user process as part of the callback invocation. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @param data Driver arbitrary data to pass to the user process. Memory pointed to by data + must be accessible to the user PD. The root driver can allocate such memory by + using qurt_mem_mmap(). + @param data_len Driver arbitrary data length. + + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync_with_data( int client_handle, + qurt_cb_data_t* cb_data, + int prio, + void *data, + unsigned data_len + ); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_clade.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_clade.h new file mode 100755 index 0000000000000..d7442cf98dd94 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_clade.h @@ -0,0 +1,62 @@ +#ifndef QURT_CLADE_H +#define QURT_CLADE_H +/** + @file qurt_clade.h + @brief Prototypes of Cache Line Accelerated Decompression Engine (CLADE) API. + CLADE is a cache line level memory compression system that is used to + decrease DRAM usage. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_clade2_get + Reads the value of the clade2 register. + + @param[in] offset Offset from the clade2 cfg base. + @param[out] *value Pointer to the register value read from the offset. + + @return + #QURT_EOK - Successfully read the value from the register at offset \n + #QURT_EINVALID - Offset passed is incorrect + + @dependencies + None. + */ +int qurt_clade2_get(unsigned short offset, unsigned int *value); + +/**@ingroup func_qurt_clade2_set + Sets the PMU register; only PMU_SEL register can be set. + + @param[in] offset Offset from the QURTK_clade2_cfg_base. + @param[in] value Value to set at offset. + + @return + #QURT_EOK -- Successfully set the value at offset. \n + #QURT_ENOTALLOWED -- Set operation performed at an offset other than CLADE2_PMU_SELECTION_REG. + + @dependencies + None. + */ +int qurt_clade2_set(unsigned short offset, unsigned int value); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CLADE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cond.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cond.h new file mode 100755 index 0000000000000..6e65ed82a8393 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cond.h @@ -0,0 +1,219 @@ +#ifndef QURT_COND_H +#define QURT_COND_H +/** + @file qurt_cond.h + @brief Prototypes of kernel condition variable object API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup condition_variables_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** QuRT condition variable type. */ +typedef union { + /** @cond */ + unsigned long long raw; + struct { + unsigned int count; + unsigned int n_waiting; + unsigned int queue; + unsigned int reserved; + }X; + /** @endcond */ +} qurt_cond_t; + +/** @} */ /* end_addtogroup condition_variables_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_cond_init + Initializes a conditional variable object. + + @datatypes + #qurt_cond_t + + @param[out] cond Pointer to the initialized condition variable object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_init(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_destroy + Destroys the specified condition variable. + + @note1hang Conditions must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Conditions must not be destroyed while they are still in use. If this occurs, + the behavior of QuRT is undefined. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to destroy. + + @return + None. + + */ +/* ======================================================================*/ +void qurt_cond_destroy(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_signal + Signals a waiting thread that the specified condition is true. \n + + When a thread wishes to signal that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the signal condition operation. \n + -# Unlock the mutex. + + @note1hang Failure to properly lock and unlock a mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_signal(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_broadcast + Signals multiple waiting threads that the specified condition is true.\n + When a thread wishes to broadcast that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the broadcast condition operation. \n + -# Unlock the mutex.\n + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_broadcast(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable (suspends the thread and unlocks the mutex). + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t \n + #qurt_mutex_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait(qurt_cond_t *cond, qurt_mutex_t *mutex); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait2 + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable, which suspends the thread and unlocks the mutex. + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @note1cont This is the same API as qurt_cond_wait(), use this version + when using mutexes of type #qurt_rmutex2_t. + + @datatypes + #qurt_cond_t \n + #qurt_rmutex2_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with the condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait2(qurt_cond_t *cond, qurt_rmutex2_t *mutex); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_COND_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_consts.h new file mode 100755 index 0000000000000..b1e35998e73b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_consts.h @@ -0,0 +1,315 @@ +#ifndef QURT_CONSTS_H +#define QURT_CONSTS_H + +/** + @file qurt_consts.h + @brief QuRT constants and definitions + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* Definitions of system events. System events suspend + a thread and put it into suspending_list. + The system event number is saved in CONTEXT::error::cause field + of the suspended thread. An event handler thread such as + page fault handler or system error handler can wake up the suspended + thread. + */ +#define QURT_EVENT_PAGEFAULT 0x1 /* Page fault event. */ +#define QURT_EVENT_SYSTEM_ERR 0x2 /* System error event. */ +#define QURT_EVENT_SUSPEND 0x3 +#define QURT_EVENT_PROCESS_EXIT 0x4 /* Process termination event.*/ + +#define QURT_SYSENV_MAX_THREADS_TYPE 1 /* Maximum threads object. */ +#define QURT_SYSENV_PROCNAME_TYPE 2 /* Process name object. */ +#define QURT_SYSENV_MAX_PI_PRIO_TYPE 3 /* Maximum pi priority object. */ +#define QURT_SYSENV_ARCH_REV_TYPE 4 /* Architecture version object. */ +#define QURT_SYSENV_APP_HEAP_TYPE 5 /* Application heap object. */ +#define QURT_SYSENV_REGION_ATTR_DEFAULT 7 /* Default region attributes. */ +#define QURT_SYSENV_STACK_PROFILE_COUNT_TYPE 8 /* Stack profile count type. */ +#define QURT_SYSENV_ISLAND_CONFIG_TYPE 9 /*island configuration check*/ +#define QURT_SYSENV_HTHREADS_TYPE 10 /* Active threads objec */ +#define QURT_SYSENV_CONFIG_IMAGE_START_LO 11 /* Config image start address for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_START_HI 12 /* Config Image start address for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_LO 13 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_HI 14 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_PLATPARAMS 15 /* Platformparams for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_SIZE 16 /* Config image Size for DTB parsing */ +#define QURT_SYSENV_L2_CACHE_LINE_SIZE 17 /*L2 cache line size*/ + +/* Get q6 regs */ +#define QURT_GET_SSR 1 +#define QURT_GET_CCR 2 +#define QURT_GET_CFGBASE 3 +#define QURT_GET_SYSCFG 4 +#define QURT_GET_REV 5 + + +/** @cond rest_reg_dist */ +/** @addtogroup performance_monitor_macros +@{ */ + +/* PMU */ +#define QURT_PMUCNT0 0 /**< */ +#define QURT_PMUCNT1 1 /**< */ +#define QURT_PMUCNT2 2 /**< */ +#define QURT_PMUCNT3 3 /**< */ +#define QURT_PMUCFG 4 /**< */ +#define QURT_PMUEVTCFG 5 /**< */ + +/* new since V55 */ +#define QURT_PMUCNT4 6 /**< */ +#define QURT_PMUCNT5 7 /**< */ +#define QURT_PMUCNT6 8 /**< */ +#define QURT_PMUCNT7 9 /**< */ +#define QURT_PMUEVTCFG1 10 /**< */ + +/* new since V61 */ +#define QURT_PMUSTID0 11 /**< */ +#define QURT_PMUSTID1 12 /**< */ + +#define QURT_PMUCNTSTID0 13 /**< */ +#define QURT_PMUCNTSTID1 14 /**< */ +#define QURT_PMUCNTSTID2 15 /**< */ +#define QURT_PMUCNTSTID3 16 /**< */ +#define QURT_PMUCNTSTID4 17 /**< */ +#define QURT_PMUCNTSTID5 18 /**< */ +#define QURT_PMUCNTSTID6 19 /**< */ +#define QURT_PMUCNTSTID7 20 /**< */ + +/** @} */ /* end_addtogroup performance_monitor_macros */ +/** @endcond */ + +/* + Power collapse operation +*/ +#define QURT_POWER_SHUTDOWN 0 /**< */ +#define QURT_TCXO_SHUTDOWN 1 /**< */ +#define QURT_POWER_CMD_PREPARE 0 /**< */ +#define QURT_POWER_CMD_PERFORM 1 /**< */ +#define QURT_POWER_CMD_EXIT 2 /**< */ +#define QURT_POWER_CMD_FAIL_EXIT 3 /**< */ +#define QURT_POWER_CMD_PERFORM_L2_RETENTION 4 /**< */ +#define QURT_POWER_CMD_PERFORM_SAVE_TCM 5 /**< */ +#define QURT_POWER_CMD_DEEP_SLEEP 6 /**< */ + + +/** @addtogroup thread_macros +@{ */ +#define QURT_MAX_HTHREAD_LIMIT 8U /**< Limit on the maximum number of hardware threads supported by QuRT for any + Hexagon version. Use this definition to define arrays, and so on, in + target independent code. */ +/** @} */ /* end_addtogroup thread_macros */ + +/** @cond internal_only */ +/** @addtogroup power_management_macros +@{ */ +/** + L2 cache retention mode +*/ +#define QURT_POWER_SHUTDOWN_TYPE_L2NORET QURT_POWER_CMD_PERFORM /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_L2RET QURT_POWER_CMD_PERFORM_L2_RETENTION /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_SAVETCM QURT_POWER_CMD_PERFORM_SAVE_TCM /**< */ +/** @} */ /* end_addtogroup power_management_macros */ +/** @endcond */ + +/* + QURT_system_state + Use for debugging the shutdown/startup process. + + State transition for cold boot: + QURT_BOOT_SETUP_ISDB --> QURT_CBOOT_BSP_INIT --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT --> + QURT_CBOOT_KERNEL_INIT_DONE --> QURT_CBOOT_PLAT_CONFIG_DONE --> + QURT_CBOOT_ROOT_TASK_STARTED + + State transition for power collapse: + QURT_PREPARE_SINGLE_MODE --> QURT_PERFORM_IPEND --> + QURT_PERFORM_SAVE_TLB --> QURT_PERFORM_SWITCH_PC --> + cache flush states (dependent on L2 retention config) + + State transition for warm boot: + QURT_BOOT_SETUP_ISDB --> QURT_WBOOT_INIT_TLB --> + QURT_WBOOT_SET_1TO1_MAP --> QURT_WBOOT_REMOVE_1TO1_MAP --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT +*/ +#define QURT_PREPARE_SINGLE_MODE 1 /**< */ +#define QURT_PREPARE_END 2 /**< */ +#define QURT_PERFORM_IPEND 3 /**< */ +#define QURT_PERFORM_SAVE_ISDP 4 /**< */ +#define QURT_PERFORM_SAVE_PMU 5 /**< */ +#define QURT_PERFORM_SAVE_TLB 6 /**< */ +#define QURT_PERFORM_SWITCH_PC 7 /**< */ +#define QURT_PERFORM_EXIT 8 /**< */ +#define QURT_FLUSH_L1CACHE 9 /**< */ +#define QURT_FLUSH_L2CACHE 0xA /**< */ +#define QURT_FLUSH_CACHE_DONE 0xB /**< */ +#define QURT_SWITCH_PC_DONE 0xC /**< */ +#define QURT_BOOT_SETUP_ISDB 0xD /**< */ +#define QURT_WBOOT_INIT_TLB 0xE /**< */ +#define QURT_WBOOT_SET_1TO1_MAP 0xF /**< */ +#define QURT_WBOOT_CFG_ADV_SYSCFG 0x10 /**< */ +#define QURT_WBOOT_REMOVE_1TO1_MAP 0x11 /**< */ +#define QURT_CBOOT_BSP_INIT 0x12 /**< */ +#define QURT_CBOOT_END_CLEAN_L1CACHE 0x13 /**< */ +#define QURT_CBOOT_END_CLEAN_INIT 0x14 /**< */ +#define QURT_CBOOT_END_OS_INIT 0x15 /**< */ +#define QURT_CBOOT_TLB_DUMP_LOAD 0x16 /**< */ +#define QURT_CBOOT_TLB_STATIC_LOAD 0x17 /**< */ +#define QURT_CBOOT_KERNEL_INIT_DONE 0x18 /**< */ +#define QURT_CBOOT_PLAT_CONFIG_DONE 0x19 /**< */ +#define QURT_CBOOT_ROOT_TASK_STARTED 0x1A /**< */ +#define QURT_IMPRECISE_EXCEPTION 0x1B /**< */ +#define QURT_WBOOT_DEBUG_L2_START 0x1C /**< */ +#define QURT_WBOOT_DEBUG_L2_END 0x1D /**< */ +#define QURT_NMI_SAVE_L2VIC_COMPLETE 0x1E /**< */ +#define QURT_NMI_HANDLER_COMPLETE 0x1F /**< */ +#define QURT_NMI_AFTER_SAVE_GLOBAL 0x20 /**< */ +#define QURT_WBOOT_START 0x21 /**< */ +#define QURT_ENTER_ISLAND 0x22 /**< */ +#define QURT_EXIT_ISLAND 0x23 /**< */ +#define QURT_LOAD_NOTIFIER_TCB 0x24 /**< */ +#define QURT_ABNORMAL_RESET 0x25 /**< */ +/* + Thread attributes +*/ + +#define QURT_THREAD_ATTR_GP 0x00000002 /*< */ +#define QURT_THREAD_ATTR_UGP 0x00000003 /*< User general pointer (UGP)*/ +#define QURT_THREAD_ATTR_PREFETCH 0x00000004 /*< */ +#define QURT_THREAD_ATTR_TID 0x00000005 /*< */ +#define QURT_THREAD_ATTR_CACHE_PART 0x00000007 /*< */ +#define QURT_THREAD_ATTR_COPROCESSOR 0x00000008 /*< */ +#define QURT_THREAD_ATTR_GET_L2CACHE_PART 0x00000009 /*< */ +#define QURT_THREAD_ATTR_SET_FRML 0x0000000A /*< */ +#define QURT_THREAD_ATTR_STID_GET 0x0000000B /*< */ +#define QURT_THREAD_ATTR_STID_SET 0x0000000C /*< */ +#define QURT_THREAD_ATTR_AUTOSTACK 0x0000000D /*< */ +#define QURT_THREAD_ATTR_SYSTEM_THREAD 0x0000000E /*< */ +#define QURT_THREAD_ATTR_STID_SET2 0x0000000F /*< */ +#define QURT_THREAD_ATTR_STID_SET2_ACKNOWLEDGE 0x00000010 /*< */ +#define QURT_THREAD_ATTR_STID_GET2 0x00000011 /*< */ + +/** Cache operations*/ +#define QURT_DCCLEAN 0U /* Clean Dcache. */ +#define QURT_DCINV 1U /* Invalidate Dcache. */ +#define QURT_DCCLEANINV 2U /* Clean and invalidate Dcache. */ +#define QURT_ICINV 3U /* Invalidate Icache. */ +#define QURT_DUMP_DCTAGS 4U /* For testing purpose. */ +#define QURT_FLUSH_ALL 5U /* Flush entire L1 and L2 cache. */ +#define QURT_TABLE_FLUSH 6U /* Flush based on table of physical pages */ +#define QURT_CLEAN_INVALIDATE_ALL 7U /* Flush and invalidate entire L1 and L2 cache. */ +#define QURT_L2CACHE_LOCK_LINES 8U /* l2 cache lock lines */ +#define QURT_L2CACHE_UNLOCK_LINES 9U /* l2 cache unlock lines */ +#define QURT_CLEAN 10U /* Flush L1 and L2 cache */ +#define QURT_CLEAN_INVALIDATE 11U /* Flush and invalidate L1 and L2 cache. */ +#define QURT_CLEAN_INVALIDATE_L2 12U /* Flush and invalidate entire L2 cache. */ + +/**@ingroup chapter_prefined_symbols */ +/**@xreflabel{hdr:QURT_API_VERSION}*/ + + +/* Process state. */ +#define QURT_UPDATE_PROCESS_STATE 0 /**< */ +#define QURT_MP_INIT 1 /*< */ +#define QURT_MP_RUNNING 2 /*< */ +#define QURT_MP_STOPPED 3 /*< */ + +/* QuRT reset reason. */ +#define QURT_NORMAL_BOOT 0 /* Normal boot. */ +#define QURT_WARM_BOOT 1 /* Power collapse warm boot. */ +#define QURT_WARM_BOOT_L2_RETENTION 2 /* Power collapse with L2 retention warm boot. */ +#define QURT_WARM_BOOT_SAVE_TCM 3 /* Power collapse with saving TCM. */ +#define QURT_QUICK_BOOT 4 /* Deep sleep. */ + +/* QuRT Wait for Idle command */ +#define QURT_WAIT_FOR_IDLE_DISABLE 0 /*< */ +#define QURT_WAIT_FOR_IDLE_ENABLE 1 /*< */ +#define QURT_WAIT_FOR_IDLE 2 /*< */ +#define QURT_WAIT_FOR_IDLE_CANCEL 3 /*< */ + +/*QuRT island exit stages */ +#define QURT_ISLAND_EXIT_STAGE1 1 /*< */ +#define QURT_ISLAND_EXIT_STAGE2 2 /*< */ + +#define QURT_MAX_NAME_LEN 64 /*< */ + +#define MAX_POOL_RANGES 16 /*< */ + +/* key definitions for debug thread info */ +//#define MAX_TCB_KEY 40 //whatever is a good number or makes debug thread structure be 1K +#define KEY_SCHDULER_STATE 1 /*< */ +#define KEY_PRIORITY 2 /*< */ +#define KEY_PRIORITY_ORIG 3 /*< */ +#define KEY_STACK_BOTTOM 4 // Currently not populated +#define KEY_STACK_TOP 5 // Currently not populated +#define KEY_HVX_STATE 6 /*< */ +#define KEY_FUTEX_OBJECT 7 /*< */ +#define KEY_THREAD_ID 8 /*< */ +#define KEY_PROFILE_CYCLE_LO 9 // Currently not populated +#define KEY_PROFILE_CYCLE_HI 10 // Currently not populated +#define KEY_ERROR_ADDRESS 11 // This holds the BADVA +#define KEY_ERROR_CAUSE 12 // This is the same as QURT_error_info.cause +#define KEY_ERROR_CAUSE2 13 // This is the same as QURT_error_info.cause2 +#define KEY_ERROR_SSR 14 /*< Holds the SSR value */ +#define QURT_RESERVED -1 + +/* VTLB method IDs. */ +#define QURT_VTLB_ENTRY_CREATE 0U +#define QURT_VTLB_ENTRY_DELETE 1U +#define QURT_VTLB_ENTRY_READ 2U +#define QURT_VTLB_ENTRY_WRITE 3U +#define QURT_VTLB_ENTRY_PROBE 4U +#define QURT_VTLB_ENTRY_SPLIT 5U +#define QURT_VTLB_ENTRY_MERGE 6U +#define QURT_VTLB_ENTRY_STATISTICS 7U +#define QURT_VTLB_ENTRY_SET_SPECIAL 8U +#define QURT_VTLB_QUEUE_PPAGE 9U +#define QURT_VTLB_RECLAIM_STACK_PAGES 10U +#define QURT_VTLB_ASID_SET_STATE_FAST 11U +#define QURT_VTLB_ASID_SET_STATE 12U +#define QURT_VTLB_ENTRY_SET_EXTENSION 13U +#define QURT_VTLB_ENTRY_CLEAR_EXTENSION 14U + +/* VTCM window access control HWIO programming. */ +#define QURT_VTCM_WINDOW_ENABLE 1U +#define QURT_VTCM_WINDOW_DISABLE 0U +#define QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT 0xFFFU +#define QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT 0U + +/** @cond */ +/* ETM source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< Memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< Memory source of SAC* is data. */ + +/* ETM PID status flags */ +#define QURT_ETM_NO_PID 0xFFFFFFFF /**< No PID is selected. */ +/** @endcond */ + +/* execution context */ +#define QURT_CTX_USER 1 +#define QURT_CTX_GUEST 2 + +/* Profiling STID */ +#define QURT_STID_DEFAULT 0U + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cycles.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cycles.h new file mode 100755 index 0000000000000..b599493f5d563 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_cycles.h @@ -0,0 +1,301 @@ + +#ifndef QURT_CYCLES_H +#define QURT_CYCLES_H 1 +/** + @file qurt_cycles.h + Prototypes of kernel pcycle API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ + +/**@ingroup func_qurt_profile_reset_idle_pcycles + @xreflabel{hdr:qurt_profile_reset_idle_pcycles} + Sets the per-hardware-thread idle cycle counts to zero. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_idle_pcycles (void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_thread_pcycles + @xreflabel{hdr:qurt_profile_get_thread_pcycles} + Gets the count of the running processor cycles for the current thread.\n + Returns the current running processor cycle count for the current QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @return + Integer -- Running processor cycle count for current thread. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_profile_get_thread_pcycles(void); + + +/*======================================================================*/ +/**@ingroup func_qurt_get_core_pcycles + @xreflabel{hdr:qurt_get_core_pcycles} + Gets the count of core processor cycles executed.\n + Returns the current number of running processor cycles executed since the Hexagon + processor was last reset. + + This value is based on the hardware core clock, which varies in speed according to the + processor clock frequency. + + @note1hang Because the hardware core clock stops running when the processor shuts + down (due to all of the hardware threads being idle), treat the cycle values returned + by this operation as relative rather than absolute. + + @note1cont Thread cycle counts are valid only in the V4 Hexagon processor version. + + @return + Integer -- Current count of core processor cycles. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_get_core_pcycles(void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles + + @deprecated use #qurt_profile_get_idle_pcycles2 instead + + Gets the current idle processor cycle counts for a maximum of 6 hardware threads. Use + #qurt_profile_get_idle_pcycles2 for reading pcycles without limitation on maximum hardware threads. + + This operation accepts a pointer to a user-defined array, and writes to the array the current + idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling is enabled or not, + and resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be a minimum of the number of hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_idle_pcycles (unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles2 + Gets the current idle processor cycle counts for maximum available hardware threads. + + This operation accepts a pointer to a user-defined array with length in bytes, and writes + to the array the current idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling enable status, and + resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be equivalent to the number of hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, + it returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_idle_pcycles2 (unsigned long long *pcycles, unsigned int length_in_bytes); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles + + @deprecated use #qurt_profile_get_threadid_pcycles2 instead + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for a maximum of 6 hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Valid thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be a minimum of the number of + hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_threadid_pcycles (int thread_id, unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles2 + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for maximum available hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be equivalent to the number of + hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, it + returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + #QURT_ENOTHREAD -- Operation failed due to invalid #thread_id + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_threadid_pcycles2 (int thread_id, unsigned long long *pcycles, unsigned int length_in_bytes); + + +/*======================================================================*/ +/**@ingroup func_qurt_profile_reset_threadid_pcycles + @xreflabel{hdr:qurt_profile_reset_threadid_pcycles} + Sets the per-hardware-thread running cycle counts to zero for the specified QuRT thread. + + @param[in] thread_id Thread identifier. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_threadid_pcycles (int thread_id); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_enable + @xreflabel{hdr:qurt_profile_enable} + Enables profiling.\n + Enables or disables cycle counting of the running and idle processor cycles. + Profiling is disabled by default. \n + + @note1hang Enabling profiling does not automatically reset the cycle counts -- this must be + done explicitly by calling the reset operations before starting cycle counting. + Cycle counting starts from the instant of it was enabled using this API, and + halts on profiling disable. + + @param[in] enable Profiling. Values: \n + - 0 -- Disable profiling \n + - 1 -- Enable profiling @tablebulletend + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_enable (int enable); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_pcycles + @xreflabel{hdr:qurt_get_hthread_pcycles} + Reads the GCYCLE_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values are 1 through . + + + @return + Value read from GCYCLE_nT register. This value indicates the total number of pcycles that got executed + from reset to current point of execution when n threads are in run mode + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_pcycles(int n); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_commits + @xreflabel{hdr:qurt_get_hthread_commits} + Reads the GCOMMIT_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values: 1 through . + + @return + Value read from the GCOMMIT_nT register. This value indicates the total number of packets + committed from reset to current point of execution when n threads are in run mode. + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_commits(int n); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_devtree.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_devtree.h new file mode 100755 index 0000000000000..4adee45bb44a2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_devtree.h @@ -0,0 +1,161 @@ +#ifndef QURT_DEVTREE_H +#define QURT_DEVTREE_H +/** + @file qurt_devtree.h + @brief Prototypes and structures for device tree aware QuRT library function. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +*/ +/*qurt_callback is included by qurt_qdi_driver.h and depends on NULL being def. + callback is not used here, so define NULL here to avoid including the world*/ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "libfdt.h" +#include "DTBExtnLib.h" +#include "qurt_qdi_ext.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_BLOB_ID (-1) +#define DEFAULT_BLOB_ID 0 + +/** QURT Device Tree Mapping Macros */ +#define QURT_DT_MAPPING_FAILED (-1) +#define QURT_DT_FLAG_ISLAND 0x1 +#define QURT_DT_FLAG_PHYSADDR 0x2 + +/** Device Tree type for Root PD Device tree. +    Root PD Device Tree will typically describe the hardware in the subsystem. +    This is the /soc portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_ROOT 0 + +/** Device Tree type for Local Device tree. +    Local Device Tree will typically contain the software settings. +    This is the /sw portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_LOCAL 1 + +int qurt_devtree_init(void); + +/**@ingroup func_qurt_dt_mapping_create + Creates a memory mapping from the specified property of the specified device + tree node. Returns virtual addresses and sizes. + + @param[in] offset Device tree node offset. + @param[in] flags Flags to configure memory. Overloaded as property + index if reg_name is NULL. + @param[in] reg_name Identifies property to use for mapping, should + resemble a region. + @param[out] vaddr Return pointer for the virtual region address. + @param[out] size Return pointer for the virtual region size. + + @return + Result code indicating success or failure \n +*/ +int qurt_dt_mapping_create(fdt_node_handle *devtreeNode, int flags, char *regionName, int regionIdx, + unsigned long long *vaddr, unsigned long long *size); + +/**@ingroup func_qurt_dt_mapping_create2 + + Creates a memory mapping from the specified property of the specified device + tree node. + + Returns virtual addresses and sizes according to architecture (i.e either 32 bit or 64 bit). + + @param[in] devtreeNode Device Tree node + + @param[in] dt_map_flags Flags to configure memory mapping and are reserved for future purpose. + (0) - Default value assumes details from DT node are phys address, size. + QURT_DT_FLAG_ISLAND + + NOTE: The PA needs to be added to corresponding island spec to create an island mapping + + @param[in] regionName NULL or name of index in range to return, should + resemble a region. Ex.reg-names = "base", "rx", "tx"; + + @param[in] regionIdx Index of range to return. Ex reg = <0x1000 0x20>, <0x10000 0x100>, <0x18000 0x100 >; + + NOTE: If client specifies both re_name & regionIdx. The precedence of + region name is taken over and region index is ignored. + + @param[in] dt_map_perm Mapping access permissions(R/W), + QURT_PERM_READ + QURT_PERM_WRITE + + @param[in] cache_attr QuRT cache mode type's : + QURT_MEM_CACHE_DEVICE + QURT_MEM_CACHE_WRITEBACK + Other required cache type enums in qurt_types.h can also be passed. + + NOTE: No default value for cache & perm is present. + Client always needs to pass any of defined the flags. + + @param[out] vaddr Return pointer to the variable that holds the virtual address + @param[out] size Return pointer for the virtual region size. + + @return + #QURT_EOK Success indicating mapping created properly. + #QURT_DT_MAPPING_FAILED Failed to create mapping. + #QURT_EINVALID Mismatch in the architecture. + + else FdtLib or thirdparty error code. + +*/ +int qurt_dt_mapping_create2(fdt_node_handle *devtreeNode, unsigned int dt_map_flags, + char *regionName, int regionIdx, unsigned int dt_map_perm, int cache_attr, void **vaddr, size_t *size); + +/**@ingroup func_qurt_dt_isr_register + Device tree aware registration of an interrupt service routine (ISR) to an ISR thread. + The interrupt defined in the specified device tree node is enabled when this function returns success. + + @datatypes + #qurt_thread_t \n + #fdt_node_handle + + @param[in] dt_node Device tree node that specifies the interrupt property. + @param[in] dt_int_index Index of the specific interrupt to use within the device tree node structure. + Specify either this or int_name, use -1 if string is used. + @param[in] dt_int_name Name of the specific interrupt to use within the device tree node structure. + Either this or int_index should be specified, use NULL if index is used + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create(), defined by qurt_isr_register2(). + @param[in] prio Priority of the ISR, defined by qurt_isr_register2(). + @param[in] flags Defines ACK type. Values : \n + #QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the kernel. + #QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + Defined by qurt_isr_register2(). + @param[in] isr ISR with proto type void isr (void *arg, int int_num), defined by qurt_isr_register2(). + @param[in] arg First argument of the ISR when it is called to service the interrupt, defined by qurt_isr_register2(). + + @return + #QURT_EOK -- Successfully registered the ISR for the interrupt \n + #QURT_EINT -- Interrupt not configured \n + #QURT_EINVALID -- Invalid thread ID \n + #QURT_EDISABLED -- The feature is disabled \n + #QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Create the thread ID qurt_isr_create(). + ISR registration completed with qurt_isr_register2(). + */ +int qurt_dt_isr_register(fdt_node_handle *dt_node, int dt_int_index, char * dt_int_name, qurt_thread_t isr_thread_id, + unsigned short prio, unsigned short flags, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_dt_blob_id_get + Returns the Blob ID for the Blob type passed. + The value returned from this API can be passed as Blob ID parameter to DTBExtnLib APIs. + + @param[in] blob_type  Blob type to look up. + @return Blob ID for the passed Blob Type. +*/ +int qurt_dt_blob_id_get(unsigned int blob_type); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ecc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ecc.h new file mode 100755 index 0000000000000..09312684e99af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ecc.h @@ -0,0 +1,168 @@ +#ifndef QURT_ECC_H +#define QURT_ECC_H + + +/*===================================================================== + + @file qurt_ecc.h + @brief Prototypes of QuRT memory ECC API functions + + Copyright (c) 2018, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup exception_handling_types +@{ */ +// ECC memory definition +typedef enum { + QURT_ECC_MEM_L1_ICACHE = 0, /**< ECC memory L1 ICache. */ + QURT_ECC_MEM_L1_DCACHE = 1, /**< ECC memory L1 DCache.*/ + QURT_ECC_MEM_L2_CACHE = 2, /**< ECC memory L2 Cache.*/ + QURT_ECC_MEM_VTCM = 3 /**< ECC memory VTCM.*/ +} qurt_ecc_memory_t; +/** @} */ /* end_addtogroup exception_handling_types */ + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup exception_handling_macros +@{ */ + +#define QURT_ECC_ERR_DETECTED_STATUS 0 /**< ECC error detected. */ +#define QURT_ECC_ERR_TYPE 1 /**< ECC error type.*/ +// ECC status type + +#define QURT_ECC_CORRECTABLE_COUNT (1<<0) /**< ECC correctable count.*/ +#define QURT_ECC_UNCORRECTABLE_COUNT (1<<1) /**< ECC uncorrectable count.*/ +#define QURT_ECC_REGION_LOGGING (1<<2) /**< ECC region logging.*/ +// ECC enable/disable definition + +#define QURT_ECC_PROTECTION_DISABLE (0<<0) /**< Bit 0. */ +#define QURT_ECC_PROTECTION_ENABLE (1<<0) /**< Bit 0. */ +/** @} */ /* end_addtogroup exception_handling_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_ecc_enable + Enables or disables ECC protection on a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] enable Set to one of the following values: + - #QURT_ECC_PROTECTION_ENABLE + - #QURT_ECC_PROTECTION_DISABLE @tablebulletend + + @return + - #QURT_EOK -- ECC enabling or disabling setup is performed successfully + - Others -- Failure + + @dependencies + None. + */ +int qurt_ecc_enable( qurt_ecc_memory_t memory, unsigned int enable ); + + +/**@ingroup func_qurt_ecc_get_error_status + Gets ECC error status for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following: + - #QURT_ECC_ERR_DETECTED_STATUS + - #QURT_ECC_ERR_TYPE @tablebulletend + + @return + Returns the following when the type is #QURT_ECC_ERR_DETECTED_STATUS: + - 0 -- No error detected \n + - 1 -- At least one error detected \n + Returns the following when the type is #QURT_ECC_ERR_TYPE: \n + - 0 through 1 -- Correctable error \n + - 2 -- Uncorrectable error + + @dependencies + None. + */ +int qurt_ecc_get_error_status( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_get_error_count + Gets the ECC error count for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values:\n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT @tablebulletend + + @return + Error count for the specified error type. + + @dependencies + None. + */ +int qurt_ecc_get_error_count( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_clear_error_count + Clears ECC error count or region logging for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: \n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one or multiple OR'ed of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT \n + - #QURT_ECC_REGION_LOGGING @tablebulletend + + @return + #QURT_EOK -- Error count successfully cleared \n + Others -- Failure at clearing the error count + + @dependencies + None. + */ +int qurt_ecc_clear_error_count( qurt_ecc_memory_t memory, unsigned int type ); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ECC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_error.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_error.h new file mode 100755 index 0000000000000..f4666b396c378 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_error.h @@ -0,0 +1,149 @@ +#ifndef QURT_ERROR_H +#define QURT_ERROR_H + +/** + @file qurt_error.h + Error results- QURT defines a set of standard symbols for the error result values. This file lists the + symbols and their corresponding values. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021-2022 , 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ +#include "qurt_except.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup chapter_error +@{ */ + +/*===================================================================== +Constants and macros +======================================================================*/ +#define QURT_EOK 0 /**< Operation successfully performed. */ +#define QURT_EVAL 1 /**< Wrong values for the parameters. The specified page does not exist. */ +#define QURT_EMEM 2 /**< Not enough memory to perform the operation.*/ + +#define QURT_EINVALID 4 /**< Invalid argument value; invalid key. */ +/** @cond */ +#define QURT_EUNKNOWN 6 /**< Defined but never used in QuRT. */ +#define QURT_ENOMSGS 7 /**< Message queue is empty. */ +#define QURT_EBADF 9 /**< Bad message queue descriptor. */ +/** @endcond */ +#define QURT_EFAILED 12 /**< Operation failed. */ + +#define QURT_ENOTALLOWED 13 /**< Operation not allowed. */ + +/** @cond */ +#define QURT_EDUPCLSID 14 /*< Duplicate class ID. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOREGISTERED 20 /**< No registered interrupts.*/ +/** @endcond */ + + +/** @cond */ +#define QURT_EISDB 21 /*< Power collapse failed due to ISDB being enabled. */ +#define QURT_ESTM 22 /*< Power collapse failed in a Single-threaded mode check. */ +/** @endcond */ + + +/** @cond rest_reg_dist */ +#define QURT_ETLSAVAIL 23 /**< No free TLS key is available. */ +#define QURT_ETLSENTRY 24 /**< TLS key is not already free. */ +/** @endcond */ + +#define QURT_EINT 26 /**< Invalid interrupt number (not registered). */ +/** @cond rest_reg_dist */ +#define QURT_ESIG 27 /**< Invalid signal bitmask (cannot set more than one signal at a time). */ +/** @endcond */ + +/** @cond */ +#define QURT_EHEAP 28 /**< No heap space is available. */ +#define QURT_ENOSPC 28 /**< No space to create another queue in the system. */ +#define QURT_EMEMMAP 29 /**< Physical address layout is not supported by the kernel. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOTHREAD 30 /**< Thread no longer exists. */ +/** @endcond */ +/** @cond */ +#define QURT_EL2CACHE 31 /**< L2cachable is not supported in kernel invalidate/cleaninv. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_EALIGN 32 /**< Not aligned. */ +#define QURT_EDEREGISTERED 33 /**< Interrupt is already deregistered.*/ +/** @endcond */ + +/** @cond internal_only */ + +#define QURT_ETLBCREATESIZE 34 /**< TLB create error -- Incorrect size.*/ +#define QURT_ETLBCREATEUNALIGNED 35 /**< TLB create error -- Unaligned address.*/ +/** @endcond */ +/** @cond rest_reg_dist*/ +#define QURT_EEXISTS 35 /**< File or message queue already exists. */ +#define QURT_ENAMETOOLONG 36 /**< Name too long for message queue creation. */ +#define QURT_EPRIVILEGE 36 /**< Caller does not have privilege for this operation.*/ + +#define QURT_ECANCEL 37 /**< A cancellable request was canceled because the associated process was asked to exit.*/ +/** @endcond */ + +/** @cond */ +#define QURT_EISLANDTRAP 38 /*< Unsupported TRAP is called in Island mode.*/ + +#define QURT_ERMUTEXUNLOCKNONHOLDER 39 /*< Rmutex unlock by a non-holder.*/ +#define QURT_ERMUTEXUNLOCKFATAL 40 /*< Rmutex unlock error, all except the non-holder error.*/ +#define QURT_EMUTEXUNLOCKNONHOLDER 41 /*< Mutex unlock by a non-holder.*/ +#define QURT_EMUTEXUNLOCKFATAL 42 /*< Mutex unlock error, all except the non-holder error.*/ +#define QURT_EINVALIDPOWERCOLLAPSE 43 /*< Invalid power collapse mode requested. */ +/** @endcond */ +#define QURT_EISLANDUSEREXIT 44 /**< User call has resulted in island exit.*/ +#define QURT_ENOISLANDENTRY 45 /**< Island mode had not yet been entered.*/ +#define QURT_EISLANDINVALIDINT 46 /**< Exited Island mode due to an invalid island interrupt.*/ +/** @cond rest_reg_dist */ +#define QURT_ETIMEDOUT 47 /**< Operation timed-out. */ +#define QURT_EALREADY 48 /**< Operation already in progress. */ +/** @endcond */ + +#define QURT_ERETRY 49 /*< Retry the operation. */ +#define QURT_EDISABLED 50 /*< Resource disabled. */ +#define QURT_EDUPLICATE 51 /*< Duplicate resource. */ +#define QURT_EBADR 53 /*< Invalid request descriptor. */ +#define QURT_ETLB 54 /*< Exceeded maximum allowed TLBs. */ +#define QURT_ENOTSUPPORTED 55 /*< Operation not supported. */ +/** @cond rest_reg_dist */ +#define QURT_ENORESOURCE 56 /**< No resource. */ +/** @endcond */ + +#define QURT_EDTINIT 57 /**< Problem with device tree intialization. */ +#define QURT_EBUFLOCK 58 /*< Buffer lock failed because it was already locked many times. */ +#define QURT_ELOCKED 59 /**< Current operation failed as the buffer is locked. */ +#define QURT_EMSGSIZE 90 /*< Message queue msg_len is greater than mq_msgsize attribute of the message queue. */ + + +#define QURT_ENOTCONFIGURED 91 /*< Interrupt is NOT configured. */ + +#define QURT_EBANDWIDTHLIMIT 92 /*< Message queue send exceed the bandwidth limit. */ + +#define QURT_ECFIVIOLATION 93 /*< CFI violation detected. */ + +#define QURT_EDESTROY 94 /**< A destroy request was made to waiting threads.*/ + +#define QURT_EHMXNOTAVAIL 95 /**< HMX is not available to target thread.*/ +#define QURT_EHMXNOTDETACHABLE 96 /**< HMX is not detachable from target thread.*/ + +#define QURT_EFATAL -1 /**< Fatal error. */ + +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ERROR_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_event.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_event.h new file mode 100755 index 0000000000000..987f0fe79f227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_event.h @@ -0,0 +1,452 @@ +#ifndef QURT_EVENT_H +#define QURT_EVENT_H +/** + @file qurt_event.h + @brief Prototypes of kernel event API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "qurt_consts.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System environment object type. + */ +/**@addtogroup sys_env_types +@{ */ +/** QuRT swap pool information type. */ +typedef struct qurt_sysenv_swap_pools { + /** @cond */ + unsigned int spoolsize; /* Swap pool size.*/ + unsigned int spooladdr; /* Swap pool start address.*/ + /** @endcond */ +}qurt_sysenv_swap_pools_t; + +/**QuRT application heap information type. */ +typedef struct qurt_sysenv_app_heap { + /** @cond */ + unsigned int heap_base; /* Heap base address.*/ + unsigned int heap_limit; /* Heap end address.*/ + /** @endcond */ +} qurt_sysenv_app_heap_t ; + +/** QuRT architecture version information type. */ +typedef struct qurt_sysenv_arch_version { + /** @cond */ + unsigned int arch_version; /*Architecture version.*/ + /** @endcond */ +}qurt_arch_version_t; + +/** QuRT maximum hardware threads information type. */ +typedef struct qurt_sysenv_max_hthreads { + /** @cond */ + unsigned int max_hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_max_hthreads_t; + +/** QuRT active hardware threads information type. */ +typedef struct qurt_sysenv_hthreads { + /** @cond */ + unsigned int hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_hthreads_t; + +/** QuRT maximum pi priority information type. */ +typedef struct qurt_sysenv_max_pi_prio { + /** @cond */ + unsigned int max_pi_prio; /*Maximum pi priority.*/ + /** @endcond */ +}qurt_sysenv_max_pi_prio_t; + +/** QuRT process name information type. */ +typedef struct qurt_sysenv_procname { + /** @cond */ + union { + unsigned int asid; /*Address space ID.*/ + unsigned int pid; /*Process ID.*/ + }; + char name[QURT_MAX_NAME_LEN]; /* Process name.*/ + /** @endcond */ +}qurt_sysenv_procname_t; + +/** QuRT stack profile count information type. */ +typedef struct qurt_sysenv_stack_profile_count { + /** @cond */ + unsigned int count; /*Stack profile count for usage.*/ + unsigned int count_watermark; /*Stack profile count for watermark.*/ + /** @endcond */ +}qurt_sysenv_stack_profile_count_t; + +/** + QuRT system error event type. + */ +typedef struct _qurt_sysevent_error_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + } qurt_sysevent_error_t ; + +typedef struct _qurt_sysevent_error_1_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + unsigned int fkey; /**< Framekey.*/ + unsigned int reserved1; /**< Reserved.*/ + unsigned int reserved2; /**< Reserved.*/ + unsigned int reserved3; /**< Reserved.*/ + } qurt_sysevent_error_1_t ; + +/** QuRT page fault error event information type. */ +typedef struct qurt_sysevent_pagefault { + qurt_thread_t thread_id; /**< Thread ID of the page fault thread. */ + unsigned int fault_addr; /**< Accessed address that caused the page fault. */ + unsigned int ssr_cause; /**< SSR cause code for the page fault. */ +} qurt_sysevent_pagefault_t ; +/** @} */ /* @endaddtogroup sys_env_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/*======================================================================*/ +/** + Gets the environment swap pool 0 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool0 (qurt_sysenv_swap_pools_t *pools ); + +/* + Gets the environment swap pool 1 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool1(qurt_sysenv_swap_pools_t *pools ); + +/**@ingroup func_qurt_sysenv_get_app_heap + Gets information on the program heap from the kernel. + + @datatypes + #qurt_sysenv_app_heap_t + + @param[out] aheap Pointer to information on the program heap. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_app_heap(qurt_sysenv_app_heap_t *aheap ); + +/**@ingroup func_qurt_sysenv_get_arch_version + Gets the Hexagon processor architecture version from the kernel. + + @datatypes + #qurt_arch_version_t + + @param[out] vers Pointer to the Hexagon processor architecture version. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter + + @dependencies + None. +*/ +int qurt_sysenv_get_arch_version(qurt_arch_version_t *vers); + +/**@ingroup func_qurt_sysenv_get_max_hw_threads + Gets the maximum number of hardware threads supported in the Hexagon processor. + The API includes the disabled hardware threads to reflect the maximum + hardware thread count. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, only HW0 and HW2 are initialized by QuRT. + HW1 and HW3 are not used at all. Under such a scenario, + qurt_sysenv_get_max_hw_threads() still returns four. + + @datatypes + #qurt_sysenv_max_hthreads_t + + @param[out] mhwt Pointer to the maximum number of hardware threads supported in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_hw_threads(qurt_sysenv_max_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_hw_threads + Gets the number of hardware threads initialized by QuRT in Hexagon processor. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, QuRT only initializes HW0 and HW2. + HW1 and HW3 are not used. In this scenario, qurt_sysenv_get_hw_threads() returns 2. + + @datatypes + #qurt_sysenv_hthreads_t + + @param[out] mhwt Pointer to the number of hardware threads active in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_hw_threads(qurt_sysenv_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_max_pi_prio + Gets the maximum priority inheritance mutex priority from the kernel. + + @datatypes + #qurt_sysenv_max_pi_prio_t + + @param[out] mpip Pointer to the maximum priority inheritance mutex priority. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_pi_prio(qurt_sysenv_max_pi_prio_t *mpip ); + +/**@ingroup func_qurt_sysenv_get_process_name2 + Gets information on the system environment process names based on the client_handle argument. + + @datatypes + #qurt_sysenv_procname_t + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name2(int client_handle, qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_process_name + Gets information on the system environment process names from the kernel. + + @datatypes + #qurt_sysenv_procname_t + + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name(qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_stack_profile_count + Gets information on the stack profile count from the kernel. + + @datatypes + #qurt_sysenv_stack_profile_count_t + + @param[out] count Pointer to information on the stack profile count. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_stack_profile_count(qurt_sysenv_stack_profile_count_t *count ); + +/**@ingroup func_qurt_exception_wait + Registers the program exception handler. + This function assigns the current thread as the QuRT program exception handler and suspends the + thread until a program exception occurs. + + When a program exception occurs, the thread is awakened with error information + assigned to the parameters of this operation. + + @note1hang If no program exception handler is registered, or if the registered handler + calls exit, QuRT raises a kernel exception. + If a thread runs in Supervisor mode, any errors are treated as kernel + exceptions. + + @param[out] ip Pointer to the instruction memory address where the exception occurred. + @param[out] sp Stack pointer. + @param[out] badva Pointer to the virtual data address where the exception occurred. + @param[out] cause Pointer to the QuRT error result code. + + @return + Registry status: \n + Thread identifier -- Handler successfully registered. \n + #QURT_EFATAL -- Registration failed. + + @dependencies + None. +*/ +unsigned int qurt_exception_wait (unsigned int *ip, unsigned int *sp, + unsigned int *badva, unsigned int *cause); + +unsigned int qurt_exception_wait_ext (qurt_sysevent_error_t * sys_err); + +/**@ingroup func_qurt_exception_wait3 + Registers the current thread as the QuRT program exception handler, and suspends the thread until a + program exception occurs. + When a program exception occurs, the thread is awakened with error information assigned to the specified + error event record. + If a program exception is raised when no handler is registered (or when a handler is registered, but it calls + exit), the exception is treated as fatal.\n + @note1hang If a thread runs in Monitor mode, all exceptions are treated as kernel exceptions.\n + @note1cont This function differs from qurt_exception_wait() by returning the error information in a data + structure rather than as individual variables. It also returns additional information (for example, SSR, FP, and LR). + + @param[out] sys_err Pointer to the qurt_sysevent_error_1_t type structure. + @param[in] sys_err_size Size of the qurt_sysevent_error_1_t structure. + + @return + Registry status: \n + - #QURT_EFATAL -- Failure. \n + - Thread ID -- Success. + + @dependencies + None. +*/ + +unsigned int qurt_exception_wait3(void * sys_err, unsigned int sys_err_size); + +/**@ingroup func_qurt_exception_raise_nonfatal + Raises a nonfatal program exception in the QuRT program system. + + For more information on program exceptions, see Section @xref{dox:exception_handling}. + + This operation never returns -- the program exception handler is assumed to perform all + exception handling before terminating or reloading the QuRT program system. + + @note1hang The C library function abort() calls this operation to indicate software + errors. + + @param[in] error QuRT error result code (Section @xref{dox:error_results}). + + @return + Integer -- Unused. + + @dependencies + None. +*/ +int qurt_exception_raise_nonfatal (int error) __attribute__((noreturn)); + + +/**@ingroup func_qurt_exception_raise_fatal + Raises a fatal program exception in the QuRT system. + + Fatal program exceptions terminate the execution of the QuRT system without invoking + the program exception handler. + + For more information on fatal program exceptions, see Section @xref{dox:exception_handling}. + + This operation always returns, so the calling program can perform the necessary shutdown + operations (data logging, on so on). + + @note1hang Context switches do not work after this operation has been called. + + @return + None. + + @dependencies + None. +*/ +void qurt_exception_raise_fatal (void); + +unsigned int qurt_enable_floating_point_exception(unsigned int mask); + +/**@ingroup func_qurt_exception_enable_fp_exceptions + Enables the specified floating point exceptions as QuRT program exceptions. + + The exceptions are enabled by setting the corresponding bits in the Hexagon + control user status register (USR). + + The mask argument specifies a mask value identifying the individual floating + point exceptions to set. The exceptions are represented as defined symbols + that map into bits 0 through 31 of the 32-bit flag value. + Multiple floating point exceptions are specified by OR'ing together the individual + exception symbols.\n + @note1hang This function must be called before performing any floating point operations. + + @param[in] mask Floating point exception types. Values: \n + - #QURT_FP_EXCEPTION_ALL \n + - #QURT_FP_EXCEPTION_INEXACT \n + - #QURT_FP_EXCEPTION_UNDERFLOW \n + - #QURT_FP_EXCEPTION_OVERFLOW \n + - #QURT_FP_EXCEPTION_DIVIDE0 \n + - #QURT_FP_EXCEPTION_INVALID @tablebulletend + + @return + Updated contents of the USR. + + @dependencies + None. +*/ + +static inline unsigned int qurt_exception_enable_fp_exceptions(unsigned int mask) +{ + return qurt_enable_floating_point_exception(mask); +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EVENT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_except.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_except.h new file mode 100755 index 0000000000000..e1684c80e3d50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_except.h @@ -0,0 +1,185 @@ +#ifndef QURT_EXCEPT_H +#define QURT_EXCEPT_H + +/** + @file qurt_except.h + @brief Defines Cause and Cause2 codes for error-handling. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. + + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + QuRT supports error handling to handle CPU detected exceptions and software errors. + QuRT treats all errors as either fatal errors or nonfatal errors. + + @section sec1 Fatal errors + All supervisor mode exceptions are treated as fatal errors. + If a registered exception handler calls qurt_exit(), it is treated as a fatal error. + Fatal errors result in saving the context of primary hardware thread to QURT_error_info and the rest of the thread contexts to the corresponding TCBs. + All hardware threads are eventually stopped and the cache is flushed. + NMI exception is treated little differently from other fatal errors. QuRT saves the contexts of all the hardware threads into QURT_error_info.\n + + @subsection subsection1 Debugging fatal errors + - QURT_error_info.status.status -- Indicates that an error occured. + - QURT_error_info.status.cause -- Cause code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.cause2 -- Cause2 code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.fatal -- Indicates whether a fatal error occurred. A user error can result in a fatal error if the exceptional handler is not registered. + - QURT_error_info.status.hw_tnum -- Indicates the index of QURT_error_info.locregs[], where the context is saved when the error is fatal error. + - QURT_error_info.global_regs -- Contains the values of the global registers of Q6 + - QURT_error_info.local_regs[QURT_error_info.status.hw_tnum] -- Provides the CPU context when the error is a supervisor error. + + + + @subsection subsection2 Debugging nonfatal errors + - QURT_error_info.user_errors -- All user errors are logged here. + - QURT_error_info.user_errors.counter -- Index to last logged error. + - QURT_error_info.user_errors.entry[0...counter] -- Structure for logged error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb -- TCB for the user error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb.error -- Information about the error; Cause, Cause2, Badva and hardware thread ID. + - QURT_error_info.user_errors.entry[0...counter].error_code -- ((cause2 << 8) 'Logical Or' (cause) ); Cause and Cause 2 details are listed below. + - QURT_error_info.user_errors.entry[0...counter].hw_thread -- Hardware thread ID for error. + - QURT_error_info.user_errors.entry[0...counter].pcycle -- Pcycle for error. + +@note + Important usage note: + Cause and Cause2 are error codes to distinguish multiple errors. + SSR and BADAVA are inconclusive without the vector number. + All cause and cause2 can range from 1 to 255 and every cause can have 1 to 255 error code. + Hence the system can have up to 255 * 255 unique error codes. + The cominations is representated as ((cause2 << 8) 'Logical OR' (cause) ) + Some Cause2 codes are statically defined, whereas some are obtaned from SSR[7:0] cause codes. It depends on cause codes. + SSR cause codes are defined in Hexagon reference manual. + All possible combinations are listed below. +*/ +/** @addtogroup chapter_error +@{ */ +/* cause - error type - 8-bits*/ +#define QURT_EXCEPT_PRECISE 0x01U /**< Precise exception occurred. For this cause code, Cause2 is SSR[7:0].*/ +#define QURT_EXCEPT_NMI 0x02U /**< NMI occurred; Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS 0x03U /**< TLBMISS RW occurred; for this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_RSVD_VECTOR 0x04U /**< Interrupt raised on a reserved vector, which must never occur. Cause2 is not defined. */ +#define QURT_EXCEPT_ASSERT 0x05U /**< Kernel assert. Cause2 QURT_ABORT_* are listed below. */ +#define QURT_EXCEPT_BADTRAP 0x06U /**< trap0(num) called with unsupported num. Cause2 is 0. */ +#define QURT_EXCEPT_UNDEF_TRAP1 0x07U /**< Trap1 is not supported. Using Trap1 causes this error. Cause2 is not defined. */ +#define QURT_EXCEPT_EXIT 0x08U /**< Application called qurt_exit() or qurt_exception_raise_nonfatal(). Can be called from C library. Cause2 is "[Argument passed to qurt_exception_raise_nonfatal() & 0xFF]". */ +#define QURT_EXCEPT_TLBMISS_X 0x0AU /**< TLBMISS X (execution) occurred. Cause2 is not defined. */ +#define QURT_EXCEPT_STOPPED 0x0BU /**< Running thread stopped due to fatal error on other hardware thread. Cause2 is not defined. */ +#define QURT_EXCEPT_FATAL_EXIT 0x0CU /**< Application called qurt_fatal_exit(). Cause2 is not defined. */ +#define QURT_EXCEPT_INVALID_INT 0x0DU /**< Kernel received an invalid L1 interrupt. Cause2 is not defined. */ +#define QURT_EXCEPT_FLOATING_POINT 0x0EU /**< Kernel received an floating point error. Cause2 is not defined. */ +#define QURT_EXCEPT_DBG_SINGLE_STEP 0x0FU /**< Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS_RW_ISLAND 0x10U /**< Read write miss in Island mode. Cause2 QURT_TLB_MISS_RW_MEM* are listed below. */ +#define QURT_EXCEPT_TLBMISS_X_ISLAND 0x11U /**< Execute miss in Island mode. For this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_SYNTHETIC_FAULT 0x12U /**< Synthetic fault with user request that kernel detected. Cause2 QURT_SYNTH_* are listed below. */ +#define QURT_EXCEPT_INVALID_ISLAND_TRAP 0x13U /**< Invalid trap in Island mode. Cause2 is trap number. */ +#define QURT_EXCEPT_UNDEF_TRAP0 0x14U /**< trap0(num) was called with unsupported num. Cause2 is trap number. */ +#define QURT_EXCEPT_PRECISE_DMA_ERROR 0x28U /**< Precise DMA error. Cause2 is DM4[15:8]. Badva is DM5 register. */ + +#define QURT_ECODE_UPPER_LIBC (0U << 16) /**< Upper 16 bits is 0 for libc. */ +#define QURT_ECODE_UPPER_QURT (0U << 16) /**< Upper 16 bits is 0 for QuRT. */ +#define QURT_ECODE_UPPER_ERR_SERVICES (2U << 16) /**< Upper 16 bits is 2 for error service. */ +/** @cond */ +#define QURT_ECODE_ISLAND_INVALID_QDI 3U /**< Passing invalid QDI method in island. */ +/** @endcond */ + +/* Cause2 for QURT_EXCEPT_SYNTHETIC_FAULT cause- 8bits */ +#define QURT_SYNTH_ERR 0x01U /**< */ +#define QURT_SYNTH_INVALID_OP 0x02U /**< */ +#define QURT_SYNTH_DATA_ALIGNMENT_FAULT 0x03U /**< */ +#define QURT_SYNTH_FUTEX_INUSE 0x04U /**< */ +#define QURT_SYNTH_FUTEX_BOGUS 0x05U /**< */ +#define QURT_SYNTH_FUTEX_ISLAND 0x06U /**< */ +#define QURT_SYNTH_FUTEX_DESTROYED 0x07U /**< */ +#define QURT_SYNTH_PRIVILEGE_ERR 0x08U /**< */ + +/* Cause2 - Abort cause reason - 8 bits */ +/* ERR_ASSERT cause */ +#define QURT_ABORT_FUTEX_WAKE_MULTIPLE 0x01U /**< Abort cause - futex wake multiple. */ +#define QURT_ABORT_WAIT_WAKEUP_SINGLE_MODE 0x02U /**< Abort cause - thread waiting to wake up in Single Threaded mode. */ +#define QURT_ABORT_TCXO_SHUTDOWN_NOEXIT 0x03U /**< Abort cause - call TCXO shutdown without exit. */ +#define QURT_ABORT_FUTEX_ALLOC_QUEUE_FAIL 0x04U /**< Abort cause - futex allocation queue failure - QURTK_futexhash_lifo empty. */ +#define QURT_ABORT_INVALID_CALL_QURTK_WARM_INIT 0x05U /**< Abort cause - invalid call QURTK_warm_init() in NONE CONFIG_POWER_MGMT mode. */ +#define QURT_ABORT_THREAD_SCHEDULE_SANITY 0x06U /**< Abort cause - sanity schedule thread is not supposed to run on the current hardware thread. */ +#define QURT_ABORT_REMAP 0x07U /**< Remap in the page table; the correct behavior must remove mapping if necessary. */ +#define QURT_ABORT_NOMAP 0x08U /**< No mapping in page table when removing a user mapping. */ +#define QURT_ABORT_OUT_OF_SPACES 0x09U +#define QURT_ABORT_INVALID_MEM_MAPPING_TYPE 0x0AU /**< Invalid memory mapping type when creating qmemory. */ +#define QURT_ABORT_NOPOOL 0x0BU /**< No pool available to attach. */ +#define QURT_ABORT_LIFO_REMOVE_NON_EXIST_ITEM 0x0CU /**< Cannot allocate more futex waiting queue. */ +#define QURT_ABORT_ARG_ERROR 0x0DU +#define QURT_ABORT_ASSERT 0x0EU /**< Assert abort. */ +#define QURT_ABORT_FATAL 0x0FU /**< Fatal error; must never occur. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_QUEUE 0x10U /**< Abort cause - invalid queue ID in futex resume. */ +#define QURT_ABORT_FUTEX_WAIT_INVALID_QUEUE 0x11U /**< Abort cause - invalid queue ID in futex wait. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_FUTEX 0x12U /**< Abort cause - invalid futex object in hashtable. */ +#define QURT_ABORT_NO_ERHNDLR 0x13U /**< No registered error handler. */ +#define QURT_ABORT_ERR_REAPER 0x14U /**< Exception in the reaper thread. */ +#define QURT_ABORT_FREEZE_UNKNOWN_CAUSE 0x15U /**< Abort in thread freeze operation. */ +#define QURT_ABORT_FUTEX_WAIT_WRITE_FAILURE 0x16U /**< During futex wait processing, could not perform a necessary write operation to userland data; most likely due to a DLPager eviction. */ +#define QURT_ABORT_ERR_ISLAND_EXP_HANDLER 0x17U /**< Exception in Island exception handler task. */ +#define QURT_ABORT_L2_TAG_DATA_CHECK_FAIL 0x18U /**< Detected error in L2 tag/data during warm boot. The L2 tag/data check is done when CONFIG_DEBUG_L2_POWER_COLLAPSE is enabled. */ +#define QURT_ABORT_ERR_SECURE_PROCESS 0x19U /**< Abort error in secure process. */ +#define QURT_ABORT_ERR_EXP_HANDLER 0x20U /**< No exception handler, or the handler caused an exception. */ +#define QURT_ABORT_ERR_NO_PCB 0x21U /**< PCB of the thread context failed initialization, PCB was NULL. */ +#define QURT_ABORT_NO_PHYS_ADDR 0x22U /**< Unable to find the physical address for the virtual address. */ +#define QURT_ABORT_OUT_OF_FASTINT_CONTEXTS 0x23U /**< Fast interrupt contexts exhausted. */ +#define QURT_ABORT_CLADE_ERR 0x24U /**< Fatal error seen with CLADE interrupt. */ +#define QURT_ABORT_ETM_ERR 0x25U /**< Fatal error seen with ETM interrupt. */ +#define QURT_ABORT_ECC_DED_ASSERT 0x26U /**< ECC two-bit DED error. */ +#define QURT_ABORT_VTLB_ERR 0x27U /**< Fatal error in the VTLB layer. */ +#define QURT_ABORT_TLB_ENCODE_DECODE_FAILURE 0x28U /**< Failure during the TLB encode or decode operation. */ +#define QURT_ABORT_VTLB_WALKOBJS_BOUND_FAILURE 0x29U /**< Failure to lookup entry in the page table. */ +#define QURT_ABORT_PHY_MEMORY_OWNERSHIP_FAILURE 0x30U /**< Failure to claim phy memory ownership. */ +#define QURT_ABORT_JTLB_SIZE_CHECK_FAIL 0x31U /**< JTLB size configured is more than actual size in hardware */ +#define QURT_ABORT_AUTOSTACK_ASSERT 0x32U /**< Error while handling stack flimit exception. */ + +/* Cause2 - TLB-miss_X - 8bits */ +#define QURT_TLB_MISS_X_FETCH_PC_PAGE 0x60U /**< */ +#define QURT_TLB_MISS_X_2ND_PAGE 0x61U /**< */ +#define QURT_TLB_MISS_X_ICINVA 0x62U /**< */ + +/* Cause2 - TLB-miss_RW - 8bits */ +#define QURT_TLB_MISS_RW_MEM_READ 0x70U /**< */ +#define QURT_TLB_MISS_RW_MEM_WRITE 0x71U /**< */ + +/** @cond rest_reg_dist */ +/* Cause2 - Floating point exception - 8 bits */ +#define QURT_FLOATING_POINT_EXEC_ERR 0xBFU /**< Execute floating-point. */ +/** @endcond */ + +/** Cause2 - autostackv2 - 8 bits */ +#define QURT_AUTOSTACKV2_CANARY_NOT_MATCH 0xC1U +#define QURT_AUTOSTACKV2_POOL_IDX_OFF_RANGE 0xC2U + +/** Cause2 - CFI violation - 8 bits */ +#define QURT_CFI_VIOLATION 0xC3U + +/** @cond rest_reg_dist*/ +/* Enable floating point exceptions */ +#define QURT_FP_EXCEPTION_ALL 0x1FU << 25 /**< */ +#define QURT_FP_EXCEPTION_INEXACT 0x1U << 29 /**< */ +#define QURT_FP_EXCEPTION_UNDERFLOW 0x1U << 28 /**< */ +#define QURT_FP_EXCEPTION_OVERFLOW 0x1U << 27 /**< */ +#define QURT_FP_EXCEPTION_DIVIDE0 0x1U << 26 /**< */ +#define QURT_FP_EXCEPTION_INVALID 0x1U << 25 /**< */ + +/** @endcond */ +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EXCEPT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fastint.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fastint.h new file mode 100755 index 0000000000000..ea65dc0917fc0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fastint.h @@ -0,0 +1,71 @@ +#ifndef QURT_FASTINT_H +#define QURT_FASTINT_H + +/** + @file qurt_fastint.h + @brief QuRT fast interrupt functions + + Copyright (c) 2013-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_fastint_register + Register fast interrupt callback function + + Fast interrupt callback should be designed to perform the minimal necessary + actions for the interrupt, and/or perform some operations, such as signaling + another regular software thread to start any additional processing. + The callback should be a fast and short function. When a fast interrupt callback + is running, the corresponding interrupt cannot be re-enabled until the callback + returns. + + The fast interrupt callback must not use any system blocking calls, such as + mutex lock or signal wait. Otherwise, it results in errors. + + The fast interrupt callback function has a single integer argument and the + function ends with no return. The argument value passed in is the interrupt + number, and therefore a single callback function can handle + multiple fast interrupts. + + @param[in] intno Interrupt number to register. + @param[in] fn Interrupt callback function. + + @return + #QURT_EOK -- Fast interrupt registration is successful. \n + #QURT_EINVALID -- Interrupt is already registered. \n + #QURT_EINT -- Invalid interrupt number. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_register(int intno, void (*fn)(int)); + + +/*======================================================================*/ +/**@ingroup func_qurt_fastint_deregister + Deregisters the fast interrupt callback function. + + @param[in] intno Level-one interrupt number to deregister. Valid range is 1 and 10 through 31 + (simulator only). + + @return + #QURT_EOK -- Interrupt deregistration is successful. \n + #QURT_EINT -- Invalid interrupt number (not registered). \n + #QURT_EINVALID -- Invalid interrupt number (already deregistered). + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_deregister(int intno); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FASTINT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fs_hub.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fs_hub.h new file mode 100755 index 0000000000000..aaa050a6c838b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_fs_hub.h @@ -0,0 +1,58 @@ +#ifndef QURT_FS_HUB_H +#define QURT_FS_HUB_H + +/** + @file qurt_fs_hub.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver that provides file-system functionality. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + This structure tracks a file-designator for a FS-hub QDI driver. + File system's QDI interface should use this object to encapsulate + true file-descriptor and return back a QDI handle. This QDI handle + will be used as file-descriptor by File-systm-hub. + */ + +typedef struct qurt_qdi_fs_obj +{ + qurt_qdi_obj_t qdi_obj; + int client_handle; + int fd; +}qurt_qdi_fs_obj_t; + + +/**@ingroup fs_hub_support_functions + This function allows a file-system to register it's QDI interface with file-system-hub. + Once registered, all file open operations for any filenames containing the mountpoint will + be forwarded to the QDI inteface. + + Mountpoint string must be encased in two forward slashes e.g. "/mountpoint/" + + @param mtpoint mount point for the file-system being registered. + @param opener opener structure for the QDI driver interface + + @return + QURT_EOK -- Successfully registered QDI driver with file-system-hub. + Negative error code -- Failed to register with file-system-hub + */ +int qurt_fs_hub_mtpoint_register(const char *mtpoint, qurt_qdi_obj_t *opener); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_futex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_futex.h new file mode 100755 index 0000000000000..1fdcc79a43f01 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_futex.h @@ -0,0 +1,82 @@ +#ifndef QURT_FUTEX_H +#define QURT_FUTEX_H +/** + @file qurt_futex.h + + @brief Prototypes of QuRT futex API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Functions +======================================================================*/ + + +/**@ingroup func_qurt_futex_wait + Moves the caller thread into waiting state when a memory object address + contains a value that is the same as a specified value. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait(void *lock, int val); + + +/**@ingroup func_qurt_futex_wait_cancellable + If a memory object address contains a value that is same as a specified + value, move the caller thread into waiting state. + The kernal can cancel the waiting state when there is a special need. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait_cancellable(void *lock, int val); + + +/**@ingroup func_qurt_futex_wake + Wakes up a specified number of threads that have been waiting + for the object change with qurt_futex_wait(). + + @param[in] lock Pointer to the object memory. + @param[in] n_to_wake Maximum number of threads to wake up. + + @return + number of threads to be woken up by this function + + @dependencies + None. + */ +int qurt_futex_wake(void *lock, int n_to_wake); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hmx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hmx.h new file mode 100755 index 0000000000000..e4037dbeae514 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hmx.h @@ -0,0 +1,226 @@ +#ifndef QURT_HMX_H +#define QURT_HMX_H +/** + @file qurt_hmx.h + @brief Prototypes of Qurt HMX API. + +Copyright (c) 2019-2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + + +/** @addtogroup hmx_types +@{ */ +/* HMX locking type */ +#define QURT_HMX_NON_SHARED_LOCK 0U /**< HMX locking type.*/ +#define QURT_HMX_SHARED_LOCK 1U /**< HMX locking type.*/ + +/* HMX unlocking type */ +#define QURT_HMX_NON_SHARED_UNLOCK 0U /**< HMX unlocking type.*/ +#define QURT_HMX_SHARED_UNLOCK 1U /**< HMX unlocking type.*/ + +/* HMX hardware context */ +#define QURT_HMX_UNIT_0 0U /**< HMX hardware context #0 */ +#define QURT_HMX_UNIT_1 1U /**< HMX hardware context #1 */ + /** @} */ /* end_addtogroup hmx_types */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_hmx_lock2 + Locks a HMX unit with the specified locking type. + + #QURT_HMX_NON_SHARED_LOCK: + - If a HMX unit is available, lock the unit and return success of #QURT_EOK. + - If the HMX unit is already locked by another thread, the caller thread is suspended + until the HMX is available and gets locked by this function. + - If there is no HMX hardware supported, returns #QURT_EVAL; + + #QURT_HMX_SHARED_LOCK: + - If a HMX unit is available, enables HMX access for the caller thread, and returns + success of #QURT_EOK. + - If the HMX is enabled on the caller thread, return #QURT_EFAILED. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_SHARED_LOCK, enable HMX access for the caller + thread, and return success of #QURT_EOK. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_NON_SHARED_LOCK, return #QURT_EFAILED. + - If the HMX is locked by a thread from another user process different from the + user process of the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX lock successful.\n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_lock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_unlock2 + Unlocks a HMX unit with the unlocking type. + + #QURT_HMX_NON_SHARED_UNLOCK: + - If there is a HMX unit locked by the caller thread, unlock the HMX unit and clear the + HMX accumulators (assuming a fixed point type). + - If there is no HMX unit locked by the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + #QURT_HMX_SHARED_UNLOCK: + - If the caller thread has locked HMX with type #QURT_HMX_SHARED_LOCK, disable the + HMX access on the caller thread, and return success of #QURT_EOK. + Note: If the caller thread is the last thread that unlocks for #QURT_HMX_SHARED_LOCK + in its user process, the unlock function clears the HMX accumulators. + - If the caller thread has locked HMX with type #QURT_HMX_NON_SHARED_LOCK, return + failure of #QURT_EFAILED. + - If the caller thread has not locked HMX, return failure of #QURT_EFAILED. + - If there is no HMX hardware supported, returns #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX is unlocked successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_unlock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_lock + Locks a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away. + If there is no HMX unit available, the caller is blocked until a HMX is available + and is locked by the function. + + @return + #QURT_EOK -- HMX lock successful. \n + #QURT_EFAILED -- Failure due to wrong locking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_lock(void); + + +/**@ingroup func_qurt_hmx_unlock + Unlocks a HMX unit. + If a HMX unit is locked by the caller thread, unlock the HMX unit and clear its + accumulators(assuming fixed point type). + If there is no HMX unit locked by the caller thread, return failure. + + @return + #QURT_EOK -- HMX unlock successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_unlock(void); + + +/**@ingroup func_qurt_hmx_try_lock + Tries to lock a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away; + if there is no HMX unit available, the function returns failure without blocking the caller. + + @return + #QURT_EOK -- HMX lock successful \n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_try_lock(void); + + +/**@ingroup func_qurt_hmx_assign + Assign a HMX unit to a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + If the requested hmx_unit is already assigned to another thread with QURT_HMX_NON_SHARED_LOCK, + kernel will detach it from the thread, and re-assign it to the target thread. + If the target thread has HVX enabled, it cannot have HMX enabled. + + Locking type + #QURT_HMX_NON_SHARED_LOCK: + - If the HMX unit is available, lock the HMX unit and return success of #QURT_EOK. + - If the HMX unit is already enabled on the target thread, return #QURT_EOK. + - If the HMX unit is already locked by another thread, detach the HMX from the thread. + Re-assign the HMX unit to the target thread, and return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] type Locking type + #QURT_HMX_NON_SHARED_LOCK -- non-shared lock + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is assigned successfully. This includes the case that \n + the target thread already has HMX assigned. \n + #QURT_EFAILED -- Failure due to wrong assigning conditions. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_assign ( unsigned int thread_id, unsigned int type, unsigned int hmx_unit ); + + +/**@ingroup func_qurt_hmx_release + Release a HMX unit from a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + + Qurt detaches the specified HMX unit from the target thread, and return success of + #QURT_EOK. If the HMX unit is already released from the target thread, return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is released successfully. This includes the case that \n + the target thread already has the HMX released. \n + #QURT_EFAILED -- Failure due to wrong assigning condition. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_release ( unsigned int thread_id, unsigned int hmx_unit ); + + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HMX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hvx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hvx.h new file mode 100755 index 0000000000000..13c213d49ac84 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_hvx.h @@ -0,0 +1,421 @@ +#ifndef QURT_HVX_H +#define QURT_HVX_H +/** + @file qurt_hvx.h + @brief Prototypes of QuRT HVX API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @cond */ + +typedef enum { + QURT_HVX_MODE_64B = 0, /**< HVX mode of 64 bytes */ + QURT_HVX_MODE_128B = 1 /**< HVX mode of 128 bytes */ +} qurt_hvx_mode_t; +/** @endcond */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @cond internal_only*/ +/** @addtogroup hvx_macros +@{ */ +#define QURT_HVX_HW_UNITS_2X128B_4X64B 0x00000204 /**< Bits 15 through 8 are for the number of 128B units. */ + /**< Bits 7 through 0 are for the number of 64B units. */ +#define QURT_HVX_HW_UNITS_4X128B_0X64B 0x00000400 +#define QURT_HVX_HW_UNITS_6X128B_0X64B 0x00000600 + +/* HVX locking status */ + +#define QURT_HVX_UNLOCKED (0) /* Has not locked HVX unit */ +#define QURT_HVX_LOCKED (1) /* Has locked HVX unit */ +#define QURT_HVX_ERROR (-1) /* Error, no HVX support */ + +/* Input value for HVX reservation */ + +#define QURT_HVX_RESERVE_ALL (4) /* All the HVX units in terms of 64B_MODE are requested to be reserved */ +#define QURT_HVX_RESERVE_ALL_AVAILABLE (0xff) /* All remaining unlocked HVX units in terms of 64B_MODE are requested to be reserved */ + +/* Return values for HVX reservation */ + +#define QURT_HVX_RESERVE_NOT_SUPPORTED (-1) /* There is no HVX hardware, or less units in the hardware than requested */ +#define QURT_HVX_RESERVE_NOT_SUCCESSFUL (-2) /* Some HVX units are already locked/reserved by other PD, thus not enough units left for the reservation. */ +#define QURT_HVX_RESERVE_ALREADY_MADE (-3) /* There is already a HVX reservation made. */ +#define QURT_HVX_RESERVE_CANCEL_ERR (-4) /* The action of cancling the reservation fails because this protection domain has no reservation made before. */ + +// HVX set requests + +#define QURT_HVX_64B 0 /**< */ +#define QURT_HVX_128B 1 /**< */ +#define QURT_HVX_NO_USE 2 /**< */ +#define QURT_HVX_RELEASE_CONTEXT 3 /**< */ +#define QURT_HVX_IMMEDIATE_USE 4 /**< */ + +// HVX set masks + +#define QURT_HVX_64B_PREFERRED (1<<(QURT_HVX_64B + 8))/**< */ +#define QURT_HVX_128B_PREFERRED (1<<(QURT_HVX_128B + 8))/**< */ +#define QURT_HVX_64B_ACCEPTABLE (1<<(QURT_HVX_64B + 12))/**< */ +#define QURT_HVX_128B_ACCEPTABLE (1<<(QURT_HVX_128B + 12))/**< */ + +// HVX set return "result" + +#define QURT_EOK 0 /**< */ +#define QURT_HVX_SET_ERROR 0xFF /**< */ + +// hvx_mode_assigned for QURT_HVX_IMMEDIATE_USE +#define QURT_HVX_64B_ASSIGNED (1<<(QURT_HVX_64B + 8)) /**< */ +#define QURT_HVX_128B_ASSIGNED (1<<(QURT_HVX_128B + 8)) /**< */ + +// Sizes of HVX dump buffer + +#define QURT_HVX_V65_64B_VSIZE 2084U /**< 64 x 32 + 8 x 4 + 4 (version). */ +#define QURT_HVX_V65_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V66_128B_VSIZE 4420U /**< 128 x (32 +2) + 16 x 4 + 4 (version). */ +#define QURT_HVX_V68_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V79_128B_VSIZE 4740U /**< 128 x (32+4+1) + 4 (version). */ +#define QURT_HVX_VREG_BUF_SIZE QURT_HVX_V79_128B_VSIZE /**< */ + +// HVX dump versions + +#define QURT_HVX_DUMP_V65_64B 1U /**< */ +#define QURT_HVX_DUMP_V65_128B 2U /**< */ +#define QURT_HVX_DUMP_V66_128B 3U /**< */ +#define QURT_HVX_DUMP_V68_128B 4U /**< */ +#define QURT_HVX_DUMP_V79_128B 5U /**< */ +/** @} */ /* end_addtogroup hvx_macros */ +/** @endcond */ +/** @cond */ +// Qurt data struct for hvx_set input +typedef struct qurt_hvx_set_struct_ { + unsigned char set_req; // LSB + struct { + unsigned char preferred_mask:4; + unsigned char acceptable_mask:4; + }; + unsigned short resvd; // MSB +} qurt_hvx_set_struct_t; // 4 bytes + + +// Qurt data struct for hvx_set return +typedef struct qurt_hvx_set_return_str_ { + unsigned char result; // LSB + unsigned char hvx_mode_assigned; + unsigned short resvd; // MSB +} qurt_hvx_set_return_struct_t; // 4 bytes +/** @endcond */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_hvx_lock + Locks one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns right away. + If the current HVX mode is different from the requested mode, the current + thread is blocked. When all HVX units become idle, QuRT changes + the mode, locks the HVX unit, and returns. + + Starting from Q6v65 with HVX context switch support, qurt_hvx_lock() is + mapped as qurt_hvx_set(64_BYTE or 128_BYTE). + + @datatypes + #qurt_mode_t + + @param[in] lock_mode #QURT_HVX_MODE_64B or #QURT_HVX_MODE_128B. + + @return + #QURT_EOK -- Success \n + Other value -- Failure + + @dependencies + None. + + */ +int qurt_hvx_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_unlock + Unlocks the HVX unit held by this software thread. + + @note1hang Starting from Q6v65 with HVX context switch support, qurt_hvx_unlock() + maps as qurt_hvx_set(QURT_HVX_RELEASE_CONTEXT). + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_unlock(void); + +/**@ingroup func_qurt_hvx_try_lock + Tries to lock one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns #QURT_EOK; Otherwise, + the function returns a failure, but does not block the current software + thread to wait for the HVX unit. + Starting from Q6v65 with HVX context switch support, qurt_hvx_try_lock() + maps to qurt_hvx_set(FOR_IMMEDIATE_USE| preferred_mask | acceptable_mask); + + @datatypes + #qurt_mode_t + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_try_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_get_mode + Gets the current HVX mode configured by QuRT. + + @note1hang Returns #QURT_HVX_MODE_128B or #QURT_HVX_MODE_64B, based on + the current HVX configuration. + + @param[out] + None. + + @return + #QURT_HVX_MODE_128B \n + #QURT_HVX_MODE_64B \n + -1 -- Not available. + + @dependencies + None. + */ +int qurt_hvx_get_mode(void); + + +/**@ingroup func_qurt_hvx_get_units + Gets the HVX hardware configuration that the chipset supports. + + @note1hang The function returns the HVX hardware configuration supported by the chipset. + + @return + Bitmask of the units: 1X64, 2X64, 4X64, 1X128, 2X128, and so on.\n + - QURT_HVX_HW_UNITS_2X126B_4X64B -- V60, V62, or V65 HVX \n + - QURT_HVX_HW_UNITS_4X128B_0X64B -- V66 CDSP or newer \n + - 0 -- not available + + @dependencies + None. + + */ +int qurt_hvx_get_units(void); + + +/**@ingroup func_qurt_hvx_reserve + Reserves HVX units in terms of 64-byte mode for the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + If one HVX unit is already locked by the application in the same PD, the unit is + added to the returned count as one reserved unit for the PD. + Starting from Q6v65 with HVX context switch support, qurt_hvx_reserve() + only does basic sanity checks on HVX units. + + @datatypes + None. + + @param[in] num_units Number of HVX units in terms of 64B_MODE to reserve for the PD. + QURT_HVX_RESERVE_ALL to reserve all the HVX units. + QURT_HVX_RESERVE_ALL_AVAILABLE to reserve the remaining unlocked units. + + @return + Number of units successfully reserved, including the units already locked in the same PD. \n + #QURT_HVX_RESERVE_NOT_SUPPORTED \n + #QURT_HVX_RESERVE_NOT_SUCCESSFUL \n + #QURT_HVX_RESERVE_ALREADY_MADE + + + @dependencies + None. + + */ +int qurt_hvx_reserve(int num_units); + + +/**@ingroup func_qurt_hvx_cancel_reserve + Cancels the HVX reservation in the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + + @return + 0 -- Success \n + #QURT_HVX_RESERVE_CANCEL_ERR -- Failure + + @dependencies + None. + + */ +int qurt_hvx_cancel_reserve(void); + + +/**@ingroup func_qurt_hvx_get_lock_val + Gets the HVX locking status value of the thread of the caller. + + @note1hang Returns the status of whether the thread of the caller already locks a HVX unit or not. + + @datatypes + None. + + @return + #QURT_HVX_UNLOCKED \n + #QURT_HVX_LOCKED \n + #QURT_HVX_ERROR + + @dependencies + None. + */ +int qurt_hvx_get_lock_val(void); + +/** @cond internal_only*/ +/**@ingroup func_qurt_hvx_set + Sets the HVX configuration for the software thread of the caller. + + @datatypes + None. + + @param[in] input_arg Composed of set_request | hvx_preferred_mode_mask + | hvx_acceptable_mode_mask where set_request can be set to: \n + - #QURT_HVX_64B \n + - #QURT_HVX_128B \n + - #QURT_HVX_NO_USE \n + - #QURT_HVX_RELEASE_CONTEXT \n + - #QURT_HVX_IMMEDIATE_USE \n + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_preferred_mode_mask can be set to: \n + - #QURT_HVX_64B_PREFERRED \n + - #QURT_HVX_128B_PREFERRED + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_acceptable_mode_mask can be set to: \n + - #QURT_HVX_64B_ACCEPTABLE \n + - #QURT_HVX_128B_ACCEPTABLE @tablebulletend + + @return + Result of the HVX setting in the least significant 8 bits of the returned data. \n + #QURT_EOK -- 0 \n + #QURT_HVX_SET_ERROR -- 0xFF \n + When #QURT_HVX_IMMEDIATE_USE has a result of #QURT_EOK, + bit 8 to bit 15 of the returned data contain hvx_mode_assigned:\n + - #QURT_HVX_64B_ASSIGNED \n + - #QURT_HVX_128B_ASSIGNED + + @dependencies + None. + */ +unsigned int qurt_hvx_set(unsigned int input_arg); + + +/**@ingroup func_qurt_system_hvx_regs_get_maxsize + Returns the maximum buffer size for saving HVX registers. + + @datatypes + None. + + @return + 0 -- No HVX supported in the target. \n + #QURT_HVX_VREG_BUF_SIZE -- Maximum buffer size for saving HVX registers. + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get_maxsize(void); + + +/**@ingroup func_qurt_system_hvx_regs_get_size + Returns the buffer size for saving HVX registers for a specified thread. + + @param[in] thread_id Thread ID of the target thread. + + @return + 0 -- No HVX assgined to the thread. \n + size -- Size of the buffer in bytes for saving HVX registers for the specified thread: \n + - #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + - #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + - #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + + @dependencies + None. + + */ +unsigned int qurt_system_hvx_regs_get_size(unsigned int thread_id); + + + +/**@ingroup func_qurt_system_hvx_regs_get + Saves the HVX registers into the specified buffer. + Returns the size of the data saved into the buffer. + After calling this function for the first time on a specified thread_id, the QuRT kernel removes the internal HVX saving buffer + from the specified thread. When calling the function on the same thread_id for the second time, this function returns 0. + + @param[in] thread_id Thread ID of the target thread. + @param[in] pBuf Pointer to the buffer for HVX register saving. + The first four bytes of the buffer are for saving the HVX version. HVX registers are saved from + the fifth byte of the buffer. The address of the fifth byte should be 256 bytes aligned. + For example, a buffer can be declared at first as: \n + unsigned char vbuf[QURT_HVX_VREG_BUF_SIZE+256];\n + unsigned char *pBuf; \n + then align the buffer pointer to: \n + pBuf = vbuf; \n + pBuf += (256 - 4 - (unsigned)pBuf%256); + @param[in] size Size of the buffer provided, which is pointed by *pBuf. The buffer size should not be smaller than that + returned from qurt_system_hvx_regs_get_size(), and pBuf should be aligned as described above. + @param[out] pBuf Buffer returned with the saved HVx registers (unsigned char hvx_regs[];), which are saved from the fith + byte of the buffer, and the HVX version (unsigned int hvx_version;), which in the first four bytes + contain one of the HVX dump versions:\n + - #QURT_HVX_DUMP_V65_64B \n + - #QURT_HVX_DUMP_V65_128B \n + - #QURT_HVX_DUMP_V66_128B \n + - #QURT_HVX_DUMP_V68_128B \n + - #QURT_HVX_DUMP_V79_128B \n + @tablebulletend + + @return + Total bytes of the data saved in the provided buffer. \n + 0 -- No HVX assigned to the thread \n + #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get(unsigned int thread_id, void *pBuf, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HVX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_int.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_int.h new file mode 100755 index 0000000000000..386aeda1051eb --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_int.h @@ -0,0 +1,509 @@ +#ifndef QURT_INT_H +#define QURT_INT_H +/** + @file qurt_int.h + @brief QuRT interrupt functions. + + + + Copyright (c) 2013-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/** @cond rest_reg_dist */ +/** @addtogroup interrupts_constants +@{ */ +#define SIG_INT_ABORT 0x80000000 /**< */ +#define QURT_INT_NON_DELAYED_ACK 0 +#define QURT_INT_DELAYED_ACK 1 +#define QURT_INT_ACK_DEFAULT QURT_INT_NON_DELAYED_ACK +#define QURT_INT_DRV_DEFAULT 0 +#define QURT_INT_PRIORITY_DEFAULT 0xFF + +/** QuRT interrupt property. */ +#define QURT_INT_CONFIGID_POLARITY 0x1U /**< */ +#define QURT_INT_CONFIGID_LOCK 0x2U /**< */ + +/** QuRT interrupt lock.*/ +#define QURT_INT_LOCK_DEFAULT 0x0 /**< Default. */ +#define QURT_INT_LOCK_DISABLE 0x0 /**< Interrupt can be enabled or disabled or deregistered. */ +#define QURT_INT_LOCK_ENABLE 0x1 /**< Interrupt is locked and cannot be enabled, disabled, or deregistered.*/ +/** @} */ /* end_addtogroup interrupts_constants */ + +/** @addtogroup Qurt_interrupt_type +@{ */ +/** Trigger type bit fields for a PDC interrupt:\n + @verbatim + Polarity Edge Output\n + 0 00 Level sensitive active low + 0 01 Rising edge sensitive + 0 10 Falling edge sensitive + 0 11 Dual edge sensitive + 1 00 Level sensitive active high + 1 01 Falling edge sensitive + 1 10 Rising edge sensitive + 1 11 Dual edge sensitive + @endverbatim +*/ +#define QURT_INT_TRIGGER_TYPE_SET(pol, edge) ((((pol) & 0x01U) << 2) | ((edge) & 0x03U)) /**< */ + +#define QURT_INT_TRIGGER_LEVEL_LOW QURT_INT_TRIGGER_TYPE_SET(0U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_LEVEL_HIGH QURT_INT_TRIGGER_TYPE_SET(1U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_RISING_EDGE QURT_INT_TRIGGER_TYPE_SET(1U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_FALLING_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_DUAL_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x03U) /**< */ +#define QURT_INT_TRIGGER_USE_DEFAULT 0xffU /**< */ +/** @} */ /* end_addtogroup Qurt_interrupt_type */ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_interrupt_register + @xreflabel{sec:interrupt_register} + Registers the interrupt.\n + Enables the specified interrupt and associates it with the specified QuRT signal object and + signal mask. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register(int int_num, qurt_anysignal_t *int_signal, int signal_mask); + +/**@ingroup func_qurt_interrupt_register2 + @xreflabel{sec:interrupt_register2} + Registers the interrupt.\n + Enables the specified interrupt, associates it with the specified QuRT signal object and + signal mask, and sets interrupt flags. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals that the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value #QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value #QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + #QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + @param[in] flags Defines interrupt property, supported property is interrupt lock enable/disable. + Possible values for flags: \n + - #QURT_INT_LOCK_ENABLE + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register2(int int_num, qurt_anysignal_t *int_signal, int signal_mask, unsigned int flags); +/* + * Waits for registered interrupt signal + + * Suspend the current thread until one of its registered interrupts occurs. The second input mask, + * contains the interrupt signals the IST expects to receive. The interrupt signals are registered + * with interrupts via qurt_register_interrupt API. + * + * The signals returned in the signal variable indicate which interrupts occurred. Use function + * qurt_anysignal_get to read the signals. IST must locally maintain a table that maps a signal to + * a specific interrupt. IST also checks if signal #SIG_INT_ABORT is received. If so, the IST + * must quit from interrupt receiving loop. + * + * For detail information on this API, see QuRT User Manual Section 4.2.5 + * + * Prototype + * + * unsigned int qurt_anysignal_wait(qurt_anysignal_t *int_signal, unsigned int mask) + */ + +/**@ingroup func_qurt_interrupt_acknowledge + Acknowledges an interrupt after it has been processed.\n + Re-enables an interrupt and clears its pending status. This is done after an interrupt is + processed by an IST. + + Interrupts are automatically disabled after they occur. To re-enable an interrupt, an IST + performs the acknowledge operation after it has finished processing the interrupt and + just before suspending itself (such as by waiting on the interrupt signal). + + @note1hang To prevent losing or reprocessing subsequent occurrences of the interrupt, + an IST must clear the interrupt signal (Section @xref{sec:anysignal_clear}) before + acknowledging the interrupt. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Interrupt acknowledge was successful. \n + #QURT_EDEREGISTERED -- Interrupt is already de-registered. + + @dependencies + None. +*/ +int qurt_interrupt_acknowledge(int int_num); + +/**@ingroup func_qurt_interrupt_deregister + Disables the specified interrupt and disassociates it from a QuRT signal object. + If the specified interrupt was never registered (Section @xref{sec:interrupt_register}), the deregister operation + returns the status value #QURT_EINT. + + @note1hang If an interrupt is deregistered while an IST waits + to receive it, the IST might wait indefinitely for the interrupt to occur. To avoid + this problem, the QuRT kernel sends the signal #SIG_INT_ABORT to awaken an + IST after determining that it has no interrupts registered. + + @param[in] int_num L2VIC to deregister; valid range is 0 to 1023. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number (not registered). + + @dependencies + None. + +*/ +unsigned int qurt_interrupt_deregister(int int_num); +/** @endcond */ + +/**@ingroup func_qurt_interrupt_disable + Disables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + After qurt_interrupt_disable() returns, the Hexagon subsystem + can no longer send the corresponding interrupt to the Hexagon + core, until qurt_interrupt_enable() is called + for the same interrupt. + + Avoid calling qurt_interrupt_disable() and qurt_interrupt_enable() frequently within + a short period of time.\n + - A pending interrupt can already be in the Hexagon core when qurt_interrupt_disable() + is called. Therefore, some time later, the pending interrupt is received on a Hexagon + hardware thread.\n + - After the Hexagon subsystem sends an interrupt to the Hexagon core, the Hexagon + hardware automatically disables the interrupt until kernel software re-enables the interrupt + at the interrupt acknowledgement stage. If qurt_interrupt_enable() is called from a certain + thread at an ealier time, the interrupt is re-enabled earlier and can trigger + sending a new interrupt to the Hexagon core while kernel software is still processing + the previous interrupt. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully disabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_disable(int int_num); + + +/**@ingroup func_qurt_interrupt_enable + Enables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully enabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. + +*/ + unsigned int qurt_interrupt_enable(int int_num); + + +/**@ingroup func_qurt_interrupt_status + Returns a value that indicates the pending status of the specified interrupt. + + @param[in] int_num Interrupt number that is being checked. + @param[out] status Interrupt status; 1 indicates that an interrupt is + pending, 0 indicates that an interrupt is not pending. + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_status(int int_num, int *status); + + +/**@ingroup func_qurt_interrupt_get_status + Gets the status of the specified interrupt in L2VIC. + + @param[in] int_num Interrupt number that is being checked. + @param[in] status_type 0 -- interrupt pending status \n + 1 -- interrupt enabling status + @param[out] status 0 -- OFF \n + 1 -- ON + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_status(int int_num, int status_type, int *status); + +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_interrupt_clear + Clears the pending status of the specified interrupt. + + @note1hang This operation is intended for system-level use, and must be used with care. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_clear(int int_num); + + +/**@ingroup func_qurt_interrupt_get_config + Gets the L2VIC interrupt configuration. \n + This function returns the type and polarity of the specified L2VIC interrupt. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[out] int_type Pointer to an interrupt type. \n + 0 -- Level-triggered interrupt \n + 1 -- Eedge-triggered interrupt + @param[out] int_polarity Pointer to interrupt polarity.\n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt. + + @return + #QURT_EOK -- Configuration successfully returned.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_config(unsigned int int_num, unsigned int *int_type, unsigned int *int_polarity); + +/**@ingroup func_qurt_interrupt_set_config + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang Deregister L2VIC interrupts before reconfiguring them. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Interrupt type. \n + 0 -- Level-triggered interrupt\n + 1 -- Edge-triggered interrupt + @param[in] int_polarity Interrupt polarity. \n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config(unsigned int int_num, unsigned int int_type, unsigned int int_polarity); + +/**@ingroup func_qurt_interrupt_set_config2 + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Notified to the hardware configuration callback function and used to + modify the L2VIC type. Possible values: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config2(unsigned int int_num, unsigned int int_type); + +/**@ingroup func_ qurt_interrupt_set_config3 + Sets the specified configuration value for the specified property of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured for polarity. + + @param[in] int_num L2VIC interrupt to re-enable. + @param[in] config_id Property to configure: \n + - #QURT_INT_CONFIGID_POLARITY \n + - #QURT_INT_CONFIGID_LOCK @tablebulletend + @param[in] config_val Dependent on the second argument config_id, specifies the value to set. \n + Values for #QURT_INT_CONFIGID_POLARITY: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE \n + + Values for #QURT_INT_CONFIGID_LOCK: \n + - #QURT_INT_LOCK_ENABLE\n + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered or is locked for enable/disable.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. +*/ +unsigned int qurt_interrupt_set_config3(unsigned int int_num, unsigned int config_id, unsigned int config_val); + + +/**@ingroup func_qurt_interrupt_raise + Raises the interrupt. \n + This function triggers a level-triggered L2VIC + interrupt, and accepts interrupt numbers in the range of 0 to 1023. + + @param[in] interrupt_num Interrupt number. + + @return + #QURT_EOK -- Success \n + -1 -- Failure; the interrupt is not supported. + + @dependencies + None. + */ +int qurt_interrupt_raise(unsigned int interrupt_num); + +/**@ingroup func_qurt_interrupt_raise2 + Raises the interrupt and returns the current pcycle value. + + @param[in] interrupt_num Interrupt number. + + @return + 0xFFFFFFFFFFFFFFFF -- Failure; the interrupt is not supported.\n + Other value -- pcycle count at the time the interrupt is raised. + + @dependencies + None. + */ +unsigned long long qurt_interrupt_raise2(unsigned int interrupt_num); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_isr_subcall + Indicates whether the current function is called from a callback procedure (either short or long). + + @return + #QURT_EOK -- TRUE \n + #QURT_EVAL -- FALSE. + + @dependencies + None. + */ +int qurt_isr_subcall(void); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_INT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_island.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_island.h new file mode 100755 index 0000000000000..f0c8ee27cf8b0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_island.h @@ -0,0 +1,122 @@ +#ifndef QURT_ISLAND_H +#define QURT_ISLAND_H + +/** + @file qurt_island.h + @brief Prototypes of power API + The APIs allow entering and exiting island mode where the memory + accesses are limited to local memory. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_island_get_status + Gets Island mode status. + + Returns a value that indicates whether the QuRT system executes in Island mode. + + @return + 0 - Normal mode. \n + 1 - Island mode. + + @dependencies + None. +*/ +unsigned int qurt_island_get_status (void); + +/**@ingroup func_qurt_island_get_status2 + Gets Island mode status especially that differentiates between island partial exit and complete exit. + + Returns a value that indicates the current state. + + @note1hang Transition from NORMAL mode to ISLAND mode happens in single + threaded mode. Whereas transition from ISLAND mode to other modes + happen in multi-threaded mode. So, a thread that gets island mode + status as NORMAL can assume the same status till it continues to + run. A thread that gets island mode status as ISLAND should + assume that the status may change to EXITING or NORMAL while it + runs. A thread that gets island mode status as EXITING should + assume that the status may change to NORMAL while it runs. If + the thread goes to wait state in after reading the status, it should get + the island mode state again and not assume the previous state. + @note2hang This api returns more intrinsic states than qurt_island_get_status, + when qurt_island_get_status returns 0, this api could return + QURT_ISLAND_MODE_EXITING or QURT_ISLAND_MODE_ISLAND + + @param[in/out] data field is reserved for future use. If NULL pointer is passed, + the field will be ignored. If a valid pointer is passed, + QuRT will return back a bitmask which can be interpreted as follows: + data[31] - Valid bit. Set to 1 to indicate data[30:0] are valid. + Otherwise set to 0. + data[30:0] – Reserved for future definition. + + @return + QURT_ISLAND_MODE_NORMAL - Main mode \n + QURT_ISLAND_MODE_ISLAND - Island mode \n + QURT_ISLAND_MODE_EXITING - Exiting Island mode \n + + @dependencies + None. +*/ +unsigned int qurt_island_get_status2 (unsigned int *data); + + + +/**@ingroup func_qurt_island_get_exit_status + Gets the reason for the last Island mode exit status. + + @param[out] cause_code Pointer that returns the cause code of the last + island exit reason. \n + - #QURT_EISLANDUSEREXIT -- Island exit due to user call for island exit.\n + - #QURT_ENOISLANDENTRY -- API called before exiting island. \n + - #QURT_EISLANDINVALIDINT -- Island exit due to an invalid interrupt in Island mode. @tablebulletend + + @param[out] int_num Pointer that holds the invalid interrupt number that caused + island exit when the cause code is #QURT_EISLANDINVALIDINT. + For other cases, it is -1. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_exit_status(unsigned int *cause_code, int *int_num); + +/**@ingroup func_qurt_island_get_enter_timestamp + Gets the recent timestamp when the system exits STM during island enter. + + @param[out] island_enter_timestamp Returns a pointer to the recent timestamp + recorded after the system exits STM during island enter. If the system never + attempts to enter island, the island_enter_timestamp return pointer holds a value + of zero. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_enter_timestamp(unsigned long long *island_enter_timestamp); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISLAND_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_isr.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_isr.h new file mode 100755 index 0000000000000..db29ea2f265d7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_isr.h @@ -0,0 +1,177 @@ +#ifndef QURT_ISR_H +#define QURT_ISR_H + +/*===================================================================== + + @file qurt_isr.h + + @brief Prototypes of Qurt ISR API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2017, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + Functions +=============================================================================*/ + + +/**@ingroup func_qurt_isr_set_hw_config_callback + Set callback function for the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_config_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_enable_callback + Set callback function for enabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_enable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_disable_callback + Set callback function for disabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_disable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_create + Creates an ISR thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + + @return + #QURT_EVAL -- Invalid arguments + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_isr_create (qurt_thread_t *thread_id, qurt_thread_attr_t *pAttr); + +/**@ingroup func_qurt_isr_register2 + Registers an Interrupt Service Routine to an ISR thread. ISR callback with the specified attributes. + The interrupt is enabled when this function returns success. + + @datatypes + qurt_thread_t + + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create() + @param[in] int_num The interrupt number + @param[in] prio Priority of the ISR + @param[in] flags Defines ACK type. Values : \n + QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the Kernel. + QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + @param[in] int_type. Notifies it to registered function. Values: \n + - QURT_INT_TRIGGER_USE_DEFAULT + - QURT_INT_TRIGGER_LEVEL_HIGH + - QURT_INT_TRIGGER_LEVEL_LOW + - QURT_INT_TRIGGER_RISING_EDGE + - QURT_INT_TRIGGER_FALLING_EDGE + - QURT_INT_TRIGGER_DUAL_EDGE + @param[in] isr Interrupt Service Routine with proto type void isr (void *arg, int int_num) + @param[in] arg 1st argument of the ISR when it is called to service the interrupt + + @return + QURT_EOK -- Successfully registered the ISR for the interrupt + QURT_EINT -- Interrupt not configured + QURT_EINVALID -- Invalid Thread ID + QURT_EDISABLED -- The feature is disabled + QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_register2 (qurt_thread_t isr_thread_id, int int_num, unsigned short prio, unsigned short flags, unsigned int int_type, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_isr_deregister2 + De-registers the ISR for the specified interrupt. + The interrupt is disabled when this function returns success. + + @param[in] int_num The interrupt number + + @return + QURT_EOK -- ISR deregistered successfully + QURT_ENOREGISTERED -- Interrupt with int_num is not registered + + @dependencies + None. + */ +int qurt_isr_deregister2 (int int_num); + +/**@ingroup func_qurt_isr_delete + ISR thread will exit and releases Kernel resources + + @note1hang The ISR thread shouldn't be actively processing interrupts, + otherwise the call will fail and return an error. + + @param[in] thread-id of the ISR thread that needs to be deleted. + + @return + QURT_ENOTALLOWED -- ISR thread is processing an interrupt + QURT_EINVALID -- Invalid ISR thread ID + QURT_EOK -- Success + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_delete (qurt_thread_t isr_tid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISR_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_l2cfg.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_l2cfg.h new file mode 100755 index 0000000000000..7e26b30a580d9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_l2cfg.h @@ -0,0 +1,98 @@ +#ifndef QURT_L2CFG_H +#define QURT_L2CFG_H +/** + @file qurt_l2cfg.h + @brief QuRT APIs for L2 configuration and system configuration + +EXTERNAL FUNCTIONS + qurt_l2cfg_set + qurt_l2cfg_get + qurt_system_config_get + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +/* Definition for system configuration */ +/** @addtogroup l2cfg_macros +@{ */ +#define QURT_CORE_CFG_HMX_INT8_SPATIAL 0x78 /**< HMX fixed-point spatial size */ +#define QURT_CORE_CFG_HMX_INT8_DEPTH 0x7C /**< HMX fixed-point output depth */ +/** @} */ /* end_addtogroup l2cfg_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_l2cfg_set + Sets the value of a L2 configuration register. A register can be set *IFF* its + initial value is configured. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[in] value Value to set the register to. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; likely + a configuration problem. \n + #QURT_EINVALID -- Argument error. \n + #QURT_ENOTALLOWED -- Setting this register is prohibited. + + @dependencies + None. + */ +int qurt_l2cfg_set (unsigned short offset, unsigned int value); + +/**@ingroup func_qurt_l2cfg_get + Gets the value of a L2 configuration register. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[out] value Pointer to value of the register. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; + likely a configuration problem. \n + #QURT_EINVALID -- Argument error. + + @dependencies + None. + + */ +int qurt_l2cfg_get (unsigned short offset, unsigned int * value); + + +/**@ingroup func_qurt_system_config_get + Gets the system configuration information. + + @param[in] index Index to system configuration. Values:\n + - #QURT_CORE_CFG_HMX_INT8_SPATIAL \n + - #QURT_CORE_CFG_HMX_INT8_DEPTH @tablebulletend + + @param[out] data Pointer to a word for returned data. + + @return + #QURT_EOK -- Get the configuration data successful. \n + Other values -- Failure (no such configuration available). + + @dependencies + None. + + */ +int qurt_system_config_get(int index, unsigned int *data); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_L2CFG_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_lifo.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_lifo.h new file mode 100755 index 0000000000000..dc399fccc5f0f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_lifo.h @@ -0,0 +1,71 @@ +#ifndef QURT_LIFO_H +#define QURT_LIFO_H +/** + @file qurt_lifo.h + + @brief + Provide lock free LastInFirstOut algorithm, which can be used in a + variety of situations for allocation/free fixed size buffer + This implementation touches the first word of your FREED buffer. Even + though it does not matter how you use it when it is allocated, you might want + to be a bit careful not to put your MAGIC number as the first field. + Because it will not hold the magic value for "freed" + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ +/** + Pops an element out of the LIFO. + + @param[in] freelist Pointer to the head of your list. + + @return + Top object from the list + + @dependencies + None. +*/ +/* ======================================================================*/ +void * qurt_lifo_pop(void *freelist); + + +/*======================================================================*/ +/** + Pushes an element into the LIFO. + + @param[in] freelist Pointer to the head of your list. + @param[in] buf Pointer to your buffer to push into the list. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_lifo_push(void *freelist, void *buf); + +void qurt_lifo_remove(void *freelist, void *buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_LIFO_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mailbox.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mailbox.h new file mode 100755 index 0000000000000..a6cd91c611782 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mailbox.h @@ -0,0 +1,176 @@ +#ifndef QURT_MAILBOX_H +#define QURT_MAILBOX_H + +/** + @file qurt_mailbox.h + @brief Definitions, macros, and prototypes used for QuRT mailbox + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* Definitions on typedef and return values */ + +#define QURT_MAILBOX_ID_NULL 0 +#define QURT_MAILBOX_ERROR -1 +#define QURT_MAILBOX_ID_ERROR -2 +#define QURT_MAILBOX_NON_VALID_DATA -3 +#define QURT_MAILBOX_FULL -4 +#define QURT_MAILBOX_DELETED -5 +#define QURT_MAILBOX_RECEIVE_HALTED -6 +#define QURT_MAILBOX_BANDWIDTH_LIMIT -7 + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ + +#define QURT_MAILBOX_AT_QURTOS 0U // Receiver is QurtOS +#define QURT_MAILBOX_AT_ROOTPD 1U // Receiver is RootPD (ASID=0) +#define QURT_MAILBOX_AT_USERPD 2U // Receiver is User PD (ASID!=0) +#define QURT_MAILBOX_AT_SECUREPD 3U // Receiver is Secure PD + +typedef unsigned char qurt_mailbox_receiver_cfg_t; + +#define QURT_MAILBOX_SEND_OVERWRITE 0U // When there is already valid content, overwrite it +#define QURT_MAILBOX_SEND_NON_OVERWRITE 1U // When there is already valid content, return failure + +typedef unsigned char qurt_mailbox_send_option_t; + + +#define QURT_MAILBOX_RECV_WAITING 0U // When there is no valid content, wait for it +#define QURT_MAILBOX_RECV_NON_WAITING 1U // When there is no valid content, return failure immediately +#define QURT_MAILBOX_RECV_PEEK_NON_WAITING 2U // Read the content, but doesn't remove it from the mailbox. No waiting. + +typedef unsigned char qurt_mailbox_recv_option_t; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/* Function prototype */ + +/**@ingroup qurt_mailbox_create + Creates a QuRT mailbox. + + @param name Mailbox name up to 8 characters. + @param recv_opt Configuration on the receiver process. + + @return + Mailbox ID -- Mailbox Identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at creating mailbox + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_create(char *name, qurt_mailbox_receiver_cfg_t recv_opt); + + +/**@ingroup qurt_mailbox_get_id + Gets a QuRT mailbox identifier. + + @param name Mailbox name up to 8 characters. + + @return + Mailbox ID -- Mailbox identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at getting mailbox ID + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_get_id(char *name); + + +/**@ingroup qurt_mailbox_send + Sends data to a QuRT mailbox. + + @param mailbox_id Mailbox identifier. + @param send_opt Option for mailbox send. + @param data Data to send. + + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors.\n + #QURT_MAILBOX_FULL Valid data already exists, non-overwriting.\n + #QURT_MAILBOX_BANDWIDTH_LIMIT Reached the bandwidth limitation. + + @dependencies + None. +*/ +int qurt_mailbox_send(unsigned long long mailbox_id, qurt_mailbox_send_option_t send_opt, unsigned long long data); + + +/**@ingroup qurt_mailbox_receive + Receive data from QuRT mailbox + + @param mailbox_id Mailbox Identifier + @param send_opt Option for mailbox receiving + @param data Pointer to data buffer for receiving + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. \n + #QURT_MAILBOX_NON_VALID_DATA No current valid data, put the previous content in the buffer. \n + #QURT_MAILBOX_RECEIVE_HALTED Receive halted, the waiting thread is woken up. \n + #QURT_MAILBOX_DELETED Mailbox is deleted, and the waiting thread is woken up. + + @dependencies + None. +*/ +int qurt_mailbox_receive(unsigned long long mailbox_id, qurt_mailbox_recv_option_t recv_opt, unsigned long long *data); + + +/**@ingroup qurt_mailbox_delete + Deletes a QuRT mailbox. + + A mailbox can only be deleted from the process that created the mailbox. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_delete(unsigned long long mailbox_id); + + +/**@ingroup qurt_mailbox_receive_halt + Halts a QuRT mailbox receiving and wakes up waiting threads. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_receive_halt(unsigned long long mailbox_id); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_MAILBOX_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_memory.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_memory.h new file mode 100755 index 0000000000000..90ce2586fec50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_memory.h @@ -0,0 +1,1487 @@ +#ifndef QURT_MEMORY_H +#define QURT_MEMORY_H +/** + @file qurt_memory.h + @brief Prototypes of kernel memory API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup memory_management_macros +@{ */ +#define QURT_SYSTEM_ALLOC_VIRTUAL 1 /**< Allocates available virtual memory in the address space of all + processes.*/ +/** @} */ /* end_addtogroup memory_management_macros */ +/**@cond rest_reg_dist */ +/** @addtogroup memory_management_types +@{ */ +/** @xreflabel{hdr:qurt_mem_default_pool} */ +extern qurt_mem_pool_t qurt_mem_default_pool __attribute__((section(".data"))); /**< Memory pool object.*/ +/** @} */ /* end_addtogroup memory_management_types */ + +/** @cond rest_reg_dist */ +/** Mapping attribute information*/ +typedef struct{ + qurt_paddr_64_t paddr; + qurt_size_t size ; + qurt_mem_cache_mode_t cache_mode; + qurt_perm_t perms ; +}qurt_mapping_attr_t; +/** @endcond */ +/** @} */ /* end_addtogroup mapping_attribute_types*/ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_mem_cache_clean + Performs a cache clean operation on the data stored in the specified memory area. + Peforms a syncht on all the data cache operations when the Hexagon processor version is V60 or greater. + + @note1hang Perform the flush all operation only on the data cache. + + @note1cont This operation flushes and invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed and invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_ALL\n + @note1 #QURT_MEM_CACHE_FLUSH_ALL is valid only when the type is #QURT_MEM_DCACHE @tablebulletend + @param[in] type Cache type. Values: + - #QURT_MEM_ICACHE + - #QURT_MEM_DCACHE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type.\n + + @dependencies + None. +*/ +int qurt_mem_cache_clean(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_clean2 + Performs a data cache clean operation on the data stored in the specified memory area. + + This API only performs the following data cache operations:\n + - #QURT_MEM_CACHE_FLUSH\n + - #QURT_MEM_CACHE_INVALIDATE\n + - #QURT_MEM_CACHE_FLUSH_INVALIDATE -- flushes/invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed/invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values:\n #QURT_MEM_CACHE_FLUSH\n #QURT_MEM_CACHE_INVALIDATE\n + #QURT_MEM_CACHE_FLUSH_INVALIDATE + @param[in] type Cache type. Values: \n #QURT_MEM_DCACHE + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type. + + @dependencies + None. +*/ +int qurt_mem_cache_clean2(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_phys_clean + Performs a cache clean operation on the data stored in the specified memory area based on address match and mask. + Operate on a cache line when (LINE.PhysicalPageNumber & mask) == addrmatch. + + @note1hang The addrmatch value should be the upper 24-bit physical address to match against. + + @datatypes + #qurt_mem_cache_op_t \n + + @param[in] mask 24-bit address mask. + @param[in] addrmatch Physical page number (24 bits) of memory to use as an address match. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid operation + + @dependencies + None. +*/ + +int qurt_mem_cache_phys_clean(unsigned int mask, unsigned int addrmatch, qurt_mem_cache_op_t opcode); + +/**@ingroup func_qurt_mem_l2cache_line_lock + Performs an L2 cache line locking operation. This function locks selective lines in the L2 cache memory. + + @note1hang Perform the line lock operation only on the 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to lock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of L2 cache memory to line lock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success.\n + #QURT_EALIGN -- Data alignment or address failure. + #QURT_EINVALID -- Improper addr and size passed (e.g. integer overflow due to addr + size) + #QURT_EFAILED -- Failed to lock cache line as all the ways were locked for the corresponding set of an address + in the range of addr and addr+size or the address range is not L2 cacheable + @dependencies + None. +*/ +int qurt_mem_l2cache_line_lock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_l2cache_line_unlock + Performs an L2 cache line unlocking operation. This function unlocks selective lines in the L2 cache memory. + + @note1hang Perform the line unlock operation only on a 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to unlock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of the L2 cache memory line to unlock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success. \n + #QURT_EALIGN -- Aligning data or address failure. \n + #QURT_EFAILED -- Operation failed, cannot find the matching tag. + + @dependencies + None. +*/ +int qurt_mem_l2cache_line_unlock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_region_attr_init + @xreflabel{sec:qurt_mem_region_attr_init} + Initializes the specified memory region attribute structure with default attribute values: \n + - Mapping -- #QURT_MEM_MAPPING_VIRTUAL \n + - Cache mode -- #QURT_MEM_CACHE_WRITEBACK \n + - Physical address -- -1 \n + - Virtual address -- -1 \n + - Memory type -- #QURT_MEM_REGION_LOCAL \n + - Size -- -1 + + @note1hang The memory physical address attribute must be explicitly set by calling the + qurt_mem_region_attr_set_physaddr() function. The size and pool attributes are set directly + as parameters in the memory region create operation. + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the destination structure for the memory region attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attach + Initializes a memory pool object to attach to a pool predefined in the system + configuration file. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. They are specified in memory region create operations + (Section @xref{sec:mem_region_create}). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool attach + operation is necessary only when allocating memory regions in nonstandard + memory units such as TCM. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach(char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_attach2 + Gets the identifier that corresponds to a pool object created specifically for a client, for example, HLOS_PHYSPOOL. + The client_handle is used to look up the client specific pool. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. Memory pool objects are specified during mapping creation operations + (qurt_mem_mmap() and qurt_mem_region_create()). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool_attach2 + operation is necessary only when allocating memory regions in memory units specific to the client. + + @datatypes + #qurt_mem_pool_t + + @param[in] client_handle Client identifier used by the OS to lookup the identifier + for client specific pool + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach2(int client_handle, char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_create + @xreflabel{hdr:qurt_mem_pool_create} + Dynamically creates a memory pool object from a physical address range. + + The pool is assigned a single memory region with the specified base address and size. + + The base address and size values passed to this function must be aligned to 4K byte + boundaries, and must be expressed as the actual base address and size values divided by 4K. + + For example, the function call: + @code + qurt_mem_pool_create ("TCM_PHYSPOOL", 0xd8020, 0x20, &pool) + @endcode + ... is equivalent to the following static pool definition in the QuRT system configuration file: + @code + + + + @endcode + + @cond rest_dist For more information on the system configuration file, see @xhyperref{80VB41979,80-VB419-79}. @endcond + + @note1hang Dynamically created pools are not identical to static pools. In particular, + qurt_mem_pool_attr_get() is not valid with dynamically created pools. + + @note1cont Dynamic pool creation permanently consumes system resources, and cannot be undone. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[in] base Base address of the memory region (divided by 4K). + @param[in] size Size (in bytes) of the memory region (divided by 4K). + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_mem_pool_create(char *name, unsigned base, unsigned size, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_add_pages + Adds a physical address range to the specified memory pool object.\n + + @note1hang Call this operation only with root privileges (guest OS mode). + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_mem_pool_add_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages); + +/**@ingroup func_qurt_mem_pool_remove_pages + Removes a physical address range from the specified memory pool object. + + If any part of the address range is in use, this operation returns an + error without changing the state. + + @note1hang Call this operation only with root privileges (guest-OS mode). + + @note1cont In the future, this operation will support (via the flags parameter) the + removal of a physical address range when part of the range is in use. + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + @param[in] flags Remove options. Values: \n + - 0 -- Skip holes in the range that are not part of the pool (default) \n + - #QURT_POOL_REMOVE_ALL_OR_NONE -- Pages are removed only if the specified + physical address range is entirely contained (with no holes) in the + pool free space. @tablebulletend + @param[in] callback Callback procedure called when pages were successfully removed. + Not called if the operation failed. Passing 0 as the parameter + value causes the callback to not be called. + @param[in] arg Value passed as an argument to the callback procedure. + + @return + #QURT_EOK -- Pages successfully removed. + + @dependencies + None. +*/ +int qurt_mem_pool_remove_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages, + unsigned flags, + void (*callback)(void *), + void *arg); +/**@ingroup memory_management_types*/ +#define QURT_POOL_REMOVE_ALL_OR_NONE 1 /**< */ + +/**@ingroup func_qurt_mem_pool_attr_get + Gets the memory pool attributes. \n + Retrieves pool configurations based on the pool handle, and fills in + the attribute structure with configuration values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_attr_t + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[out] attr Pointer to the memory region attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_attr_get (qurt_mem_pool_t pool, qurt_mem_pool_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attr_get_size + Gets the size of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] size Pointer to the destination variable for the range size. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_size (qurt_mem_pool_attr_t *attr, int range_id, qurt_size_t *size){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*size) = 0; + return QURT_EINVALID; + } + else { + (*size) = attr->ranges[range_id].size; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr + Gets the start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_t *addr){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; + } + else { + (*addr) = (attr->ranges[range_id].start)<<12; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr_64 + Gets the 64 bit start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_64_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr_64 (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_64_t *addr){ +if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; +} +else { + (*addr) = ((qurt_addr_64_t)attr->ranges[range_id].start)<<12; + } + return QURT_EOK; + } + + +/**@ingroup func_qurt_mem_pool_status_get + Gets the memory pool status. \n + Based on the pool handle, retrieves largest contiguous free memory, + total free memory, and total memory declared for the pool in bytes. Fills in + the memory status structure with the values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_status_t + + @param[in] pool Pool handle. + @param[out] status Pointer to the memory pool status structure. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_status_get (qurt_mem_pool_t pool, qurt_mem_pool_status_t *status); + + +/**@ingroup func_qurt_mem_pool_is_available + Checks whether the number of pages that the page_count argument indicates + can be allocated from the specified pool. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_mem_mapping_t \n + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[in] page_count Number of 4K pages. + @param[in] mapping_type Variable of type qurt_mem_mapping_t. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Mapping_type is invalid. \n + #QURT_EMEM -- Specified pages cannot be allocated from the pool. + + @dependencies + None. +*/ +int qurt_mem_pool_is_available(qurt_mem_pool_t pool, int page_count, qurt_mem_mapping_t mapping_type); + + +/**@ingroup func_qurt_mem_region_create + @xreflabel{sec:mem_region_create} + Creates a memory region with the specified attributes. + + The application initializes the memory region attribute structure with + qurt_mem_region_attr_init() and qurt_mem_region_attr_set_bus_attr(). + + If the virtual address attribute is set to its default value + (Section @xref{sec:qurt_mem_region_attr_init}), the virtual address of the memory region is + automatically assigned any available virtual address value. + + If the memory mapping attribute is set to virtual mapping, the physical address of the memory region + is also automatically assigned.\n + + @note1hang The physical address attribute is explicitly set in the attribute structure only + for memory regions with physical-contiguous-mapped mapping. + + Memory regions are always assigned to memory pools. The pool value specifies the memory pool + that the memory region is assigned to. + + @note1hang If attr is specified as NULL, the memory region is created with default + attribute values (Section @xref{sec:qurt_mem_region_attr_init}). + QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}), which allocates memory regions in SMI memory. + + @datatypes + #qurt_mem_region_t \n + #qurt_size_t \n + #qurt_mem_pool_t \n + #qurt_mem_region_attr_t + + @param[out] region Pointer to the memory region object. + @param[in] size Memory region size (in bytes). If size is not an integral multiple of 4K, + it is rounded up to a 4K boundary. + @param[in] pool Memory pool of the region. + @param[in] attr Pointer to the memory region attribute structure. + + @return + #QURT_EOK -- Memory region successfully created.\n + #QURT_EMEM -- Not enough memory to create region. + #QURT_EINVALID -- Invalid cache attributes / permissions provided in attribute. + + @dependencies + None. +*/ +int qurt_mem_region_create(qurt_mem_region_t *region, qurt_size_t size, qurt_mem_pool_t pool, qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_region_delete + Deletes the specified memory region. + + If the caller application creates the memory region, it is removed and the system reclaims its + assigned memory. + + If a different application creates the memory region (and is shared with the caller + application), only the local memory mapping to the region is removed; the system does + not reclaim the memory. + + @datatypes + #qurt_mem_region_t + + @param[in] region Memory region object. + + @returns + #QURT_EOK -- Region successfully deleted. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. +*/ +int qurt_mem_region_delete(qurt_mem_region_t region); + + +/**@ingroup func_qurt_mem_region_attr_get + @xreflabel{sec:mem_region_attr_get} + Gets the memory attributes of the specified message region. + After a memory region is created, its attributes cannot be changed. + + @datatypes + #qurt_mem_region_t \n + #qurt_mem_region_attr_t + + @param[in] region Memory region object. + @param[out] attr Pointer to the destination structure for memory region attributes. + + @return + #QURT_EOK -- Operation successfully performed. \n + Error code -- Failure. + + @dependencies + None. +*/ +int qurt_mem_region_attr_get(qurt_mem_region_t region, qurt_mem_region_attr_t *attr); + + +/**@ingroup func_qurt_mem_region_attr_set_type + Sets the memory type in the specified memory region attribute structure. + + The type indicates whether the memory region is local to an application or shared between + applications. + @cond rest_dist For more information, see @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in,out] attr Pointer to memory region attribute structure. + @param[in] type Memory type. Values: \n + - #QURT_MEM_REGION_LOCAL \n + - #QURT_MEM_REGION_SHARED @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t type){ + attr->type = type; +} + +/**@ingroup func_qurt_mem_region_attr_get_size + Gets the memory region size from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] size Pointer to the destination variable for memory region size. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_size(qurt_mem_region_attr_t *attr, qurt_size_t *size){ + (*size) = attr->size; +} + +/**@ingroup func_qurt_mem_region_attr_get_type + Gets the memory type from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] type Pointer to the destination variable for the memory type. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t *type){ + (*type) = attr->type; +} + +/**@ingroup func_qurt_mem_region_attr_set_physaddr + Sets the memory region 32-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise QuRT automatically sets it + when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr(qurt_mem_region_attr_t *attr, qurt_paddr_t addr){ + attr->ppn = (unsigned)(((unsigned)(addr))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr + Gets the memory region physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for memory region physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned)(((unsigned) (attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_region_attr_set_virtaddr + Sets the memory region virtual address in the specified memory attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_addr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_virtaddr(qurt_mem_region_attr_t *attr, qurt_addr_t addr){ + attr->virtaddr = addr; +} + +/**@ingroup func_qurt_mem_region_attr_get_virtaddr + Gets the memory region virtual address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for the memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_virtaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned int)(attr->virtaddr); +} + +/**@ingroup func_qurt_mem_region_attr_set_mapping + Sets the memory mapping in the specified memory region attribute structure. + + The mapping value indicates how the memory region is mapped in virtual memory. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mapping Mapping. Values: + - #QURT_MEM_MAPPING_VIRTUAL + - #QURT_MEM_MAPPING_PHYS_CONTIGUOUS + - #QURT_MEM_MAPPING_IDEMPOTENT + - #QURT_MEM_MAPPING_VIRTUAL_FIXED + - #QURT_MEM_MAPPING_NONE + - #QURT_MEM_MAPPING_VIRTUAL_RANDOM + - #QURT_MEM_MAPPING_INVALID @tablebulletend + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t mapping){ + attr->mapping_type = mapping; +} + +/**@ingroup func_qurt_mem_region_attr_get_mapping + Gets the memory mapping from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mapping Pointer to the destination variable for memory mapping. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t *mapping){ + (*mapping) = attr->mapping_type; +} + +/**@ingroup func_qurt_mem_region_attr_set_cache_mode + Sets the cache operation mode in the specified memory region attribute structure. + + @cond rest_dist For more information on the cache, see @xhyperref{80VB41992,80-VB419-92}.@endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mode Cache mode. Values: \n + - #QURT_MEM_CACHE_WRITEBACK \n + - #QURT_MEM_CACHE_WRITETHROUGH\n + - #QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE\n + - #QURT_MEM_CACHE_NONE @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t mode){ + QURT_PGATTR_C_SET(attr->pga, (unsigned)mode); +} + +/**@ingroup func_qurt_mem_region_attr_get_cache_mode + Gets the cache operation mode from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t *mode){ + unsigned int mode_temp = QURT_PGATTR_C_GET(attr->pga); + (*mode) = (qurt_mem_cache_mode_t)mode_temp; +} + +/**@ingroup func_qurt_mem_region_attr_set_bus_attr + Sets the (A1, A0) bus attribute bits in the specified memory region attribute structure. + + @cond rest_dist For more information on the bus attribute bits, see the @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] abits The (A1, A0) bits to use with the memory region, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_bus_attr(qurt_mem_region_attr_t *attr, unsigned abits){ + QURT_PGATTR_A_SET(attr->pga, abits); +} + +/**@ingroup func_qurt_mem_region_attr_get_bus_attr + Gets the (A1, A0) bus attribute bits from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] pbits Pointer to an unsigned integer that is filled in with + the (A1, A0) bits from the memory region attribute structure, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_bus_attr(qurt_mem_region_attr_t *attr, unsigned *pbits){ + (*pbits) = QURT_PGATTR_A_GET(attr->pga); +} + +void qurt_mem_region_attr_set_owner(qurt_mem_region_attr_t *attr, int handle); +void qurt_mem_region_attr_get_owner(qurt_mem_region_attr_t *attr, int *p_handle); +void qurt_mem_region_attr_set_perms(qurt_mem_region_attr_t *attr, unsigned perms); +void qurt_mem_region_attr_get_perms(qurt_mem_region_attr_t *attr, unsigned *p_perms); + +/**@ingroup func_qurt_mem_map_static_query + Determines whether a memory page is statically mapped. + Pages are specified by the following attributes: physical address, page size, cache mode, + and memory permissions. \n + - If the specified page is statically mapped, vaddr returns the virtual + address of the page. \n + - If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + The system configuration file defines QuRT memory maps. + + @datatypes + #qurt_addr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr Physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped, vaddr returns the virtual address. \n + #QURT_EMEM -- Specified page is not statically mapped, vaddr returns -1. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query(qurt_addr_t *vaddr, qurt_addr_t paddr, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + + +/**@ingroup func_qurt_mem_region_query + Queries a memory region. \n + This function determines whether a dynamically-created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. + When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns #QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_paddr_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr Physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Query successfully performed. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_t paddr); + + +/**@ingroup func_qurt_mapping_create + @xreflabel{hdr:qurt_mapping_create} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Mapping created. \n + #QURT_EMEM -- Failed to create mapping. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove + @xreflabel{hdr:qurt_mapping_remove} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Mapping created. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr + Translates a virtual memory address to the physical memory address to which it maps. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the + physical address of another process. + + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- Physical address to which the virtual address is mapped.\n + 0 -- Virtual address not mapped. + + @dependencies + None. +*/ +qurt_paddr_t qurt_lookup_physaddr (qurt_addr_t vaddr); + +/**@ingroup func_qurt_mem_region_attr_set_physaddr_64 + Sets the memory region 64-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise it is automatically set by + QuRT when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr_64 Memory region 64-bit physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t addr_64){ + attr->ppn = (unsigned)(((unsigned long long)(addr_64))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr_64 + Gets the memory region 64-bit physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr_64 Pointer to the destination variable for the memory region 64-bit physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t *addr_64){ + (*addr_64) = (unsigned long long)(((unsigned long long)(attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_map_static_query_64 + Determines if a memory page is statically mapped. + The following attributes specify pages: 64-bit physical address, page size, cache mode, + and memory permissions. \n + If the specified page is statically mapped, vaddr returns the virtual + address of the page. + If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + QuRT memory maps are defined in the system configuration file. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr_64 64-bit physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped; a virtual address is returned in vaddr. \n + #QURT_EMEM -- Specified page is not statically mapped; -1 is returned in vaddr. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query_64(qurt_addr_t *vaddr, qurt_paddr_64_t paddr_64, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mem_region_query_64 + Determines whether a dynamically created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr_64 64-bit physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query_64(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64); + +/**@ingroup func_qurt_mapping_create_64 + @xreflabel{hdr:qurt_mapping_create_64} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Failure. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove_64 + @xreflabel{hdr:qurt_mapping_remove_64} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Success. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr_64 + Translates a virtual memory address to the 64-bit physical memory address it is mapped to. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the physical + address of another process. + + @datatypes + #qurt_paddr_64_t \n + #qurt_addr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address has not been mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr_64 (qurt_addr_t vaddr); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_mapping_reclaim + Deallocates all QuRT resources associated with the specified virtual + memory area, making it available for user memory management:\n + - The associated physical memory areas are freed and added to the + specified physical pool.\n + - The associated TLB entries are deleted and made available for TLB + management.\n + - The virtual memory area is not freed -- it is left in + place as allocated, but unmapped virtual memory. Access to this + memory area generates an exception.\n + + The virtual memory area must be statically allocated. + If no pool is specified, the freed physical memory is not added to any pool. + + @note1hang The virtual memory area is restricted to being filled with locked + TLB entries that are contiguous within the memory area, and contained by it. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_pool_t + + @param[in] vaddr Virtual address of the memory area to free. + @param[in] vsize Size (in bytes) of the memory area to free. + @param[in] pool Handle to the physical pool where freed physical memory is added. + If set to 0, freed physical memory is not added to any pool. + + @return + 0 -- Success. \n + Nonzero -- Failure that indicates a partial success, or that the request was malformed. \n @note1hang The expected behavior is that + QuRT logs messages related to the failure, and callers are free to ignore the return value. + + @dependencies + None. +*/ +int qurt_mapping_reclaim(qurt_addr_t vaddr, qurt_size_t vsize, qurt_mem_pool_t pool); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_mem_configure_cache_partition + Configures the Hexagon cache partition at the system level. + + A partition size value of #SEVEN_EIGHTHS_SIZE is applicable only to the L2 cache. + + The L1 cache partition is not supported in Hexagon processor version V60 or greater. + + @note1hang Call this operation only with QuRT OS privilege. + + @datatypes + #qurt_cache_type_t \n + #qurt_cache_partition_size_t + + @param[in] cache_type Cache type for partition configuration. Values: \n + - #HEXAGON_L1_I_CACHE \n + - #HEXAGON_L1_D_CACHE \n + - #HEXAGON_L2_CACHE @tablebulletend + + @param[in] partition_size Cache partition size. Values: \n + - #FULL_SIZE \n + - #HALF_SIZE \n + - #THREE_QUARTER_SIZE \n + - #SEVEN_EIGHTHS_SIZE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Error. + + @dependencies + None. + */ +int qurt_mem_configure_cache_partition(qurt_cache_type_t cache_type, qurt_cache_partition_size_t partition_size); + + +/**@ingroup func_qurt_mem_syncht + @xreflabel{hdr:qurt_mem_syncht} + Performs heavy-weight synchronization of memory transactions. + + This operation does not return until all previous memory transactions (cached and uncached load/store, + mem_locked, and so on) that originated from the current thread are complete and globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon syncht instruction. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_syncht(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" SYNCHT \n"); + #endif +} + +/**@ingroup func_qurt_mem_barrier + @xreflabel{hdr:qurt_mem_barrier} + Creates a barrier for memory transactions. + + This operation ensures that all previous memory transactions are globally observable before any + future memory transactions are globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon barrier instruction. + @return + None + + @dependencies + None. + */ +static inline void qurt_mem_barrier(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" BARRIER \n"); + #endif +} +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_system_mem_alloc + Requests that the kernel allocates memory from the kernel-owned pool. + + @param[in] size Size in bytes (aligned to 4K) to allocate. + @param[in] align Any alignment that must be considered for the allocation. + @param[in] flags Supports the #QURT_SYSTEM_ALLOC_VIRTUAL flag; allocates + available virtual memory in the address space of all processes. + + @return + #QURT_EFATAL -- Allocation failed \n + Start address of the successful allocation. + + @dependencies + None. +*/ +unsigned qurt_system_mem_alloc(unsigned size, unsigned align, unsigned flags); +/** @endcond */ +/** @cond rest_reg_dist*/ +/**@ingroup func_qurt_lookup_physaddr2 + Translates the virtual memory address of the specified process to the 64-bit + physical memory address to which it is mapped. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[in] vaddr Virtual address. + @param[in] pid PID. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address is not mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr2(qurt_addr_t vaddr, unsigned int pid); +/** @endcond */ + +/**@ingroup func_qurt_mapping_attr_get + Gets the mapping attributes for a given virtual address and PID + + @datatypes + #qurt_addr_t \n + #qurt_mapping_attr_t + + @param[in] vaddr virtual address for which the attributes are required. + @param[in] pid process id for the target process + @param[out] attr Pointer to the mapping attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Incorrect virtual address or pid +*/ +int qurt_mapping_attr_get(qurt_addr_t vaddr, unsigned int pid, qurt_mapping_attr_t *attr); + + +/**@ingroup func_qurt_mapping_attr_get_cache_mode + Gets the cache operation mode in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] cache_mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_cache_mode(qurt_mapping_attr_t *attr, qurt_mem_cache_mode_t *cache_mode) +{ + (*cache_mode) = attr->cache_mode; +} + +/**@ingroup func_qurt_mapping_attr_get_physaddr + Gets the physical memory address in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] physaddr Pointer to the destination variable for physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_physaddr(qurt_mapping_attr_t *attr, qurt_paddr_64_t *physaddr) +{ + (*physaddr) = attr->paddr; +} + +/**@ingroup func_qurt_mapping_attr_get_perms + Gets the permissions in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_perm_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] perms Pointer to the destination variable for permissions. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_perms(qurt_mapping_attr_t *attr, qurt_perm_t *perms) +{ + (*perms) = attr->perms; +} + +/**@ingroup func_qurt_mapping_attr_get_size + Gets the size in the specified memory mapping attribute structure.This represents size of the + TLB entry which covers the virtual address. + + + @datatypes + #qurt_mapping_attr_t \n + #unsigned int + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] size Pointer to the destination variable for size. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_mapping_attr_get_size(qurt_mapping_attr_t *attr, unsigned int *size) +{ + (*size) = attr->size; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MEMORY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mmap.h new file mode 100755 index 0000000000000..c3bd875910af7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mmap.h @@ -0,0 +1,359 @@ +#ifndef QURT_MMAP_H +#define QURT_MMAP_H +/** + @file qurt_mmap.h + @brief Prototypes of memory mapping/unmapping APIs. + The APIs allow the user to map, un-map, and change permissions + on memory regions. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2022, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_mem_mmap + Creates a memory mapping with the specified attributes. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that specifies a pool handle + if the user wants to allocate memory from a specific pool. + The default value for this argument is NULL. + @param[in] pRegion Map region. This argument is unused, and the default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + @param[in] flags Mapping modes.\n + - #QURT_MAP_NAMED_MEMSECTION + - #QURT_MAP_FIXED \n + - #QURT_MAP_NONPROCESS_VPOOL \n + - #QURT_MAP_TRYFIXED \n + - #QURT_MAP_ANON \n + - #QURT_MAP_PHYSADDR \n + - #QURT_MAP_VA_ONLY @tablebulletend + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap2 + Creates a memory mapping with the specified attributes. Returns a more descriptive + error code in case of failure. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that allows the user to specify a pool handle + when the user wants to allocate memory from a specific pool. + Default value for this argument is NULL. + @param[in] pRegion Map region (unused argument); default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode. + @param[in] flags Mapping modes; + Shared, Private, or Anonymous. + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_EMEM -- Physical address is not available. \n + #QURT_EFAILED -- VA is not available or mapping failed.\n + #QURT_EINVALID -- Invalid argument was passed (for example, an unaligned VA/PA). + */ +void *qurt_mem_mmap2(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap_by_name + Creates a memory mapping for a named-memsection using the specified attributes. + The named memsection should be specified in cust_config.xml. + + @note1hang If the specified attributes are not valid or the named memsection is not found, + an error result is returned. + + @param[in] name Name of the memsection in cust_config.xml that specifies + this mapping. Should be less than 25 characters. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode + @param[in] flags Mapping modes, such as + Shared, Private, or Anonymous. + @param[in] offset Offset relative to the physical address range specified in memsection. + If offset + length exceeds size of memsection, failure is + returned. + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap_by_name(const char* name, + void *addr, + size_t length, + int prot, + int flags, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mprotect2 + Changes access permissions and attributes on an existing mapping based on the client_handle argument. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned. + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping.\n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect2(int client_handle, const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_mprotect + Changes access permissions and attributes on an existing mapping. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned.\n + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect(const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_munmap + Removes an existing mapping. + + @note1hang If the specified mapping is not found in the context of the caller process + or invalid attributes are passed, an error code is returned. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap(void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap2 + Removes an existing mapping for a specified process. + + @note1hang This API allows a root process entity, such as a driver, to remove mapping + that was created for a user process. If the specified mapping is not found in the context + of client handle or invalid attributes are passed, an error code is returned. + + @param[out] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap2(int client_handle, + void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap3 + Removes an existing mapping or reservation for a specified process. + + @param[in] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Pointer to a virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] flags Specifies the flag. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap3(int client_handle, + void *addr, + size_t length, + int flags); + +/* +|| The macros here follow the style of the standard mmap() macros, but with +|| QURT_ prepended to avoid name conflicts, and to avoid having a dependency +|| on sys/mman.h. +|| +|| Wherever possible, any values here that are also present in sys/mman.h +|| should have the same value in both places so that we can accept "mmap" +|| calls without having to remap parameters to new values. +|| +|| In the future, it would be desirable to have a regression test that +|| checks, for instance, that these macros match. Example: +|| +|| assert(QURT_MAP_FAILED == MAP_FAILED); +|| ... repeat as needed ... +*/ + +/** @addtogroup memory_mapping_macros +@{ */ +/** @cond */ +#define QURT_PROT_NONE 0x00U /**< */ +#define QURT_PROT_READ 0x01U /**< */ +#define QURT_PROT_WRITE 0x02U /**< */ +#define QURT_PROT_EXEC 0x04U /**< */ +#define QURT_PROT_NODUMP 0x08U /**< Skip dumping the mapping. During PD dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and the DSP process + crashes before the mapping is removed.*/ +#define QURT_PROT_ISLAND 0x10U /**< Island mapping. */ + +#define QURT_MAP_SHARED 0x0001U /**< Shared. */ +#define QURT_MAP_PRIVATE 0x0002U /**< Private. */ +/** @endcond */ +#define QURT_MAP_NAMED_MEMSECTION 0x0004U /**< Named memsection. */ +#define QURT_MAP_FIXED 0x0010U /**< Fixed virtual address. */ +#define QURT_MAP_RENAME 0x0020U /**< Rename. */ +#define QURT_MAP_NORESERVE 0x0040U /**< No reserve. */ +#define QURT_MAP_INHERIT 0x0080U /**< Inherit. */ +#define QURT_MAP_NONPROCESS_VPOOL 0x0100U /**< Use a virtual address outside of the default range of the + processes. This option is only supported in the root process + and only when virtual memory split is enabled in the XML. + The root process can use this flag to create mapping for a + user process, for example, if the virtual address is configured + for a 3G/1G split, the root process can use this flag to create + mapping in the top 1 GB area for the user process or the + lower 3 GB area for the root process. This is useful for + shared buffer use cases. */ +#define QURT_MAP_HASSEMAPHORE 0x0200U /**< Has semaphore. */ +#define QURT_MAP_TRYFIXED 0x0400U /**< Try to create a mapping for a virtual address that was passed. + If the passed virtual address fails, use a random virtual address. */ +#define QURT_MAP_WIRED 0x0800U /**< Wired. */ +#define QURT_MAP_FILE 0x0000U /**< File. */ +#define QURT_MAP_ANON 0x1000U /**< Allocate physical memory from the pool that was passed. + By default, memory is allocated from the default physpool. */ +#define QURT_MAP_VA_ONLY 0X2000U /**< Reserve a virtual address without + mapping it. */ + +/** @cond */ +#define QURT_MAP_ALIGNED(n) ((n) << QURT_MAP_ALIGNMENT_SHIFT) +#define QURT_MAP_ALIGNMENT_SHIFT 24 + + +#define QURT_MAP_ALIGNMENT_MASK QURT_MAP_ALIGNED(0xff) /**< */ +#define QURT_MAP_ALIGNMENT_64KB QURT_MAP_ALIGNED(16) /**< */ +#define QURT_MAP_ALIGNMENT_16MB QURT_MAP_ALIGNED(24) /**< */ +#define QURT_MAP_ALIGNMENT_4GB QURT_MAP_ALIGNED(32) /**< */ +#define QURT_MAP_ALIGNMENT_1TB QURT_MAP_ALIGNED(40) /**< */ +#define QURT_MAP_ALIGNMENT_256TB QURT_MAP_ALIGNED(48) /**< */ +#define QURT_MAP_ALIGNMENT_64PB QURT_MAP_ALIGNED(56) /**< */ +/** @endcond */ +#define QURT_MAP_FAILED ((void *) -1) /**< Mapping creation failed. */ + +/* +|| The macros below are extensions beyond the standard mmap flags, but follow +|| the style of the mmap flags. +*/ +/** @cond */ +// Describe bitfields in (prot) +#define QURT_PROT_CACHE_BOUNDS 16U,19U,7U /**< Bits 16 through 19 are cache attribute, default is 0. */ +#define QURT_PROT_BUS_BOUNDS 20U,21U,0U /**< Bits 20 through 21 are bus attributes, default is 0. */ +#define QURT_PROT_USER_BOUNDS 22U,23U,3U /**< Bits 22 through 23 are user mode, default is 3; + default of 3 means to derive user mode setting from the + default mode of the client. */ + +// Describe bitfields in (flags) +#define QURT_MAP_PHYSADDR_BOUNDS 15U,15U,0U /**< Bits 15 through 15 are physaddr, default is 0. */ +#define QURT_MAP_TYPE_BOUNDS 16U,19U,0U /**< Bits 16 through 19 are mapping type, default is 0. */ +#define QURT_MAP_REGION_BOUNDS 20U,23U,0U /**< Bits 20 through 23 are region type, default is 0. */ +/** @endcond */ + +// These macros get OR'ed into (prot) +#define QURT_PROT_CACHE_MODE(n) QURT_MMAP_BUILD(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_BUS_ATTR(n) QURT_MMAP_BUILD(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_USER_MODE(n) QURT_MMAP_BUILD(QURT_PROT_USER_BOUNDS,(n)) /**< */ +// These macros get OR'ed into (flags) + +#define QURT_MAP_PHYSADDR QURT_MMAP_BUILD(QURT_MAP_PHYSADDR_BOUNDS,1U) /**< Use the physical address that was passed in offset field. + This is allowed only for root process. */ +#define QURT_MAP_TYPE(n) QURT_MMAP_BUILD(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_REGION(n) QURT_MMAP_BUILD(QURT_MAP_REGION_BOUNDS,(n)) /**< */ +/** @} */ /* end_addtogroup memory_mapping_macros */ +/** @cond */ +// These macros extract fields from (prot) +#define QURT_PROT_GET_CACHE_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_BUS_ATTR(n) QURT_MMAP_EXTRACT(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_USER_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_USER_BOUNDS,(n)) /**< */ + +// These macros extract fields from (flags) +#define QURT_MAP_GET_TYPE(n) QURT_MMAP_EXTRACT(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_GET_REGION(n) QURT_MMAP_EXTRACT(QURT_MAP_REGION_BOUNDS,(n)) /**< */ + +// Macros for bitfield insertion and extraction +#define QURT_MMAP_MASK(lo,hi) (~((~0u) << ((hi)-(lo)+1U))) /**< Mask of same size as [lo..hi]. */ +#define QURT_MMAP_BUILD_(lo,hi,def,n) ((((n)^(def))&QURT_MMAP_MASK((lo),(hi)))<<(lo)) /**< */ +#define QURT_MMAP_EXTRACT_(lo,hi,def,n) ((((n)>>(lo))&QURT_MMAP_MASK((lo),(hi)))^(def)) /**< */ +#define QURT_MMAP_BUILD(a,b) QURT_MMAP_BUILD_(a,b) /**< */ +#define QURT_MMAP_EXTRACT(a,b) QURT_MMAP_EXTRACT_(a,b) /**< */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mq.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mq.h new file mode 100755 index 0000000000000..580c83d3de41a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mq.h @@ -0,0 +1,458 @@ +#ifndef QURT_MQ_H +#define QURT_MQ_H +/** + @file qurt_mq.h + + @brief Prototypes of secure message queues API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2019-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +======================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_MQ_NAME_MAXLEN 16U /**< Maximum name length. */ + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/* This enum must be generated in accordance to process class class numbers. + For now it is made to match generated version, do not change this unless + there is a corresponding change in the process_class.py, indicies start from 0 + basically: QURT_MQ_SECURITY_SCOPE_ = (1 << QURTK_process_class_index_) +*/ +typedef enum { + QURT_MQ_SECURITY_SCOPE_KERNEL = ( 1U << 0 ), + QURT_MQ_SECURITY_SCOPE_SRM = ( 1U << 1 ), + QURT_MQ_SECURITY_SCOPE_SECURE = ( 1U << 2 ), + QURT_MQ_SECURITY_SCOPE_CPZ = ( 1U << 3 ), + QURT_MQ_SECURITY_SCOPE_ROOT = ( 1U << 4 ), + QURT_MQ_SECURITY_SCOPE_SIGNED = ( 1U << 5 ), + QURT_MQ_SECURITY_SCOPE_UNSIGNED = ( 1U << 6 ), + QURT_MQ_SECURITY_SCOPE_SECURE_ROOT = ( 1U << 7 ) +} qurt_mq_security_scope_t; + +typedef enum { + QURT_MQ_CARDINALITY_PTP = (1U << 0), + QURT_MQ_CARDINALITY_MTO = (1U << 1) +}qurt_mq_cardinality_t; + +typedef unsigned int qurt_mqd_t; + +typedef union{ + struct { + unsigned int perms:2; + unsigned int cardinality:1; + unsigned int blocking:1; + + qurt_mq_security_scope_t creator_scope: 8; + qurt_mq_security_scope_t allowed_scope: 8; //can be a bitmask in case of MTO + unsigned int queue_closed: 1; + unsigned int reserved: 11; + }; //try to do anonymous struct + unsigned int raw; +} qurt_mq_flags_t; + + +/* permissions are from qurt_types.h , block X though */ +#if 0 +/** Memory access permission. */ +typedef enum { + QURT_PERM_READ=0x1U, /**< */ + QURT_PERM_WRITE=0x2U, /**< */ + QURT_PERM_EXECUTE=0x4U, /**< */ + QURT_PERM_FULL=QURT_PERM_READ|QURT_PERM_WRITE|QURT_PERM_EXECUTE, /**< */ +} qurt_perm_t; +#endif + +struct qurt_mq_attr { + unsigned flags; /**< Configured flags. Only meaningful with get_attr(), only used for qurt_mq_flags_t.perms. */ + unsigned mq_maxmsg; /**< Maximum number of messages. Used with create() and get_attr. */ + unsigned short mq_send_msgsize; /**< Maximum size (bytes) of message in receiver facing queue, + from sender to receiver. */ + unsigned short mq_recv_msgsize; /**< Maximum size (bytes) of message in sender facing queue, + from receiver to sender. */ + unsigned client_pid; /**< Process ID of client that is allowed to open the message queue + that was created using qurt_mq_create(). */ + qurt_mq_cardinality_t cardinality; /**< Cardinality of message queue connection, see below. */ + qurt_mq_security_scope_t scope; /**< Security scope of the senders to the queue. */ +}; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mq_attr_init + Initializes attributes to default values used for creating the queue. + + The initialize operation sets the following default attribute values: \n + - flag - QURT_PERM_READ | QURT_PERM_WRITE \n + - maxmsg - 1 \n + - mq_send_msgsize - 8 \n + - mq_recv_msgsize - 8 \n + - sender_pid - -1 \n + - cardinality - QURT_MQ_CARDINALITY_PTP \n + - scope - QURT_MQ_SECURITY_SCOPE_SIGNED \n + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the initialized message queue object. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_init(struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_attr_set_send_msgsize + Sets the message size in bytes the sender can send. + Maximum message length is configurable using the XML configuration, however, limited to a maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_send_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_recv_msgsize + Sets the message size in bytes that the receiver can read. + Maximum message length is configurable using the XML configuration, however, limited to maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_recv_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_maxmsg + Sets the maximum message that can queue in the message queue. + Message depth is configurable using the XML configuration. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] depth Maximum message that can be queued. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_maxmsg (struct qurt_mq_attr *attr, unsigned int depth); + +/**@ingroup qurt_mq_attr_set_scope + Sets the scope of the message queue. A message queue created with a security + scope allows only a process class of that scope to open a message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mq_security_scope_t + + @param[in,out] attr Pointer to the message queue object. + @param[in] scope Scope of the message queue: \n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_scope (struct qurt_mq_attr *attr, qurt_mq_security_scope_t scope); + + +/**@ingroup qurt_mq_attr_set_client_pid + Sets the client_pid that can open this message queue. + If client_pid is set, allowed_scope to open MQ shall not be considered. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] client_pid Valid PID for client process. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_client_pid (struct qurt_mq_attr *attr, unsigned client_pid); + +/**@ingroup qurt_mq_attr_set_flags + Sets the properties of the message queues. + The current implementation is only used to set the permission for the message queue using the flag attribute. + Default is #QURT_PERM_READ | #QURT_PERM_WRITE, explicit permission is not implemented. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] flags Permission for message queue. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_flags (struct qurt_mq_attr *attr, unsigned int flags); + +/**@ingroup qurt_mq_create + Create a message queue with the provided name and attributes. + The calling process becomes the owner of the queue. + Name of the message queue is limited to 16 characters including the NULL terminator. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue identifier if + the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] attr Pointer to the initialized message queue attribute + structure that specifies the attributes of the created message queue. + + @return + #QURT_EOK Message queue created. \n + #QURT_EINVALID Invalid arguments. \n + #QURT_ENOSPC Maximum number of queues in the system is exceeded. + + @dependencies + None. +*/ +int qurt_mq_create(qurt_mqd_t *mqd, const char *name, struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_open + Opens a message queue connection between a process and a created message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue + identifier if the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] flags Flag that contains the properties that define the behavior of message queue connection. + Permissions:\n + #QURT_PERM_READ \n + #QURT_PERM_WRITE \n + #QURT_PERM_READ | QURT_PERM_WRITE @tablebulletend + Default is QURT_PERM_READ | QURT_PERM_WRITE, explicit permission is not implemented \n + Cardinality: \n + #QURT_MQ_CARDINALITY_PTP (default) \n + #QURT_MQ_CARDINALITY_MTO (not implemented) \n + Block suspend thread until the message queue with the apecified name is created. \n + Scope: security boundary to which the message queue and its users are constrained. + Block suspend thread until the message queue with the apecified name is created. \n + It is coupled with process privilege level/scope.\n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED @tablebulletend + + @return + QURT_EOK -- Message queue connection successfully opened \n + QURT_EFAILED -- Message queue connection failed , if non-blocking message queue \n + QURT_ENOTALLOWED -- Open failed due to security scope mismatch + + @dependencies + None. +*/ +int qurt_mq_open (qurt_mqd_t *mqd, const char *name, qurt_mq_flags_t flags); + +/**@ingroup qurt_mq_send + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send shall resume that thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] msg_len Length of the message buffer in bytes. + + @return + #QURT_EOK Message queue send was successful.\n + #QURT_EMSGSIZE Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED Send failed due to security scope mismatch. + + @dependencies + None. +*/ +int qurt_mq_send(qurt_mqd_t mqd, const char *msg_ptr, size_t msg_len); + +/**@ingroup qurt_mq_send_timed + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message or until timeout is reached. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_send_timed shall return #QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] duration Interval (in microseconds) that the duration value must be + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in] msg_len Length of message buffer in bytes. + + @return + #QURT_EOK -- Message queue send was successful. \n + #QURT_EMSGSIZE -- Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED -- Send failed due to security scope mismatch \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. +*/ +int qurt_mq_send_timed(qurt_mqd_t mqd, const char *msg_ptr, unsigned long long int duration, size_t msg_len); + + /**@ingroup qurt_mq_recv + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue. \n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv shall resume the thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in,out] msg_len Pointer to the length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID Message pointer or msg_len ptr are NULL. \n + #QURT_EBADR Message queue descriptior (mqd) is invalid. \n + #QURT_EBADF Sender closed the message queue. + + @dependencies + None. +*/ +int qurt_mq_recv(qurt_mqd_t mqd, unsigned char *msg_ptr, size_t *msg_len); + + /**@ingroup qurt_mq_recv_timed + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue or until timeout is reached.\n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_recv_timed shall return QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in] duration Interval (in microseconds) that the duration value must be; + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in,out] msg_len Pointer to length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID -- Message ptr or msg_len ptr are NULL. \n + #QURT_EBADR -- Message queue descriptior (mqd) is invalid.\n + #QURT_EBADF -- Sender closed the message queue. \n + #QURT_ETIMEDOUT -- Timeout. + + @dependencies + None. +*/ +int qurt_mq_recv_timed(qurt_mqd_t mqd, unsigned char *msg_ptr, unsigned long long int duration, size_t *msg_len); + + /**@ingroup qurt_mq_close + Closes the message queue and disassociates the calling process (client) from the message queue + under this descriptor. Marks the queue as closed for the receiver. + This function is expected to be called from the client side. If called + from the server side, the function reduces to no-op and returns success. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue close was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_close(qurt_mqd_t mqd); + + /**@ingroup qurt_mq_destroy + Destroys the message queue. This function ought to be + called from the process that called qurt_mq_create(). + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue destroy was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_destroy(qurt_mqd_t mqd); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif //QURT_MQ_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mutex.h new file mode 100755 index 0000000000000..4ad6b270cdde6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_mutex.h @@ -0,0 +1,211 @@ +#ifndef QURT_MUTEX_H +#define QURT_MUTEX_H +/** + @file qurt_mutex.h + @brief Prototypes of mutex API. + This is mostly a user space mutex, but calls the + kernel to block if the mutex is taken. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT mutex type. + + Both non-recursive mutex lock and unlock, and recursive + mutex lock and unlock can be applied to this type. + */ +typedef union qurt_mutex_aligned8{ + /** @cond */ + struct { + unsigned int holder; + unsigned int count; + unsigned int queue; + unsigned int wait_count; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_mutex_t; +/** @} */ /* end_addtogroup mutex_types */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* @addtogroup mutex_const_macros +@{ */ +#define MUTEX_MAGIC 0xfe /**< */ +#define QURTK_FUTEX_FREE_MAGIC 0x1F // 11111 /**< */ +#define QURT_MUTEX_INIT {{MUTEX_MAGIC, 0, QURTK_FUTEX_FREE_MAGIC,0}} /**< Suitable as an initializer for a + variable of type qurt_mutex_t. */ +/* @} */ /* end_addtogroup mutex_const_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mutex_init + Initializes a mutex object. + The mutex is initially unlocked. + + @note1hang Each mutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_mutex_destroy() + when this object is not used anymore + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the mutex object. Returns the initialized object. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_destroy + Destroys the specified mutex. + + @note1hang Mutexes must be destroyed when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Mutexes must not be destroyed while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_lock + Locks the specified mutex. + If a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. + + @note1hang A thread is suspended indefinitely if it locks a mutex that it has already + locked. Avoid this by using recursive mutexes (Section @xref{dox:recursive_mutexes}). + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_lock(qurt_mutex_t *lock); /* blocking */ + +/**@ingroup func_qurt_mutex_lock_timed + Locks the specified mutex. + When a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + When a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. If the duration of suspension exceeds the timeout duration, wait is + terminated and no access to mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object; specifies the mutex to lock. + @param[in] duration Interval (in microseconds) that the duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_mutex_lock_timed (qurt_mutex_t * lock, unsigned long long int duration); + +/**@ingroup func_qurt_mutex_unlock + Unlocks the specified mutex. \n + More than one thread can be suspended on a mutex. When the mutex is unlocked, only the + highest-priority thread waiting on the mutex is awakened. If the awakened thread has + higher priority than the current thread, a context switch occurs. + + @note1hang The behavior of QuRT is undefined if a thread unlocks a mutex it did not first + lock. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to unlock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_unlock(qurt_mutex_t *lock); /* unlock */ + +/**@ingroup func_qurt_mutex_try_lock + @xreflabel{hdr:qurt_mutex_try_lock} + Attempts to lock the specified mutex. + If a thread performs a try_lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + @note1hang If a thread performs a try_lock operation on a mutex that it has already locked + or is in use by another thread, qurt_mutex_try_lock immediately returns with a + nonzero result value. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_mutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_os_services.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_os_services.h new file mode 100755 index 0000000000000..cbc4c239e9620 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_os_services.h @@ -0,0 +1,24 @@ +/*============================================================================= + + qurt_os_services.c + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ + +#define QURT_OS_SERVICE_THREAD "/os/thread" /**< Thread service */ +#define QURT_OS_SERVICE_FS_HUB "/os/fs_hub" /**< file-system hub */ +#define QURT_OS_SERVICE_CALLBACK "/os/callback" /**< QDI callback service */ +#define QURT_OS_SERVICE_INTERRUPTS "/os/interrupt" /**< Interrupt service */ +#define QURT_OS_SERVICE_PROXY "/os/proxy" /**< QDI proxy serice */ +#define QURT_OS_SERVICE_MEMORY "/os/memory" /**< Memory management service */ +#define QURT_OS_SERVICE_MEMPOOL "/os/mempool" /**< Pool management service */ +#define QURT_OS_SERVICE_PROCESS "/os/process" /**< Process management service */ +#define QURT_OS_SERVICE_MMAP "/os/mem_mapper" /**< mmapper service */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex.h new file mode 100755 index 0000000000000..61aee5cba7ce8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_PIMUTEX_H +#define QURT_PIMUTEX_H 1 +/** + @file qurt_pimutex.h + @brief Prototypes of qurt_pimutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pimutex_init + Initializes a priority inheritance mutex object. + The priority inheritance mutex is initially unlocked. + + This function works the same as qurt_mutex_init(). + + @note1hang Each pimutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_pimutex_destroy() + when this object is not used anymore + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the priority inheritance mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_destroy + Destroys the specified priority inheritance mutex. + + @note1hang Priority inheritance mutexes must be destroyed when they are no longer in + use. Failure to do this causes resource leaks in the QuRT kernel.\n + @note1cont Priority inheritance mutexes must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_lock + Requests access to a shared resources. If a thread performs a lock operation on a mutex + that is not in use, the thread gains access to the shared resource that the mutex protects, + and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + If a thread is suspended on a priority inheritance mutex, and the priority of the suspended + thread is higher than the priority of the thread that has locked the mutex, the thread + with the mutex acquires the higher priority of the suspended thread. The locker thread blocks + until the lock is available. + + @note1hang A thread is not suspended if it locks a priority inheritance mutex that it has + already locked . However, the mutex does not become available to other + threads until the thread performs a balanced number of unlocks on the mutex.\n + @note1cont When multiple threads compete for a mutex, the lock operation for a priority + inheritance mutex is slower than it is for a recursive mutex. + In particular, it is about 10 times slower when the mutex is available for locking, + and slower (with greatly varying times) when the mutex is already locked. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_lock(qurt_mutex_t *lock); + + +/**@ingroup func_qurt_pimutex_lock_timed + Locks a priority inheritance mutex with timeout. + + A thread can lock a priority inheritance mutex for multiple times. The mutex is not + available to other threads until the thread performs the same number of mutex unlock + operations. + + If a thread performs a lock operation on a mutex that is already locked by another thread, + the thread is moved to waiting state. When the mutex becomes available again (because the + other thread has unlocked the mutex), the thread is awakened and tries to lock the mutex. + + If a thread is waiting on a priority inheritance mutex, and the priority of the waiting thread + is higher than the priority of the thread that has locked the mutex, the priority of the thread + that has locked the mutex is raised to the same priority of the waiting thread. + + If the duration of waiting exceeds the timeout duration, the waiting is terminated, and + the function returns QURT_ETIMEDOUT as a failure of the mutex lock. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to lock. + @param[in] duration Duration (in microseconds) to wait. The duration value must be between + #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + #QURT_EINVALID -- Duration is out of range + + @dependencies + None. + + */ +int qurt_pimutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + + +/**@ingroup func_qurt_pimutex_unlock + Releases access to a shared resource; unlocks the specified priority inheritance mutex. \n + More than one thread can be suspended on a priority inheritance mutex. When the mutex + is unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + When a thread unlocks a priority inheritance mutex, its thread priority is restored to its + original value from any higher priority value that it acquired from another thread + suspended on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_try_lock + Request access to a shared resource (without suspend). Attempts to lock the specified priority inheritance mutex.\n + If a thread performs a try_lock operation on a priority inheritance mutex that is not in + use, the thread gains access to the shared resource that is protected by the mutex, and + continues executing. + If a thread performs a try_lock operation on a priority inheritance mutex that is already + in use by another thread, qurt_pimutex_try_lock immediately returns with a + nonzero result value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_pimutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex2.h new file mode 100755 index 0000000000000..b809f163cbfd2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pimutex2.h @@ -0,0 +1,162 @@ +#ifndef QURT_PIMUTEX2_H +#define QURT_PIMUTEX2_H +/** + @file qurt_pimutex2.h + @brief Prototypes of pimutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_pimutex2_init + Initializes a recursive mutex object. + + @deprecated use #qurt_pimutex_init instead. + + The recursive mutex is initially unlocked. + + Objects of type pimutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_destroy + + @deprecated use #qurt_pimutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1cont Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code should destroy an pimutex2 object prior to + deallocating it; calling qurt_pimutex2_destroy() before deallocating it ensures + that all qurt_pimutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_lock + + @deprecated use #qurt_pimutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not being used, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing. + + If a thread performs a lock operation on a recursive mutex that is already being used by + another thread, the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_unlock + + @deprecated use #qurt_pimutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_pimutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_pimutex2_lock(). If a call to qurt_pimutex2_lock() would + succeed immediately, this function behaves similarly, and returns 0 for success. + If a call to qurt_pimutex2_lock() would not succeed immediately, this function has + no effect and returns non-zero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_pimutex2_try_lock(qurt_rmutex2_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pipe.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pipe.h new file mode 100755 index 0000000000000..6bdaa044f8640 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pipe.h @@ -0,0 +1,479 @@ +#ifndef QURT_PIPE_H +#define QURT_PIPE_H +/** + @file qurt_pipe.h + @brief Prototypes of the pipe interface API + This is a pipe or message queue + It blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup pipe_types +@{ */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_PIPE_MAGIC 0xF1FEF1FE /**< Magic. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_RAM 0 /**< RAM. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_TCM 1 /**< TCM. */ + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** QuRT pipe data values type. */ +typedef unsigned long long int qurt_pipe_data_t; + +/** QuRT pipe type.*/ +typedef struct { + /** @cond */ + qurt_mutex_t pipe_lock; + qurt_sem_t senders; + qurt_sem_t receiver; + unsigned int size; + unsigned int sendidx; + unsigned int recvidx; + void (*lock_func)(qurt_mutex_t *); + void (*unlock_func)(qurt_mutex_t *); + int (*try_lock_func)(qurt_mutex_t *); + void (*destroy_lock_func)(qurt_mutex_t *); + unsigned int magic; + qurt_pipe_data_t *data; + /** @endcond */ +} qurt_pipe_t; + +/** QuRT pipe attributes type. */ +typedef struct { + /** @cond */ + qurt_pipe_data_t *buffer; + unsigned int elements; + unsigned char mem_partition; + /** @endcond */ +} qurt_pipe_attr_t; + +/** @} */ /* end_addtogroup pipe_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pipe_attr_init + @xreflabel{hdr:qurt_pipe_attr_init} + Initializes the structure that sets the pipe attributes when a pipe is created. + + After an attribute structure is initialized, the individual attributes in the structure are + explicitly set using the pipe attribute operations. + + The attribute structure is assigned the following default values: \n + - buffer -- 0 \n + - elements -- 0 \n + - mem_partition -- #QURT_PIPE_ATTR_MEM_PARTITION_RAM + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_init(qurt_pipe_attr_t *attr) +{ + attr->buffer = NULL; + attr->elements = 0; + attr->mem_partition = QURT_PIPE_ATTR_MEM_PARTITION_RAM; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer + @xreflabel{sec:qurt_pipe_attr_set_buffer} + Sets the pipe buffer address attribute.\n + Specifies the base address of the memory area to use for the data buffer of a pipe. + + The base address and size (Section @xref{sec:qurt_pipe_attr_set_elements}) specify the + memory area used as a pipe data buffer. The user is responsible for allocating the + memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t \n + #qurt_pipe_data_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] buffer Pointer to the buffer base address. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer(qurt_pipe_attr_t *attr, qurt_pipe_data_t *buffer) +{ + attr->buffer = buffer; +} + +/**@ingroup func_qurt_pipe_attr_set_elements + @xreflabel{sec:qurt_pipe_attr_set_elements} + Specifies the length of the memory area to use for the data buffer of a pipe. + + The length is expressed in terms of the number of 64-bit data elements that + can be stored in the buffer. + + The base address (Section @xref{sec:qurt_pipe_attr_set_buffer}) and size specify + the memory area used as a pipe data buffer. The user is responsible for + allocating the memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] elements Pipe length (64-bit elements). + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_elements(qurt_pipe_attr_t *attr, unsigned int elements) +{ + attr->elements = elements; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer_partition + @xreflabel{sec:qurt_pipe_attr_set_buffer_partition} + Specifies the memory type where a pipe's buffer is allocated. + Allocate pipes in RAM or TCM/LPM. + + @note1hang If a pipe is specified as allocated in TCM/LPM, it must be created + with the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] mem_partition Pipe memory partition. Values: \n + - #QURT_PIPE_ATTR_MEM_PARTITION_RAM -- Pipe resides in RAM \n + - #QURT_PIPE_ATTR_MEM_PARTITION_TCM -- Pipe resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer_partition(qurt_pipe_attr_t *attr, unsigned char mem_partition) +{ + attr->mem_partition = mem_partition; +} + +/**@ingroup func_qurt_pipe_create + Creates a pipe.\n + Allocates a pipe object and its associated data buffer, and initializes the pipe object. + + @note1hang The buffer address and size stored in the attribute structure specify how the + pipe data buffer is allocated. + + @note1cont If a pipe is specified as allocated in TCM/LPM, it must be created + using the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the created pipe object. + @param[in] attr Pointer to the attribute structure used to create the pipe. + + @return + #QURT_EOK -- Pipe created. \n + #QURT_EFAILED -- Pipe not created. \n + #QURT_ENOTALLOWED -- Pipe cannot be created in TCM/LPM. + + @dependencies + None. + */ +int qurt_pipe_create(qurt_pipe_t **pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_init + Initializes a pipe object using an existing data buffer. + + @note1hang The buffer address and size stored in the attribute structure must + specify a data buffer that the user has already allocated. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the pipe object to initialize. + @param[in] attr Pointer to the pipe attribute structure used to initialize the pipe. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Failure. + + @dependencies + None. + */ +int qurt_pipe_init(qurt_pipe_t *pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_destroy + @xreflabel{sec:qurt_pipe_destroy} + Destroys the specified pipe. + + @note1hang Pipes must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel. + Pipes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_destroy(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_delete + Deletes the pipe.\n + Destroys the specified pipe (Section @xref{sec:qurt_pipe_destroy}) and deallocates the pipe object and its + associated data buffer. + + @note1hang Delete pipes only if they were created using qurt_pipe_create + (and not qurt_pipe_init). Otherwise the behavior of QuRT is undefined. \n + @note1cont Pipes must be deleted when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Pipes must not be deleted while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_delete(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_send + Writes a data item to the specified pipe. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + None. + + @dependencies + None. +*/ +void qurt_pipe_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_receive + Reads a data item from the specified pipe. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + Integer containing the 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_receive(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_try_send + Writes a data item to the specified pipe (without suspending the thread if the pipe is full).\n + + If a thread writes to a full pipe, the operation returns immediately with success set to -1. + Otherwise, success is always set to 0 to indicate a successful write operation. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + 0 -- Success. \n + -1 -- Failure (pipe full). + + @dependencies + None. +*/ +int qurt_pipe_try_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_try_receive + Reads a data item from the specified pipe (without suspending the thread if the pipe is + empty).\n + If a thread reads from an empty pipe, the operation returns immediately with success set + to -1. Otherwise, success is always set to 0 to indicate a successful read operation.\n + + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[out] success Pointer to the operation status result. + + @return + Integer containing a 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_try_receive(qurt_pipe_t *pipe, int *success); + +/**@ingroup func_qurt_pipe_receive_cancellable + Reads a data item from the specified pipe (with suspend), cancellable. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + The operation is cancelled if the user process of the calling thread is killed, + or if the calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] result Pointer to the integer containing the 64-bit data item from pipe. + + @return + #QURT_EOK -- Receive completed. \n + #QURT_ECANCEL -- Receive canceled. \n + #QURT_EDESTROY -- Receive destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_receive_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t *result); + +/**@ingroup func_qurt_pipe_send_cancellable + @xreflabel{hdr:qurt_pipe_send_cancellable} + Writes a data item to the specified pipe (with suspend), cancellable. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + The operation is canceled if the user process of the calling thread is killed, or if the + calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] data Data item to write. + + @return + #QURT_EOK -- Send completed. \n + #QURT_ECANCEL -- Send canceled. \n + #QURT_EDESTROY -- Send destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_send_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_is_empty + Returns a value indicating whether the specified pipe contains any data. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + 1 -- Pipe contains no data. \n + 0 -- Pipe contains data. + + @dependencies + None. +*/ +int qurt_pipe_is_empty(qurt_pipe_t *pipe); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIPE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmem_manager.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmem_manager.h new file mode 100755 index 0000000000000..8c8da985228b9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmem_manager.h @@ -0,0 +1,82 @@ +#ifndef QURT_PMEM_MANAGER_H +#define QURT_PMEM_MANAGER_H +/** + @file qurt_pmem_manager.h + Prototypes of kernel physical memory manager APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* physical memory API return error code */ +#define QURT_PMEM_SUCCESS 0 +#define QURT_PMEM_NO_PRIV 1 +#define QURT_PMEM_RETRY 2 +#define QURT_PMEM_OVERLAP 3 +#define QURT_PMEM_NOT_EXIST 4 +#define QURT_PMEM_INIT_FAILURE 5 +#define QURT_PMEM_OUTSTANDING_MAPPING 6 +#define QURT_PMEM_GENERIC_FAILURE 7 +#define QURT_PMEM_ENTRY_FOUND 8 +#define QURT_PMEM_REACH_END 9 +#define QURT_PMEM_UNCLAIMED 10 +#define QURT_PMEM_ALREADY_CLAIMED 11 + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_pmem_acquire + Acquire the ownership of a specific physical memory region. + + @note1hang The ownership will be the caller + + @param[in] ppage Starting physical page number + @param[in] pnum Number of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_OVERLAP -- The whole or part of the range has been owned \n + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. +*/ +int qurt_pmem_acquire(unsigned int ppage, unsigned int pnum); + +/**@ingroup func_qurt_pmem_release + Release the ownership of a specific physical memory region. + + @param[in] ppage The start of physical page number + @param[in] pnum The numbers of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_NOT_EXIST -- The physical memory range is not usable. \n + #QURT_PMEM_OUTSTANDING_MAPPING -- There is outstanding mapping in this range + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. + */ +int qurt_pmem_release(unsigned int ppage, unsigned int pnum); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMEM_MANAGER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmu.h new file mode 100755 index 0000000000000..73ea8eba04abf --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_pmu.h @@ -0,0 +1,121 @@ +#ifndef QURT_PMU_H +#define QURT_PMU_H +/** + @file qurt_pmu.h + Prototypes of pipe interface API. + A pipe or message queue blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_pmu_set + Sets the value of the specified PMU register. + + @note1hang Setting PMUEVTCFG automatically clears the PMU registers PMUCNT0 + through PMUCNT3. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @param[in] reg_value Register value. + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_set (int reg_id, unsigned int reg_value); + +/**@ingroup func_qurt_pmu_get + Gets the PMU register.\n + Returns the current value of the specified PMU register. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @return + Integer -- Current value of the specified PMU register. + + @dependencies + None. + */ +unsigned int qurt_pmu_get (int reg_id); + +/**@ingroup func_qurt_pmu_enable + Enables or disables the Hexagon processor PMU. + Profiling is disabled by default. + + @note1hang Enabling profiling does not automatically reset the count registers -- this must + be done explicitly before starting event counting. + + @param[in] enable Performance monitor. Values: \n + - 0 -- Disable performance monitor \n + - 1 -- Enable performance monitor @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_enable (int enable); + +/**@ingroup func_qurt_pmu_get_pmucnt + Reads PMU counters in a single trap. + + @param[out] buf Pointer to a buffer to save values read from PMU counters. + buffer size should be at least 32 bytes to read all eight PMU counters. + + @return + #QURT_EOK -- Successful read.\n + #QURT_EFATAL -- Failure. + + @dependencies + None. + */ +int qurt_pmu_get_pmucnt (void * buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMU_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_power.h new file mode 100755 index 0000000000000..2ee4d29a73976 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_power.h @@ -0,0 +1,140 @@ +#ifndef QURT_POWER_H +#define QURT_POWER_H +/** + @file qurt_power.h + @brief Prototypes of power API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/*============================================================================= + + EDIT HISTORY FOR MODULE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + +when who what, where, why +-------- --- ------------------------------------------------------------ +03/03/11 op Add header file +12/12/12 cm (Tech Pubs) Edited/added Doxygen comments and markup. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +/**@ingroup func_qurt_power_shutdown_fail_exit + Returns from Power Collapse mode when power collapse cannot proceed. + + This function unmasks the global interrupt. This operation is used only when the thread is + recovering from a failed power collapse operation (Section @xref{sec:powerShutdownEnter}). + + @return + #QURT_EOK -- Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_fail_exit qurt_power_exit + +/**@ingroup func_qurt_power_shutdown_exit + Undoes state changes made preparing for power collapse.\n + This function unmasks the global interrupts. + + @return + #QURT_EOK --Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_exit qurt_power_exit +/**@endcond */ + +/**@ingroup func_qurt_system_ipend_get + Gets the IPEND register.\n + + @note1hang Returns the current value of the Hexagon processor IPEND register. The return value + is a mask value that identifies the individual interrupts that are pending. \n + + @note1hang The bit order of the mask value is identical to the order defined for the IPEND register. A + mask bit value of 1 indicates that the corresponding interrupt is pending, and 0 indicates that the + corresponding interrupt is not pending. \n + + @return + Return the IPEND register value. + + @dependencies + None. + */ +unsigned int qurt_system_ipend_get (void); + + +/**@ingroup func_qurt_system_vid_get + Gets the VID register. \n + + @note1hang Returns the current value of the Hexagon processor VID register. The return value is + the vector number of a second-level interrupt that has been accepted by the Hexagon + processor core.\n + + @return + Return the VID register value that is the L2 VIC interrupt number accepted by the processor. + Valid range is 0 to 1023. + + @dependencies + None. + */ +unsigned int qurt_system_vid_get(void); + +/**@ingroup func_qurt_power_shutdown_get_pcycles + Gets the number of power collapses and processor cycles for entering and exiting most recent + power collapse. + + @note1hang If no power collapse has occured yet, processor cycle numbers are zero. + + @param[out] enter_pcycles Number of processor cycles for entering most + recent power collapse. + @param[out] exit_pcycles Number of processor cycles for exiting most + recent power collapse. + @return + Zero -- No power collapses have occurred. \n + Nonzero -- Number of power collapses that have occurred since + the processor was reset. + + @dependencies + None. + */ +int qurt_power_shutdown_get_pcycles( unsigned long long *enter_pcycles, unsigned long long *exit_pcycles ); + +/**@ingroup func_qurt_system_tcm_set_size + Set size of TCM to save during full power collapse. + + @note1hang The size aligns to 32 bytes. If size passed is greater than the maximum size defined in + XML, the size is truncated to the size defined in XML. + + @param[in] new_size Size of TCM to save. + + @return + Zero -- Size successfully set \n + -1 -- Size of 0 passed + + @dependencies + None. + */ +int qurt_system_tcm_set_size(unsigned int new_size); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_POWER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_printf.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_printf.h new file mode 100755 index 0000000000000..a775d8a815918 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_printf.h @@ -0,0 +1,44 @@ +#ifndef QURT_PRINTF_H +#define QURT_PRINTF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file qurt_printf.h + Prototypes of printf API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup chapter_function_tracing +@{ */ + +int qurt_printf(const char* format, ...); + +int qurt_vprintf(const char* format, va_list args); + +/** @} */ /* end_addtogroup chapter_function_tracing */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PRINTF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_process.h new file mode 100755 index 0000000000000..0df9ddc2d4a70 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_process.h @@ -0,0 +1,995 @@ +#ifndef QURT_PROCESS_H +#define QURT_PROCESS_H +/** + @file qurt_process.h + @brief Prototypes of QuRT process control APIs. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2009-2013, 2021-2023 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_callback.h" +#include "qurt_consts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup process_types +@{ */ +#define QURT_PROCESS_ATTR_NAME_MAXLEN QURT_MAX_NAME_LEN /**< Maximum length of the process name. */ +#define QURT_PROCESS_ATTR_BIN_PATH_MAXLEN 128 /**< Maximum length of the path of binary/ELF for this process. */ +#define QURT_PROCESS_ATTR_CAP_MAXLEN 128 /**< Maximum length for a resource name. */ + +/** QuRT process capability wildcard strings */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_ALL "ALLOW_ALL" /**< Capability wild-card for full access */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_NONE "ALLOW_NONE" /**< Capability wild-card for no access */ + +/** QuRT process capability states */ +#define QURT_PROCESS_ATTR_CAP_ENABLED 0x1 /**< Capability enabled*/ +#define QURT_PROCESS_ATTR_CAP_DISABLED 0x0 /**< Capability disabled*/ + +/* QuRT process thread attributes. */ +#define QURT_PROCESS_DEFAULT_CEILING_PRIO 0 /**< Default ceiling priority of the threads in the new process. */ +#define QURT_PROCESS_DEFAULT_MAX_THREADS -1 /**< Default number of threads in the new process. + -1 indicates that the limit is set to the maximum supported by the system. */ + +/* QuRT process flags. */ +#define QURT_PROCESS_SUSPEND_ON_STARTUP (1U) /**< Suspend the new processes just before calling main(). */ +#define QURT_PROCESS_NON_SYSTEM_CRITICAL (1u << 1) /**< Starts the new process as non system-critical. */ +#define QURT_PROCESS_ISLAND_RESIDENT (1u << 2) /**< Process is island resident. */ +#define QURT_PROCESS_RESTARTABLE (1u << 3) /**< Indicates that the process is restartable */ +#define QURT_PROCESS_UNTRUSTED (1u << 7) /**< Starts the new process as unsigned process. */ + +/* QuRT process debugging session status.*/ +#define QURT_DEBUG_NOT_START 0 /**< Debug is not started. */ +#define QURT_DEBUG_START 1 /**< Debug has started. */ + +/** Process Suspend Options */ +#define QURT_PROCESS_SUSPEND_DEFAULT 0 + +/** Process Resume Options */ +#define QURT_PROCESS_RESUME_DEFAULT 0 + + +/* QuRT process types. */ +typedef enum { + QURT_PROCESS_TYPE_RESERVED, /**< Process type is reserved. \n */ + QURT_PROCESS_TYPE_KERNEL, /**< Kernel process. \n*/ + QURT_PROCESS_TYPE_SRM, /**< SRM process. \n*/ + QURT_PROCESS_TYPE_SECURE, /**< Secure process. \n*/ + QURT_PROCESS_TYPE_ROOT, /**< Root process. \n*/ + QURT_PROCESS_TYPE_USER, /**< User process. */ +}qurt_process_type_t; + +/** QuRT process callback types. */ +typedef enum { + QURT_PROCESS_DUMP_CB_ROOT, /**< Register the callback that executes in the + root process context. \n */ + QURT_PROCESS_DUMP_CB_ERROR, /**< Register the user process callback that is + called after threads in the process are frozen. \n */ + QURT_PROCESS_DUMP_CB_PRESTM, /**< Register the user process callback that is + called before threads in the process are frozen. \n*/ + QURT_PROCESS_DUMP_CB_MAX /**< Reserved for error checking. */ +}qurt_process_dump_cb_type_t; + +/** QuRT process dump attributes. */ +typedef struct _qurt_pd_dump_attr{ + /** @cond */ + unsigned int enabled; /**< Process dump is enabled. */ + const char *path; /**< Process dump path. */ + unsigned int path_len; /**< Length of process dump path. */ + /** @endcond */ +}qurt_pd_dump_attr_t; + +/** QuRT process capability resource type */ +enum qurt_process_cap_type_t { + QURT_PROCESS_CAP_TYPE_NUM_ENTRIES=0, /**< Number of entries in the capability structure*/ + QURT_PROCESS_CAP_TYPE_DRIVER=1, /**< Driver resource */ + QURT_PROCESS_CAP_TYPE_MAX /**< Maximum identifier */ +}; + +/** QuRT process capability structure */ +typedef struct _qurt_capability { + enum qurt_process_cap_type_t type; /**< Resource type */ + char name[QURT_PROCESS_ATTR_CAP_MAXLEN]; /**< Resource name*/ + unsigned long long cap; /**< Capabilities allowed for this resource */ +}qurt_capability_t; + +/** QuRT process attributes. */ +typedef struct _qurt_process_attr { + /** @cond */ + char name[QURT_PROCESS_ATTR_NAME_MAXLEN]; /**< Name of the new process. */ + char path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the binary for the new process. */ + char dtb_path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the DTB ELF for the new process. */ + int flags; /**< Flags as indicated by QuRT process flags. */ + unsigned int sw_id; /**< Software ID of the process be load. */ + unsigned sid; /**< Stream ID of the process being spawned. */ + unsigned max_threads; /**< Maximum number of threads that the new process can create. */ + unsigned short ceiling_prio; /**< Maximum priority at which threads can be + created by new process. */ + qurt_process_type_t type; /**< Process type as indicated by + #qurt_process_type_t. */ + qurt_pd_dump_attr_t dump_attr; /**< Process dump attributes for the new process + as indicated by #qurt_pd_dump_attr_t. */ + qurt_capability_t *capabilities; /**< Pointer to array of structure of type + qurt_capability_t */ + /** @endcond */ +} qurt_process_attr_t; + +/** @} */ /* end_addtogroup process_types */ + +/*============================================================================= +FUNCTIONS +=============================================================================*/ + /** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_create + Creates a process with the specified attributes, and starts the process. + + The process executes the code in the specified executable ELF file. + + @datatypes + #qurt_process_attr_t + + @param[out] attr Accepts an initialized process attribute structure, which specifies + the attributes of the created process. + + @return + Postive return value Indicates Process ID. + Negative return value Indicates any of follwoing error, + #-QURT_EPRIVILEGE -- Caller does not have privilege for this operation \n + #-QURT_EMEM -- Not enough memory to perform the operation \n + #-QURT_EFAILED -- Operation failed \n + #-QURT_ENOTALLOWED -- Operation not allowed \n + #-QURT_ENOREGISTERED -- Not registered \n + #-QURT_ENORESOURCE -- Resource exhaustion \n + #-QURT_EINVALID -- Invalid argument value + #QURT_EFATAL -- attr is NULL + + @dependencies + None. +*/ +int qurt_process_create (qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_get_id + Returns the process identifier for the current thread. + + @return + None. + + @dependencies + Process identifier for the current thread. +*/ +int qurt_process_get_id (void); +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_get_uid + Returns the user identifier for the current thread. + + @return + None. + + @dependencies + User identifier for the current thread. +*/ +int qurt_process_get_uid (void); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_init + Initializes the structure that sets the process attributes when a thread is created. + + After an attribute structure is initialized, the individual attributes in the structure can + be explicitly set using the process attribute operations. + + Table @xref{tbl:processAttrDefaults} lists the default attribute values set by the initialize + operation. + + @inputov{table_process_attribute_defaults} + + @datatypes + #qurt_process_attr_t + + @param[out] attr Pointer to the structure to initialize. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_process_attr_init (qurt_process_attr_t *attr) +{ + attr->name[0] = '\0'; + attr->path[0] = '\0'; + attr->dtb_path[0] = '\0'; + attr->flags = 0; + attr->sw_id = 0; + attr->sid = 0; + attr->max_threads = (unsigned)QURT_PROCESS_DEFAULT_MAX_THREADS; + attr->ceiling_prio = QURT_PROCESS_DEFAULT_CEILING_PRIO; + attr->type = QURT_PROCESS_TYPE_RESERVED; + attr->dump_attr.enabled = 0; + attr->dump_attr.path = NULL; + attr->dump_attr.path_len = 0; + attr->capabilities = NULL; +} + +/**@ingroup func_qurt_process_attr_set_executable + Sets the process name in the specified process attribute structure. + + Process names identify process objects that are already + loaded in memory as part of the QuRT system. + + @note1hang Process objects are incorporated into the QuRT system at build time. + + @note1hang Maximum length of name string is limited to QURT_PROCESS_ATTR_NAME_MAXLEN - 1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] name Pointer to the process name. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_executable (qurt_process_attr_t *attr, const char *name); + +/**@ingroup func_qurt_process_attr_set_binary_path + Sets the binary path for the process loading in the specified process attribute structure. + + Path specifies the binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_binary_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_dtb_path + Sets the DTB binary path for the process loading in the specified process attribute structure. + + Path specifies the DTB binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_dtb_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_flags +Sets the process properties in the specified process attribute structure. +Process properties are represented as defined symbols that map into bits +0 through 31 of the 32-bit flag value. Multiple properties are specified by OR'ing +together the individual property symbols. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] flags QURT_PROCESS_NON_SYSTEM_CRITICAL Process is considered as non system-critical. + This attribute will be used by error services, + to decide whether to kill user pd or whole subsystem. + QURT_PROCESS_ISLAND_RESIDENT Process will be marked as island resident. + QURT_PROCESS_RESTARTABLE Process will be marked as restartable. + QURT_PROCESS_UNTRUSTED Process will be marked as unsigned process. +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_flags (qurt_process_attr_t *attr, int flags) +{ + attr->flags = flags; +} +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_sid +Sets the process streamID in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sid streamID to set for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sid (qurt_process_attr_t *attr, unsigned sid) +{ + attr->sid = sid; +} +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_set_max_threads +Sets the maximum number of threads allowed in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] max_threads Maximum number of threads allowed for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_max_threads (qurt_process_attr_t *attr, unsigned max_threads) +{ + attr->max_threads = max_threads; +} + +/**@ingroup func_qurt_process_attr_set_sw_id +Sets the software ID of the process to load in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sw_id Software ID of the process, used in authentication. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sw_id(qurt_process_attr_t *attr, unsigned int sw_id) +{ + attr->sw_id = sw_id; +} + +/**@ingroup func_qurt_process_attr_set_ceiling_prio +Sets the highest thread priority allowed in the specified process attribute structure. +Refer qurt_thread.h for priority ranges. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] prio Priority. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_ceiling_prio (qurt_process_attr_t *attr, unsigned short prio) +{ + attr->ceiling_prio = prio; +} +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_dump_status +Sets the process domain dump-enabled field in the process domain dump attributes. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] enabled 1 -- Process domain dump is collected \n + 0 -- Process domain dump is not collected + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_status(qurt_process_attr_t *attr, unsigned int enabled) +{ + attr->dump_attr.enabled = enabled; +} + +/**@ingroup func_qurt_process_attr_set_dump_path +Sets the process domain dump path and type. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] path Path where the process domain dumps must be saved. +@param[in] path_len Length of the path string. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_path(qurt_process_attr_t *attr, const char *path, int path_len) +{ + attr->dump_attr.path = path; + attr->dump_attr.path_len = (unsigned int)path_len; +} + +/**@ingroup func_qurt_process_attr_set_capabilities +Sets list of capabilities available to this process. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] capabilities Pointer to array of structures of type qurt_capability_t defining + resources and capabilites + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_capabilities(qurt_process_attr_t *attr, qurt_capability_t *capabilities) +{ + attr->capabilities = capabilities; +} + +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_cmdline_get +Gets the command line string associated with the current process. +The Hexagon simulator command line arguments are retrieved using +this function as long as the call is made +in the process of the QuRT installation, and with the +requirement that the program runs in a simulation environment. + +If the function modifies the provided buffer, it zero-terminates +the string. It is possible that the function does not modify the +provided buffer, so the caller must set buf[0] to a NULL +byte before making the call. A truncated command line is returned when +the command line is longer than the provided buffer. + +@param[in] buf Pointer to a character buffer that must be filled in. +@param[in] buf_siz Size (in bytes) of the buffer pointed to by the buf argument. + +@return +None. + +@dependencies +None. +*/ +void qurt_process_cmdline_get(char *buf, unsigned buf_siz); + +/**@ingroup func_qurt_process_get_thread_count +Gets the number of threads present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of threads in the process indicated by PID, if positive value is obtained +Negative error code if failed include: + QURT_EFATAL - Invalid PID + -QURT_ENOTALLOWED - Current process doesnt have access to target process indicated by PID + +@dependencies +None. +*/ +int qurt_process_get_thread_count(unsigned int pid); + +/**@ingroup func_qurt_process_get_thread_ids +Gets the thread IDs for a process indicated by PID. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a user passed buffer that must be filled in with thread IDs. +@param[in] thread_num Number of thread IDs requested. + +@return +#QURT_EOK - Success +#QURT_EFATAL - Failed, ptr is NULL + +@dependencies +None. + */ +int qurt_process_get_thread_ids(unsigned int pid, unsigned int *ptr, unsigned thread_num); +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_dump_get_mem_mappings_count +Gets the number of mappings present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of mappings for the process indicated by the PID. + +@dependencies +None. +*/ +int qurt_process_dump_get_mem_mappings_count(unsigned int pid); + +/**@ingroup func_qurt_process_dump_get_mappings +Gets the mappings for a specified PID. + +@note1hang This API skips device type mappings or mappings created by setting the #QURT_PERM_NODUMP attribute. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a buffer that must be filled in with mappings. +@param[in] count Count of mappings requested. + +@return +Number of mappings filled in the buffer passed by the user. + +@dependencies +None. +*/ +int qurt_process_dump_get_mappings(unsigned int pid, unsigned int *ptr, unsigned count); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_get +Gets the attributes of the process with which it was created. + +@datatypes +#qurt_process_attr_t + +@param[in] pid PID of the process for which the information is required. +@param[in,out] attr Pointer to the user allocated attribute structure. + +@return +#QURT_EOK - Success +#QURT_INVALID - Invalid PID +#QURT_EFATAL - attr is NULL + +@dependencies +None. +*/ +int qurt_process_attr_get(unsigned int pid, qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_dump_register_cb +Registers the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information. +@param[in] type Callback type; these callbacks are called in the context of the user process domain: \n + #QURT_PROCESS_DUMP_CB_PRESTM -- Before threads of the exiting process are frozen. \n + #QURT_PROCESS_DUMP_CB_ERROR -- After threads are frozen and captured. \n + #QURT_PROCESS_DUMP_CB_ROOT -- After threads are frozen and captured, and CB_ERROR type of callbacks + are called. +@param[in] priority Priority. + +@return +#QURT_EOK -- Success \n +Other values -- Failure + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_register_cb(qurt_cb_data_t *cb_data, qurt_process_dump_cb_type_t type, unsigned short priority); + +/**@ingroup func_qurt_process_dump_deregister_cb +Deregisters the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information to deregister. +@param[in] type Callback type. + +@return +#QURT_EOK -- Success.\n +Other values -- Failure. + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_deregister_cb(qurt_cb_data_t *cb_data,qurt_process_dump_cb_type_t type); + +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_set_rtld_debug +Sets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in] address rtld_debug address. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_set_rtld_debug(unsigned int pid,unsigned int address); + +/**@ingroup func_qurt_process_get_rtld_debug +Gets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in,out] address Pointer to the user passed address in which the rtld_debug address must be returned. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_get_rtld_debug(unsigned int pid,unsigned int *address); +/** @endcond */ +/**@ingroup func_qurt_process_exit +Exits the current user process with an exit code. + +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exit(int exitcode); + +/**@ingroup func_qurt_process_kill +Kills the process represented by the PID with the exit code. + +@param[in] pid PID of the process to kill. +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_kill(int pid, int exitcode); + + +/**@ingroup func_qurt_debugger_register_process +Registers the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. +@param[in] adr Address. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_register_process(int pid, unsigned int adr); + + +/**@ingroup func_qurt_debugger_deregister_process +Deregister the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_deregister_process(int pid); + +/**@ingroup func_qurt_process_exec_callback +Executes callbacks in the user process as indicated by the client_handle argument. + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] callback_fn Callback function to execute. +@param[in] stack_base Stack address to use. +@param[in] stack_size Stack size. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exec_callback(int client_handle, + unsigned callback_fn, + unsigned stack_base, + unsigned stack_size); + +/**@ingroup func_qurt_process_get_pid +Gets the process ID of the process that the client_handle argument represents. + +@note1hang This API is not supported for unsigned PD, For unsigned PD use qurt_process_get_id() + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] pid Pointer to the address to store the PID. + +@return +#QURT_EOK -- Success +#QURT_EFATAL -- pid pointer passed as NULL + +@dependencies +None. +*/ +int qurt_process_get_pid(int client_handle, int * pid); + +/**@ingroup func_qurt_process_get_dm_status +Gets the debugging session status on the process represented by the pid argument. + +@param[in] pid Process ID +@param[in,out] status Address to store the status: \n + #QURT_DEBUG_NOT_START \n + #QURT_DEBUG_START + +@return +#QURT_EOK - Success \n +#QURT_EINVALID - Error + +@dependencies +None. +*/ +int qurt_process_get_dm_status( unsigned int pid, unsigned int *status); + + +/**@ingroup func_qurt_process_suspend_threads + Suspends user threads in a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in GuestOS/root process. + After the user threads in the target user process are suspended, they cannot be scheduled to run by the kernel + until they resume later. + + This function has one optional argument with one default option. + #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + This function call is a synchronous call, the function returns after the relevant threads are + completely suspended. + + If some user threads in the target user process are set as non-suspendable, this function call does + not suspend these threads. + + If the target user process is already suspended, this function call returns success as the + confirmation on the user process suspending. + + QuRT debugger monitor threads in the target user process are non-suspendable, this function call does + not suspend the threads. + + If the target user process is a secure user process, or a CPZ process, this function call returns error + without suspending the target user process. + + If a user thread in the target user process runs in the guest OS/root process via a QDI call, this function call + does not suspend the thread in the guest OS, but instead marks the thread as pending-suspend. The thread is suspended + when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success while the user thread can be running in GuestOS, and is suspended + when exiting the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Dfault option #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid process_id input \n + #QURT_ENOTALLOWED -- Failure because the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_suspend_threads (unsigned int process_id, unsigned int option); + + +/**@ingroup func_qurt_process_resume_threads + Resumes a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in the guest OS/root process. + After the user threads in the target user process resume, the kernel scheduler + can schedule the user threads to run based on their thread priorities. + + This function has an optional argument, #QURT_PROCESS_RESUME_DEFAULT, which + resumes user threads in the target user process. + + This is an asynchronous function, it returns after the kernel moves the user thread from + suspended state to runnable state. The threads are scheduled to run based on their thread priorities. + + This function call does not resume threads in the target user process that have been set as non-resumable. + + If the target user process have already resumed, this function call confirms that the user process resumes + by returning success. + + If the target user process is a secure user process or a CPZ process, this function call returns an error without + resuming operation. + + If user threads in the target user process run in the guest OS/root process via QDI call, this function + call clears the mark of suspend-pending on these threads, so that the threads are be suspended when it exits + the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Default option #QURT_PROCESS_RESUME_DEFAULT resumes user threads in the target user process. + + @return + #QURT_EOK -- Success + #QURT_EINVALID -- Failure because of invalid process_id input. + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_resume_threads (unsigned int process_id, unsigned int option); + +/**@ingroup func_qurt_process_vtcm_window_set + Set a VTCM access window for a process. + The caller thread needs to be in SRM process. + + This is an synchronous function, it ensures all running threads of the process have the requested + window in effect.The requested view for all non-running thread will take in effect when they get + scheduled. + + @param[in] pid Process identifier. + @param[in] enable QURT_VTCM_WINDOW_ENABLE enforces VTCM access window defined by high and low offset. + QURT_VTCM_WINDOW_DISABLE high and low offset is ignored and VTCM access is fully + disabled for the process. + @param[in] high_offset Specifies the high window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT restore high offset to reset value. + @param[in] low_offset Specifies the low window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT restore low offset to reset value. + + @note1hang + when high_offset is set to QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT and low offset is set as + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT full VTCM range is accessible. Access to VTCM is controlled + via MMU mapping for the process. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_set(int pid, unsigned int enable, unsigned int high_offset, unsigned int low_offset); + +/**@ingroup func_qurt_process_vtcm_window_get + Get the VTCM window for a process. + The caller thread needs to be in SRM process. + + + @param[in] pid Process identifier. + @param[out] enable address to store enable status if set + @param[out] high_offset address to return high window offset, in 4K increments, from the base address of the VTCM + @param[out] low_offset address to return low window offset, in 4K increments, from the base address of the VTCM. + + @note1hang + User must first check the value of enable returned before checking high and low offset. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_get(int pid, unsigned int *enable, unsigned int *high_offset, unsigned int *low_offset); + +/**@ingroup func_qurt_process_set_group_config + Enable thread groups in the process with the ceiling priorities setup + + @param[in] process_id Process identifier. + @param[in] group_bitmask 64-bit mask of active thread groups + @param[in] ceiling_priorities array of ceiling priorities for thread group + + @note1hang + This API can only be called by root PD and can only be called once for each process, otherwise it will be + rejected. Group 0 must be enabled in group_bitmask, otherwise QuRT will return error. After this API, all + exisiting threads will be moved to group 0, and if there is any thread's priority higher than ceiling + priority of group 0, it will be lowered to the ceiling value. + Examples 1: + group_bitmask = 0xD7; //'b11010111 + ceiling_priorities[] = {100, 128, 200, 0, 196, 0, 240, 20}; // 0 - does not care + Exmaples 2: + group_mask = 0x5; //'b101 + ceiling_priorities[] = {240, 0, 20}; // 0 - does not care + + + @return + #QURT_EOK -- Success. + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_ENOTALLOWED -- The group has been configured already. + + @dependencies + None. + */ +int qurt_process_set_group_config(unsigned int process_id, unsigned long long group_bitmask, + unsigned char *ceiling_priorities); + + +/**@ingroup func_qurt_process_stid_set + Set the specified stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[in] stid stid to be set + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) if stid needs to set at a process level. + All threads within a process that has default stid (QURT_STID_DEFAULT) will inherit the stid set for a process. + When a non-default group_id is specified, the stid is set only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_set(unsigned int pid, unsigned int group_id , unsigned int stid); + +/**@ingroup func_qurt_process_stid_get + Get the stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[out] Pointer to a variable to return stid + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) to return process-level stid. + When a non-default group_id is specified, the stid is returned only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_get(unsigned int pid, unsigned int group_id , unsigned int *stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_profile.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_profile.h new file mode 100755 index 0000000000000..2a50c461440f6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_profile.h @@ -0,0 +1,98 @@ +#ifndef QURT_PROFILE_H +#define QURT_PROFILE_H +/** + @file qurt_profile.h + QuRT profiling support. + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup profiling_macros +@{ */ +#define QURT_PROFILE_DISABLE 0 /**< Disable profiling. */ +#define QURT_PROFILE_ENABLE 1 /**< Enable profiling. */ + +typedef unsigned int qurt_profile_param_t; + +#define QURT_PROFILE_PARAM_THREAD_READY_TIME 0U /**< Profile thread ready time. */ + +/** @} */ /* end_addtogroup profiling_macros */ + +/** @addtogroup profiling_types + @{ */ +/** Profiling results. */ +typedef union +{ + /** Result associated with #QURT_PROFILE_PARAM_THREAD_READY_TIME. */ + struct + { + unsigned int ticks; /**< Cumulative ticks the thread was ready. */ + } thread_ready_time; + +} qurt_profile_result_t; +/** @} */ /* end_addtogroup profiling_types */ + +/**@ingroup func_qurt_profile_enable2 + * Starts profiling of a specific parameter on a specific thread (as applicable). + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of the thread (if applicable) for which the specified + * paramter must be profiled. + * @param[in] enable #QURT_PROFILE_DISABLE -- disable \n #QURT_PROFILE_ENABLE -- + * enable + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EALREADY -- Measurement already in progress or already stopped \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_enable2 ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + int enable +); + +/**@ingroup func_qurt_profile_get + * Gets the value of the profiling parameter that was previously enabled. + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of thread (if applicable) for which the specified + * profiling paramter must be retrieved. + * @param [out] result Profiling result associated with the parameter for the specified + * thread (if applicable). + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EFAILED -- Operation failed; profiling was not enabled \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_get ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + qurt_profile_result_t * result +); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ptrace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ptrace.h new file mode 100755 index 0000000000000..622304dd92865 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_ptrace.h @@ -0,0 +1,37 @@ +/*============================================================================= + + qurt_ptrace.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SYS_PTRACE_H__ +#define __SYS_PTRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum __ptrace_request +{ + /** + Indicates that the process making this request is requesting to be traced. + */ + PTRACE_TRACEME = 0, + PTRACE_EXT_IS_DEBUG_PERMITTED = 500 +}; + +long ptrace(enum __ptrace_request request, unsigned int pid, void*addr, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_PTRACE_H__ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi.h new file mode 100755 index 0000000000000..705408e5cfc6f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi.h @@ -0,0 +1,185 @@ +#ifndef QDI_H +#define QDI_H + +/** + @file qurt_qdi.h + @brief Prototypes of QuRT Driver Invocation API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_qdi_open + Opens the specified driver for subsequent operations. + qurt_qdi_open() is the primary mechanism by which a driver user can + obtain a QDI handle. The user provides the name of the driver to the + qurt_qdi_open call, and gets back a handle referencing + the named driver. \n + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_open function prototype is not actually defined as a varargs. + + + @param[in] p Driver name. + @param[in] ... Up to nine additional device-specific arguments can be passed as parameters, + and should follow the POSIX open() convention. \n + - flags -- Optional second parameter (POSIX flags), the handle + access requested (read-only, write-only, or read-write, + for instance) and other flags such as whether the call + should create a new device or only open an existing + device. \n + - mode -- Optional third parameter (POSIX mode); permissions to + configure when a new device is created. @tablebulletend + + @return + Negative value -- Error. \n + Non-negative value -- Success, this result value serves as a handle to the + opened driver. + @dependencies + None. + */ +// int qurt_qdi_open(); +#define qurt_qdi_open(p,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN,(p),##__VA_ARGS__) + +#define qurt_qdi_open_dt(p,q,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN_FROM_DT,(p),(q),##__VA_ARGS__) + +/**@ingroup func_qurt_qdi_handle_invoke + Performs a generic driver operation, which (depending on the specified operation) can be + either be one of the predefined operations listed in @xhyperref{tbl:functionMapping,QDI function mapping} + or a driver-specific operation. + The user provides a QDI handle and an integer + method number, along with 0 to 8 optional 32-bit arguments. + The device driver invocation function is invoked with the + same method number and 0 to 8 optional arguments. The + return value from the invocation function is passed back to + the user as the return value of qurt_qdi_handle_invoke. + + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_handle_invoke() function prototype is not actually defined as a + varargs function (and would break if it were defined this way). + + @param[in] h Driver handle. + @param[in] m Integer number for the operation to perform. + @param[in] ... Up to eight optional arguments can be passed to the device driver as operation-specific parameters: \n + arg1 -- First parameter \n + arg2 -- Second parameter \n + arg3 -- Third parameter \n + arg4 -- Fourth parameter \n + arg5 -- Fifth parameter \n + arg6 -- Sixth parameter \n + arg7 -- Seventh parameter \n + arg8 -- Eighth parameter + + @return + Integer value defined by the device driver. \n + -1 -- Error. + + @dependencies + None. + */ +// int qurt_qdi_handle_invoke(); +#define qurt_qdi_handle_invoke(h,m,...) \ + _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__) +#define _QDMHI3(a,b,c) qurt_qdi_qhi3(0,b,c) +#define _QDMHI4(a,b,c,d) qurt_qdi_qhi4(0,b,c,(int)(d)) +#define _QDMHI5(a,b,c,d,e) qurt_qdi_qhi5(0,b,c,(int)(d),(int)(e)) +#define _QDMHI6(a,b,c,d,e,f) qurt_qdi_qhi6(0,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMHI7(a,b,c,d,e,f,g) qurt_qdi_qhi7(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMHI8(a,b,c,d,e,f,g,h) qurt_qdi_qhi8(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMHI9(a,b,c,d,e,f,g,h,i) qurt_qdi_qhi9(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMHI10(a,b,c,d,e,f,g,h,i,j) qurt_qdi_qhi10(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMHI11(a,b,c,d,e,f,g,h,i,j,k) qurt_qdi_qhi11(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMHI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_qdi_qhi12(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) +int qurt_qdi_qhi3(int,int,int); +int qurt_qdi_qhi4(int,int,int,int); +int qurt_qdi_qhi5(int,int,int,int,int); +int qurt_qdi_qhi6(int,int,int,int,int,int); +int qurt_qdi_qhi7(int,int,int,int,int,int,int); +int qurt_qdi_qhi8(int,int,int,int,int,int,int,int); +int qurt_qdi_qhi9(int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi10(int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi11(int,int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi12(int,int,int,int,int,int,int,int,int,int,int,int); + +/**@ingroup func_qurt_qdi_write + Writes data to the specified driver. + A predefined invocation routine for drivers that + support a POSIX-like write functionality. + qqurt_qdi_write(handle, buf, len) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_WRITE, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data to write is stored. + @param[in] len Number of bytes of data to write. + + @return + Non-negative integer -- Number of bytes written. \n + Negative error code -- Write could not take place. + + @dependencies + None. + */ +int qurt_qdi_write(int handle, const void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_read + User-visible API to read data from a QDI handle. + A predefined invocation routine for drivers that + support a POSIX-like read functionality. + qurt_qdi_read(handle, buf, len) is equivalent to: + qurt_qdi_handle_invoke(handle, QDI_READ, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data read is stored. + @param[in] len Number of bytes of data to read. + + @return + Non-negative integer number -- Bytes read. \n + Negative error code -- Read could not take place. + + @dependencies + None. + */ +int qurt_qdi_read(int handle, void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_close + Closes the specified driver, releasing any resources associated with the open driver. + User-visible API to close a QDI handle. + + This API should be called when the user is done using a + QDI-based handle. When this function is called, the driver can release + any resources held and perform other necessary cleanup + operations. qurt_qdi_close(handle) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_CLOSE, handle) + + @param[in] handle Driver handle. + + @return + 0 -- Success.\n + Negative error code -- Failure. + + @dependencies + None. + */ +int qurt_qdi_close(int handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_constants.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_constants.h new file mode 100755 index 0000000000000..4866fada067f0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_constants.h @@ -0,0 +1,193 @@ +#ifndef QDI_CONSTANTS_H +#define QDI_CONSTANTS_H + +/** + @file qurt_qdi_constants.h + @brief Predefined invocation methods for drivers. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Method numbers used for QDI. +|| +|| Intended grouping of method numbers for QDI +|| including future usage: +|| +|| Method 0 should always be unused and not responded to by +|| any driver. +|| Methods 1 and 2 are reserved for name registration and +|| name lookup. +|| Methods 3 through 31 are reserved for POSIX-type operations +|| on open handles. +|| Methods 32 through 127 are reserved for the QDI infrastructure +|| and may be extended in the future to provide standard +|| driver debug services, management services, and system +|| notifications. +|| Methods 128 through 255 are reserved for the use of automatically +|| generated methods such as might be generated by an IDL (interface +|| definition language). The infrastructure may be extended to +|| perform services on these methods based on information provided +|| by the IDL, such as automatic buffer validation, etc. These +|| method numbers should not be used for any "ad hoc" methods. +|| Methods with number >= 256 are "private" method numbers that are +|| outside the scope of the QDI infrastructure. Drivers that want +|| to generate and consume their own "ad hoc" methods are free to +|| use these method numbers as they wish. The infrastructure does +|| not generate these method numbers or respond to them, but +|| passes them on unmolested. +|| +|| All driver implementations *should* return a value of +|| -1 when called with an unsupported method. The standard error +|| return value for POSIX APIs is -1, so we emulate that behavior +|| here. +*/ +/** @cond */ +#define QDI_UNUSED 0 +#define QDI_DEVNAME_REGISTER 1 +#define QDI_OPEN 2 +#define QDI_CLOSE 3 +#define QDI_READ 4 +#define QDI_WRITE 5 +#define QDI_IOCTL 6 +#define QDI_MMAP 7 +#define QDI_OS_FILEOPEN 8 +#define QDI_FLEN 9 +#define QDI_UNLINK 10 +#define QDI_FTELL 22 +#define QDI_SEEK 23 +#define QDI_FSTAT 24 + +#define QDI_FSNAME_REGISTER 150 +#define QDI_FS_OPEN 151 +#define QDI_MMAP2 153 +#define QDI_MPROTECT2 154 +#define QDI_MUNMAP2 155 + +#define QDI_CLIENT_HANDLE_OBJREF_GET 10 + +#define QDI_OS_PROCESS_LOAD 12 +#define QDI_OS_PROCESS_CHOOSE_ASID 13 + +#define QDI_OS_SET_GP 26 +#define QDI_CLIENT_HANDLE_CALLBACK 27 + +#define QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T 19 //reused +#define QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T 80 +#define QDI_CLIENT_HANDLE_HANDLE_RELEASE 81 +#define QDI_CLIENT_HANDLE_COPY_FROM_USER 82 +#define QDI_CLIENT_HANDLE_COPY_TO_USER 83 +#define QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE 86 +#define QDI_CLIENT_HANDLE_SAFE_CACHE_OPS 87 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK 41 +#define QDI_CLIENT_HLOSPOOL_INFO_GET 90 +#define QDI_CLIENT_HLOSPOOL2_INFO_GET 96 + +#define QDI_CLIENT_PID 44 +#define QDI_CLIENT_ASID QDI_CLIENT_PID + +#define QDI_OS_CLIENT_INFO_GET 48 + +#define QDI_OS_MEM_LOOKUP_PHYSADDR 57 + +#define QDI_OS_THREAD_ITERATOR_CREATE 68 +#define QDI_OS_THREAD_ITERATOR_NEXT 69 + +#define QDI_OS_SYSENV 78 + +#define QDI_REGION_USERMALLOC_INIT 180 // This method is for generic handle + + +#define QDI_CLIENT_HANDLE_USER_MALLOC 84 +#define QDI_CLIENT_HANDLE_USER_FREE 85 + +#define QDI_SIGNAL_GROUP_SIGNAL_CREATE 96 +#define QDI_SIGNAL_GROUP_WAIT 98 +#define QDI_SIGNAL_GROUP_POLL 99 +#define QDI_SIGNAL_SET 96 +#define QDI_SIGNAL_CLEAR 97 +#define QDI_SIGNAL_WAIT 98 +#define QDI_SIGNAL_POLL 99 + +#define QDI_OS_WAIT_FOR_MAIN_REAPER 104 + +#define QDI_CLIENT_HANDLE_REFPROXY_INSTALL 105 +#define QDI_CLIENT_HANDLE_REFPROXY_ADD 106 +#define QDI_CLIENT_HANDLE_REFPROXY_REMOVE 107 + +#define QDI_CLIENT_HANDLE_DETACH 116 + +#define QDI_OS_RESERVED1 139 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK2 142 + +#define QDI_DT_REGISTER 158 +#define QDI_OPEN_DEVICE 159 +#define QDI_OPEN_FROM_DT 160 + +#define QDI_PRIVATE 256 /* Method numbers beginning at 256 + are private method numbers, which + are device-specific and available + for use by device implementors. */ +/* +|| Permission bitmasks for use with qurt_qdi_lock_buffer(). +|| +|| Make sure these match with permission values from qurt_perm_t. +*/ +/** @endcond */ + +/** @addtogroup driver_support_constants +@{ */ +#define QDI_PERM_W 2 /**< Write access. */ +#define QDI_PERM_R 1 /**< Read access. */ +#define QDI_PERM_RW (QDI_PERM_R | QDI_PERM_W) /**< Read/write access. */ + +#define QDI_HANDLE_LOCAL_CLIENT 3 /**< Local client. */ +#define QDI_HANDLE_GENERIC 4 /**< Generic. */ + +#define QDI_REFCNT_BASE 0x510000 /**< */ +#define QDI_REFCNT_MAXED 0x51FFFD /**< */ +#define QDI_REFCNT_INIT 0x51FFFE /**< Driver object is temporary and is eventually deleted.*/ +#define QDI_REFCNT_PERM 0x51FFFF /**< Driver object is permanent and is never deleted. */ +/** @} */ /* end_addtogroup driver_support_constants */ + +/** @cond */ +/* +|| Flags used by process loaders. +*/ + +#define QDI_OS_PROCESS_FLAGS_ISLAND_RESIDENT 0x1 /* Set this flag to request the loaded process + to have island residency. */ +#define QDI_OS_PROCESS_FLAGS_ROOT_RESIDENT 0x2 /* Set this flag to request the loaded process + to have root residency, for example, DL Pager. */ +/* +|| Constants used for qurt_event register API, type field. +*/ + +#define QURT_PROCESS_EXIT 1 + +/* +|| Constants used by QDI extensions. +*/ + +#define QURT_QDI_SINGLETON_TYPE_TRUE 0 +#define QURT_QDI_SINGLETON_TYPE_FALSE 1 +#define QURT_QDI_SINGLETON_TYPE_PER_PROCESS 2 +/** @endcond */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QDI_CONSTANTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_driver.h new file mode 100755 index 0000000000000..e044e25f1bb72 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_driver.h @@ -0,0 +1,868 @@ +#ifndef QURT_QDI_DRIVER_H +#define QURT_QDI_DRIVER_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2018, 2019-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "stddef.h" +#include "qurt_qdi.h" +#include "qurt_types.h" +#include "qurt_callback.h" +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" +#include "qurt_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| This gives the canonical form for the arguments to a QDI +|| driver invocation function. The arguments are as follows: +|| +|| int client_handle (R0) QDI handle that represents the client +|| that made this QDI request. If the +|| client is remote, this is a +|| variable handle; if the client is local +|| (same thread and process), this is +|| set to QDI_HANDLE_LOCAL_CLIENT. +|| +|| qurt_qdi_obj_t *obj (R1) Points at the qdi_object_t structure +|| on which this QDI request is being made. +|| The qdi_object_t structure is usually +|| the first element of a larger structure +|| that contains state associated with the +|| object; because it is usually the first +|| element, the object pointers can be freely +|| interchanged through casts. +|| +|| int method (R2) Integer QDI method that represents +|| the request type. +|| +|| qurt_qdi_arg_t arg1 (R3) First three general purpose arguments +|| qurt_qdi_arg_t arg2 (R4) to the invocation function are passed in +|| qurt_qdi_arg_t arg3 (R5) these slots. +|| +|| qurt_qdi_arg_t arg4 (SP+0) Arguments beyond the first three are +|| qurt_qdi_arg_t arg5 (SP+4) passed on the stack. +|| qurt_qdi_arg_t arg6 (SP+8) +|| qurt_qdi_arg_t arg7 (SP+12) +|| qurt_qdi_arg_t arg8 (SP+16) +|| qurt_qdi_arg_t arg9 (SP+20) +|| +|| The canonical form of the invocation function takes a +|| total of 12 arguments, but not all of them are used. In general, +|| the QDI infrastructure only passes those arguments provided by +|| the caller; if the invocation function accesses additional +|| arguments beyond those provided by the caller, the values are not +|| useful. +*/ +/** @cond */ +#define QDI_INVOKE_ARGS \ + int, struct qdiobj *, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define QDI_EXT_INVOKE_ARGS \ + int, qurt_qdi_man_obj_t*, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define BUFFER_LOCK 1 +#define BUFFER_UNLOCK 0 + +struct qdiobj; +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef union { + void *ptr; /**< Pointer to the driver handle. */ + int num; /**< Method number. */ +} qurt_qdi_arg_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI driver version */ +typedef union { + int num; + struct { + short major; /** Driver major version number. */ + short minor; /** Driver minor version number. */ + }; +} qurt_qdi_version_t; + +typedef int (*qurt_qdi_pfn_invoke_t)(QDI_INVOKE_ARGS); +typedef void (*qurt_qdi_pfn_release_t)(struct qdiobj *); +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef struct qdiobj { + qurt_qdi_pfn_invoke_t invoke; /**< Invocation function that implements the driver methods.*/ + int refcnt; /**< Reference count, an integer value maintained by the QDI infrastructure that tracks the number of + references to a driver instance. */ + qurt_qdi_pfn_release_t release; /**< Release function that performs details associated with deleting an instance + of the driver object.*/ +} qurt_qdi_obj_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI managed object */ +typedef struct qurt_qdi_man_obj +{ + qurt_qdi_obj_t qdi_obj; + union + { + struct qurt_qdi_ext_driver * opener_obj; + struct qurt_qdi_ext_device * device_obj; + }; +}qurt_qdi_man_obj_t; + +typedef int (*qurt_qdi_ext_pfn_create_t)(int client_id, const char *name, qurt_qdi_version_t version, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_create_device_t)(int client_id, const char *name, qurt_qdi_version_t version, struct qurt_qdi_ext_device * device, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_invoke_t)(QDI_EXT_INVOKE_ARGS); +typedef void (*qurt_qdi_ext_pfn_destroy_t)(qurt_qdi_man_obj_t *qdi_obj); +typedef int (*qurt_qdi_ext_pfn_probe_t)(void *handle, struct qurt_qdi_ext_device **device); + +typedef struct qurt_qdi_ext_obj_info{ + qurt_qdi_man_obj_t *obj; + int qdi_client_id; + struct qurt_qdi_ext_obj_info *next; +}qurt_qdi_ext_obj_info_t; +typedef struct qurt_qdi_ext_obj_info *qurt_qdi_ext_obj_info_ptr; + +/** QuRT QDI device */ +//temporarily add this back while there are still drivers who statically define this structure +struct qurt_qdi_device { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; +}; +typedef struct qurt_qdi_device qurt_qdi_man_device; + +struct qurt_qdi_ext_driver { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + qurt_qdi_ext_pfn_create_device_t create_device; + qurt_qdi_version_t version; + qurt_qdi_ext_pfn_probe_t probe; + const char* compatible; + struct qurt_qdi_ext_device * device_list; + //qurt_qdi_ext_device_ptr device_list; +}; +typedef struct qurt_qdi_ext_driver qurt_qdi_ext_driver_t; +//above replaces qurt_qdi_man_device + +extern int qurt_qdi_obj_ref_inc(qurt_qdi_obj_t *); +extern int qurt_qdi_obj_ref_dec(qurt_qdi_obj_t *); + +extern int qurt_qdi_ext_opener (QDI_INVOKE_ARGS); +/** @endcond */ +/**@ingroup func_qurt_qdi_method_default + Processes a method that is unrecognized or unsupported in the driver invocation function. + All arguments passed to the current invocation function (Section @xref{sec:invocationFunction}) must be forwarded + to this function. + + @note1hang Invocation functions must process all unrecognized or unsupported methods + by calling this function. + + @return + None. + + @dependencies + None. +*/ +extern int qurt_qdi_method_default(QDI_INVOKE_ARGS); + +/**@ingroup func_qurt_qdi_handle_create_from_obj_t + Allocates a new device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[out] obj Pointer to the driver object. + + @return + Non-negative integer -- Success; this value is the new handle. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_invoke + Allocates a new island device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). + @param[in] obj Pointer. + + @return + Non-negative integer value that is the new handle -- Success. \n + Negative return value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_island_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_release + Deallocates the specified device handle. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] handle_to_release Handle to release. + + @return + 0 -- Success. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_release(int client_handle, int handle_to_release) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_RELEASE, + handle_to_release); +} + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_handle(int client_handle, int object_handle) +{ + qurt_qdi_obj_t *ret; + + ret = NULL; + + qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_OBJREF_GET, + object_handle, + &ret); + + return ret; +} + +/**@ingroup func_qurt_client_add_memory + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory(int client_handle, qurt_addr_t phys_addr, qurt_size_t size); + +/**@ingroup func_qurt_client_add_memory2 + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting 36-bit address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory2(int user_client_handle, qurt_paddr_64_t phys_addr, qurt_size_t size); + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_pointer(qurt_qdi_obj_t *objptr) +{ + qurt_qdi_obj_t * ret = NULL; + + if (qurt_qdi_obj_ref_inc(objptr) < 0) { + ret = NULL; + } else { + ret = objptr; + } + + return ret; +} + +static __inline void +qurt_qdi_objref_release(qurt_qdi_obj_t *objptr) +{ + if (qurt_qdi_obj_ref_dec(objptr) == 1) { + (*objptr->release)(objptr); + } +} + +/**@ingroup func_qurt_qdi_copy_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the driver buffer. + @param[in] src Base address of the user buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_from_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_FROM_USER, + dest, src, len); +} + +/**@ingroup qurt_qdi_copy_string_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param dest Base address of the driver buffer. + @param src Base address of the user buffer. + @param len Number of bytes to copy. NOTE: This is the destination buffer length. + + @return + Negative error result -- privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +int qurt_qdi_copy_string_from_user(int client_handle, char *dest, const char *src, unsigned len); + +/**@ingroup func_qurt_qdi_copy_to_user + Copies the contents of a driver memory buffer to user memory. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the user buffer. + @param[in] src Base address of the driver buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_to_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_TO_USER, + dest, src, len); +} + +/**@ingroup func_qurt_qdi_safe_cache_ops + Do cache operations on user memory + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] addr Base address of the user memory. + @param[in] size Size of the user memory. + @param[in] opcode Cache operations (QURT_MEM_CACHE_FLUSH, QURT_MEM_CACHE_INVALIDATE...) + @param[in] type Cache type (QURT_MEM_ICACHE, QURT_MEM_DCACHE) + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_safe_cache_ops(int client_handle, qurt_addr_t addr, qurt_size_t size, + qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SAFE_CACHE_OPS, + addr, size, opcode, type); +} + + +/**@ingroup func_qurt_qdi_buffer_lock + Prepares for the direct manipulation of a potentially untrusted buffer provided by a QDI + client. + + This function is used to permit a trusted driver to safely access memory that is + provided by a potentially untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + + This function performs the following security checks: \n + - Verifies that the entire buffer is accessible to the client. \n + - Ensures that the pointer remains valid for the remainder of the QDI driver + operation. \n + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] buf Pointer to the base address of the client buffer address. + @param[in] len Buffer length (in bytes). + @param[in] perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + - #QDI_PERM_R -- Read access \n + - #QDI_PERM_W -- Write access \n + - #QDI_PERM_RW -- Read/write access @tablebulletend + @param[out] obuf Pointer to the buffer address that the driver must use to access the buffer. + + @return + Negative value -- Error; the operation crosses a privilege boundary, indicating a privilege or security violation. \n + Nonzero value -- User passed a buffer that does not fulfill the requested read/write access permission. + In this case the QDI driver call must be terminated cleanly, with an appropriate error code + returned to the client. \n + Zero -- Success; when this occurs the QDI driver must use the pointer at *obuf to access memory, and not the + pointer passed in as buf -- even if the user process changes the mapping of memory at buf, + the mapping of memory at *obuf remains valid until the driver invocation completes. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK, + buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_lock2 + Prepares for the direct manipulation of a possibly-untrusted buffer provided by a QDI + client. + This API permits a trusted driver to safely access memory + provided by a possibly-untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + This function performs the following security checks: \n + -- Entire buffer is accessible to the client. \n + -- Entire buffer is mapped with permissions passed in perms field \n + -- Entire buffer is physically contiguous \n + In addition to the security checks, the API also locks the client mapping such that the client + cannot remove the mapping while the physical memory is used by the trusted + driver. \n + + @note1 Drivers are responsible for calling qurt_qdi_buffer_unlock() at appropriate time. Not + pairing qurt_qdi_buffer_unlock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client. If the client exits abruptly, the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Safe buffer + unmapping or user buffer unlock is not supported in Island mode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + -- #QDI_PERM_R -- Read access \n + -- #QDI_PERM_W -- Write access \n + -- #QDI_PERM_RW -- Read/write access \n + @param obuf Optional parameter that returns a pointer to the buffer address that + the driver must use to access the buffer. If NULL is passed, the API + only performs security checks and does not create a mapping to access the user buffer in + a safe way. + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EPRIVILEGE -- One of the security checks on the user buffer failed. \n + QURT_EFAILED -- Mapping cannot be created for the trusted driver. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock2(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_LOCK, buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_unlock + This API is paired with qurt_qdi_buffer_lock2(). A temporary overlapping mapping + created for the driver is removed. Client mapping for the user buffer is + unlocked. + + @note1 Drivers are responsible for pairing this with qurt_qdi_buffer_lock(). Not + pairing qurt_qdi_buffer_lock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client, and if the client exits abruptly, all the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Actual + unmapping of driver accessible memory or unlocking of the buffer is not + supported in Island bode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param obuf Safe buffer address that was returned in the obuf field after calling + qurt_qdi_buffer_lock2(). + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. \n + other results -- Safe buffer unmapping failed or unlocking of user buffer failed \n. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_unlock(int client_handle, void *buf, unsigned len, + void *obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_UNLOCK, buf, len, obuf); +} + +/**@ingroup func_qurt_qdi_user_malloc + Allocates memory area in the QDI heap that is read/write accessible to both the driver and + the client. \n + @note1hang The QDI heap has a limited amount of memory available, and only the + device driver can free the allocated memory. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param size Size. + + @return + Non-zero -- Success; this returned value points to the allocated memory area. \n + Zero -- Error. + + @dependencies + None. +*/ +void *qurt_qdi_user_malloc(int client_handle, unsigned size); + +/**@ingroup func_qurt_qdi_user_free + Deallocates memory area in the QDI heap. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param ptr Pointer. + + @dependencies + None. +*/ +void qurt_qdi_user_free(int client_handle, void *ptr); + +/**@ingroup funct_qurt_qdi_client_detach + Detaches a client (a process), indicating that the client does not + participate in the qurt_wait() mechanism. This behavior + is opt-in and irrevocable. When a client is detached, it can + not be un-detached. + + @param client_handle Handle of the client to detach. + + @return + Zero -- Success. Detachable clients always return success. + Nonzero value -- client_handle did not refer to a + detachable user client. + + @dependencies + None. +*/ +static __inline int qurt_qdi_client_detach(int client_handle) +{ + return qurt_qdi_handle_invoke(client_handle, QDI_CLIENT_HANDLE_DETACH); +} + +/**@ingroup func_qurt_qdi_signal_group_create + Creates a new signal group for use in a device driver. + A QDI signal group contains up to 32 signals, which can be operated on either + individually (using the qurt_qdi_signal_* functions) or as a group (using the + qurt_qdi_signal_group_* functions). \n + @note1hang Driver implementation is responsible for using the proper signal group + handle in any given situation. \n + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param p_signal_group_handle_local Returns a handle intended for use by code that + resides in the same context and process as the created signal group + (for example, the device driver implementation that allocated the + signal group). + @param p_signal_group_handle_remote Returns a handle intended for use by code + that resides in a different context and process than the created signal group + (for example, the user-mode client of an OS driver). + + @return + Zero return value indicates success.\n + Negative return value indicates could not create signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_create(int client_handle, + int *p_signal_group_handle_local, + int *p_signal_group_handle_remote) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE, + p_signal_group_handle_local, + p_signal_group_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_group_wait + Suspends the current thread until any of the signals are set in the specified signal group. + + If a signal is set in a signal group object, and a thread waits on the signal group object, + the thread is awakened. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @param signal_group_handle Handle of the signal group. + + @return + If the client is remote: + QURT_EOK -- Wait complete \n + QURT_ECANCEL -- Wait cancelled.\n + If the client is local, returns a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_wait(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_group_poll + Returns a value that indicates if any of the signals are set in the specified signal group. + + @param signal_group_handle Handle of the signal group. + + @return + 1 -- Indicates whether any of the signals are set in the signal group.\n + 0 -- Indicates that none of the signals are set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_poll(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_POLL); +} + + +/**@ingroup func_qurt_qdi_signal_create + Creates a new signal in the specified signal group. + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @note1hang Driver implementation is responsible for using the proper signal handle in + any given situation. + + @param signal_group_handle Handle of an existing signal group. + @param p_signal_handle_local Returns a handle intended for use by code that resides in + the same context and process as the created signal (for example, + the device driver implementation that allocated the signal). + @param p_signal_handle_remote Returns a handle intended for use by code that resides in + a different context and process than the created signal (for + example, the user-mode client of an OS driver). + + @return + Nonzero value -- No more signals can be created in the specified + signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_create(int signal_group_handle, + int *p_signal_handle_local, + int *p_signal_handle_remote) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_SIGNAL_CREATE, + p_signal_handle_local, + p_signal_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_set + Sets the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_set(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_SET); +} + +/**@ingroup func_qurt_qdi_signal_clear + Clears the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_clear(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_CLEAR); +} + +/**@ingroup func_qurt_qdi_signal_wait + Suspends the current thread until the specified signal is set. + If a signal is set in a signal object, and a thread waits on the signal object, the + thread is awakened. If the awakened thread has higher priority than the current thread, a + context switch may occur. + + @param signal_handle Handle of the signal. + + @return + If client is remote: + QURT_EOK -- Wait complete. \n + QURT_ECANCEL -- Wait cancelled.\n + If client is local, return a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_wait(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_poll + Returns a value that indicates if the specified signal is set. + + @param signal_handle Handle of the signal. + + @return + 1 -- Signal is set. \n + 0 -- Signal is not set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_poll(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_POLL); +} + +/**@ingroup func_qurt_qdi_devname_register + Registers a QDI device with the generic QDI object in the + current QDI context. + + This function registers an exact name or a directory prefix with a QDI opener object. + Future invocations of qurt_qdi_open() in the context of the caller invokes the + opener object if a match is detected. + + Directory prefix names are specified by ending the name with a forward slash character. + + Example of an exact name: + @code qurt_qdi_devname_register(/dev/foobar, foobar_opener);@endcode + + Example of a directory prefix: + @code qurt_qdi_devname_register(/pipedev/, pipedev_opener);@endcode + + Given the two registrations shown above, the only qurt_qdi_open() requests to + direct to the foobar_opener object are requests for the exact name + "/dev/foobar", Any request beginning with "/pipedev/" is directed to the + pipedev_opener object. + + The pipedev invocation function presumably examines the name argument to + determine exactly how to handle the request. The name is passed to the invocation + function in the a1.ptr argument (Section @xref{sec:invocationFunction}). + + @param name Device name or device name prefix. + @param opener Pointer to the opener object for the device. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. + + @dependencies + None. + */ +static __inline int qurt_qdi_devname_register(const char *name, + qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, + QDI_DEVNAME_REGISTER, + name, + opener); +} + +// Macros for backward compatibility with deprecated APIs +// (These will go away soon) + +#define qurt_qdi_register_devname(name, opener) \ + qurt_qdi_devname_register((name), (void *)(opener)) +#define qurt_qdi_new_handle_from_obj_t(handle, obj) \ + qurt_qdi_handle_create_from_obj_t((handle), (obj)) +#define qurt_qdi_release_handle(client_handle, handle) \ + qurt_qdi_handle_release((client_handle), (handle)) +#define qurt_qdi_lock_buffer(handle, buf, len, perms, obuf) \ + qurt_qdi_buffer_lock((handle), (buf), (len), (perms), (obuf)) +#define qurt_qdi_usermalloc(handle, size) \ + qurt_qdi_user_malloc((handle), (size)) +#define qurt_qdi_userfree(handle, ptr) \ + qurt_qdi_user_free((handle), (ptr)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_ext.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_ext.h new file mode 100755 index 0000000000000..383e1799a15d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_ext.h @@ -0,0 +1,58 @@ +#ifndef QURT_QDI_EXT_H +#define QURT_QDI_EXT_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018, 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct qurt_qdi_ext_device { + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + struct qurt_qdi_ext_device * next; + char * instance; + fdt_node_handle context; +}; +typedef struct qurt_qdi_ext_device *qurt_qdi_ext_device_ptr; + +/**@ingroup func_qurt_qdi_dt_register + Registers a QDI device with the generic QDI object in the current QDI context, + if and only if a compatible device node is found in the device tree. This + function serves as a device tree aware wrapper for qurt_qdi_devname_register(). + + @param name Device name or device name prefix. + @param opener Pointer to QDI ext specialized opener object for the driver. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. +*/ +static __inline int qurt_qdi_dt_register(const char *name, qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_DT_REGISTER, name, opener); +} + +static inline void qurt_qdi_ext_deviceobj_set_name (struct qurt_qdi_ext_device * device, char * name) +{ + device->instance = name; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_imacros.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_imacros.h new file mode 100755 index 0000000000000..c0a8448ac87f8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_imacros.h @@ -0,0 +1,34 @@ +#ifndef QURT_QDI_IMACROS_H +#define QURT_QDI_IMACROS_H + +/** + @file qurt_qdi_imacros.h + @brief Internal macros used for QDI. Mostly consists of tricky (and ugly) + preprocessor hacks that permit us to do varargs function invocations + where we pass optional arguments in registers and where we can do + type casting and checking automatically. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _QDMPASTE(a,b) _QDMPASTE_(a,b) +#define _QDMPASTE_(a,b) a##b +#define _QDMCNT(...) _QDMCNT_(__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _QDMCNT_(a,b,c,d,e,f,g,h,i,j,k,l,cnt,...) cnt + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_proxy.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_proxy.h new file mode 100755 index 0000000000000..f1d8992ea8811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_qdi_proxy.h @@ -0,0 +1,55 @@ +/*============================================================================= + + qurt_qdi_proxy.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef _QURT_QDI_PROXY_H +#define _QURT_QDI_PROXY_H + +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* APIs allowing operation on the proxy object directly */ +int qurt_qdi_proxy_ref_create(void); + +/* APIs allowing to operate on proxy given a known proxy handle + * 1) using qdi handle of the object + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_handle(int proxy_handle, int qdi_handle); +int qurt_qdi_proxy_ref_sub_by_handle(int proxy_handle, int qdi_handle); + +/* 2) using object reference + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); +int qurt_qdi_proxy_ref_sub_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); + +/* API allowing to associate a proxy object with a particular client given a client handle + * successfule return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_install (int client_handle, int proxy_handle); + +/* APIs allowing operation on proxy object from user client + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_add(int qdi_handle); +int qurt_client_proxy_ref_remove(int qdi_handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_QDI_PROXY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex.h new file mode 100755 index 0000000000000..a013a0bbddb1d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_RMUTEX_H +#define QURT_RMUTEX_H +/** + @file qurt_rmutex.h + Prototypes of rmutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013 - 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_rmutex_init + Initializes a recursive mutex object. + The recursive mutex is initialized in unlocked state. + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_destroy + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex protects, and continues executing. + + If a thread performs a lock operation on a mutex that is already use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock_timed + Locks the specified recursive mutex. The wait must be terminated when the specified timeout expires.\n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex is protecting, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked by itself. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + If timeout expires, this wait must be terminated and no access to the mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + + */ +int qurt_rmutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + +/**@ingroup func_qurt_rmutex_unlock + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a mutex. When the mutex is + unlocked, the thread waiting on the mutex awakens. If the awakened + thread has higher priority than the current thread, a context switch occurs. + + @note1hang When a thread unlocks a recursive mutex, the mutex is not available until + the balanced number of locks and unlocks has been performed on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock + Attempts to lock the specified recursive mutex.\n + + If a thread performs a try_lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing.\n + If a thread performs a try_lock operation on a recursive mutex that another thread has + already locked, qurt_rmutex_try_lock immediately returns with a nonzero result + value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex_try_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock_block_once + Attempts to lock a mutex object recursively. If the mutex is available, + it locks the mutex. If the mutex is held by the current thread, + it increases the internal counter and returns 0. If not, it returns a + nonzero value. + If the mutex is already locked by another thread, the caller thread is + suspended. When the mutex becomes available again (because the other + thread has unlocked it), the caller thread is awakened and tries to lock + the mutex; and if it fails, this function returns failure with a nonzero + value. If it succeeds, this function returns success with zero. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the qurt_mutex_t object. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_rmutex_try_lock_block_once(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex2.h new file mode 100755 index 0000000000000..a37e7e4458c4b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_rmutex2.h @@ -0,0 +1,183 @@ +#ifndef QURT_RMUTEX2_H +#define QURT_RMUTEX2_H +/** + @file qurt_rmutex2.h + @brief Prototypes of rmutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT rmutex2 type. + Mutex type used with rmutex2 APIs. + */ +typedef struct { + /** @cond */ + unsigned int holder __attribute__((aligned(8))); /* UGP value of the mutex holder. */ + unsigned short waiters; /* Number of waiting threads. */ + unsigned short refs; /* Number of references to this mutex. */ + unsigned int queue; /* Kernel-maintained futex queuevalue. */ + unsigned int excess_locks; /* Number of excess times the holder has locked the mutex. */ + /** @endcond */ +} qurt_rmutex2_t; +/** @} */ /* end_addtogroup mutex_types */ +/** @cond internal_only*/ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_rmutex2_init + + @deprecated use #qurt_rmutex_init instead. + + Initializes a recursive mutex object. + + The recursive mutex is initially unlocked. + + Objects of type rmutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_destroy + + @deprecated use #qurt_rmutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code must destroy an rmutex2 object prior to + deallocating it; calling qurt_rmutex2_destroy() before deallocating it ensures + that all qurt_rmutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_lock + + @deprecated use #qurt_rmutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that the mutex protects, and continues + to execute. + + If a thread performs a lock operation on a recursive mutex that another thread is using, + the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_unlock + + @deprecated use #qurt_rmutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex awakens. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_rmutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_rmutex2_lock(). When a call to qurt_rmutex2_lock() + succeeds immediately, this function behaves similarly, returning 0 for success. + When a call to qurt_rmutex2_lock() does not succeed immediately, this function has + no effect and returns nonzero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex2_try_lock(qurt_rmutex2_t *lock); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sclk.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sclk.h new file mode 100755 index 0000000000000..a83cf5f1db889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sclk.h @@ -0,0 +1,145 @@ +#ifndef QURT_SCLK_H +#define QURT_SCLK_H +/** + @file qurt_sclk.h + @brief Header file describing the APIs supported by QuRT system SCLK + feature. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + + +/*============================================================================= + + INCLUDE FILES + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + Conversion from microseconds to sleep ticks. + */ +#define QURT_SYSCLOCK_TIMETICK_FROM_US(us) ((us) * 192ULL / 10UL) +#define qurt_sysclock_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_SYSCLOCK_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_SYSCLOCK_MAX_DURATION (1042499uLL * 3600uLL * 1000uLL * 1000uLL) +#define qurt_sysclock_max_duration() QURT_SYSCLOCK_MAX_DURATION +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_SYSCLOCK_MAX_DURATION_TICKS (1042499uLL * 3600uLL * 19200000uLL) +#define qurt_sysclock_max_duration_ticks() QURT_SYSCLOCK_MAX_DURATION_TICKS +/** + Sleep timer error margin for Qtimer is 192 ticks ~10 us. +*/ +#define QURT_SYSCLOCK_ERROR_MARGIN 192U //QURT_TIMER_MIN_DURATION*timer_freq; +#define qurt_sysclock_error_margin() QURT_SYSCLOCK_ERROR_MARGIN + +/*============================================================================= + + DATA DECLARATIONS + +=============================================================================*/ + +/**@ingroup func_qurt_sysclock_get_hw_ticks + @xreflabel{sec:qurt_sysclock_get_hw_ticks} + Gets the hardware tick count.\n + Returns the current value of a 64-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation must be used with care because of the wrap-around behavior. + + @return + Integer -- Current value of 64-bit hardware counter. + + @dependencies + None. + */ +unsigned long long qurt_sysclock_get_hw_ticks (void); + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_32 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_32} + Gets the hardware tick count in 32 bits.\n + Returns the current value of a 32-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 32 bits are the lower 32 bits of the Qtimer counter. + + @return + Integer -- Current value of the 32-bit timer counter. + + @dependencies + None. + */ +static inline unsigned long qurt_sysclock_get_hw_ticks_32 (void) +{ + //Beginning with v61 there is a HW register that can be read directly. + unsigned long count; + __asm__ __volatile__ (" %0 = c30 " : "=r"(count)); + return count; +} + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_16 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_16} + Gets the hardware tick count in 16 bits.\n + Returns the current value of a 16-bit timer counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 16 bits are based on the value of the lower 32 bits in Qtimer + counter, right shifted by 16 bits. + + @return + Integer -- Current value of the 16-bit timer counter, calculated from the lower 32 bits in the + Qtimer counter, right shifted by 16 bits. + + @dependencies + None. + */ + + +static inline unsigned short qurt_sysclock_get_hw_ticks_16 (void) +{ + unsigned long ticks; + + //Beginning with v61 there is a HW register that can be read directly. + __asm__ __volatile__ (" %0 = c30 " : "=r"(ticks)); + __asm__ __volatile__ ( "%0 = lsr(%0, #16) \n" :"+r"(ticks)); + + return (unsigned short)ticks; +} +unsigned long long qurt_timer_timetick_to_us(unsigned long long ticks); +#define qurt_sysclock_timetick_to_us(ticks) qurt_timer_timetick_to_us(ticks) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif /* QURT_SCLK_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_secure_proc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_secure_proc.h new file mode 100755 index 0000000000000..f40c7deb9bca1 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_secure_proc.h @@ -0,0 +1,53 @@ +#ifndef QURT_SECURE_PROC_H +#define QURT_SECURE_PROC_H + +/** + @file qurt_secure_proc.h + @brief Definitions, macros, and prototypes used for handling secure process + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_process_migrate_secure_process + Migrate the user process to Qurt secure process + + @param secure_phy_address Physical starting address of secure memory + @param secure_memory_size Size of secure memory + @param entry Entry function to secure process + + @return + EOK + Negative return value -- Error. + + @dependencies + None. +*/ +int qurt_process_migrate_secure_process(unsigned long long secure_phy_address, unsigned int secure_memory_size, void entry(unsigned)); + +/**@ingroup qurt_process_get_migration_mem_size + get the size of all writable memory regions in a user PD. This is for preparation on secure process migration. + + @return + size of all writable memory regions in a user PD. + + @dependencies + None. +*/ +int qurt_process_get_migration_mem_size(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sem.h new file mode 100755 index 0000000000000..ee5ce4b2d94ab --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_sem.h @@ -0,0 +1,252 @@ +#ifndef QURT_SEM_H +#define QURT_SEM_H +/** + @file qurt_sem.h + Prototypes of semaphore API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup semaphore_types +@{ */ + +/** QuRT semaphore type. */ +typedef union { + /** @cond */ + unsigned int raw[2] __attribute__((aligned(8))); + struct { + unsigned short val; /**< */ + unsigned short n_waiting; /**< */ + unsigned int reserved1; /**< */ + unsigned int queue; /**< */ + unsigned int reserved2; /**< */ + }X; /** @endcond */ +} qurt_sem_t; +/** @} */ /* end_addtogroup semaphore_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_sem_add + Releases access to a shared resource (the specified amount increments the semaphore count value).\n + When a thread performs an add operation on a semaphore, the specified value increments the semaphore count. + The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing. \n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel repeatedly awakens the highest-priority waiting thread and decrements + the semaphore count value until either no waiting threads remain or the + semaphore count value is zero. If any of the awakened threads has higher priority + than the current thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] amt Amount to increment the semaphore count value. + + @return + Unused integer value. + + @dependencies + None. + + */ +int qurt_sem_add(qurt_sem_t *sem, unsigned int amt); + +/**@ingroup func_qurt_sem_up + Releases access to a shared resource. When a thread performs an up operation on a semaphore, + the semaphore count value increments. The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing.\n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel awakens the highest-priority waiting thread and decrements the + semaphore count value. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +static inline int qurt_sem_up(qurt_sem_t *sem) { return qurt_sem_add(sem,1); } + +/**@ingroup func_qurt_sem_down + Requests access to a shared resource. When a thread performs a down operation on a + semaphore, the result depends on the semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +int qurt_sem_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_down_timed + When a thread performs a down operation on a semaphore, the result depends on the + semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. Terminate the wait when the specified timeout expires. + If timeout expires, terminate this wait and grant no access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_sem_down_timed(qurt_sem_t *sem, unsigned long long int duration); + +/**@ingroup func_qurt_sem_try_down + @xreflabel{hdr:qurt_sem_try_down} + Requests access to a shared resource (without suspend). When a thread performs a try down + operation on a semaphore, the result depends on the semaphore count value: \n + - The count value is decremented when it is nonzero. The down operation returns 0 as + the function result, and the thread gains access to the shared resource and is free to + continue executing.\n + - The count value is not decremented when it is zero. The down operation returns -1 + as the function result, and the thread does not gain access to the shared resource + and should not continue executing. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + 0 -- Success. \n + -1 -- Failure. + + @dependencies + None. + + */ +int qurt_sem_try_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init + Initializes a semaphore object. + The default initial value of the semaphore count value is 1. + + @param[out] sem Pointer to the initialized semaphore object. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_destroy + Destroys the specified semaphore.\n + @note1hang Semaphores must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Semaphores must not be destroyed while they are still in use. If this occur, + the behavior of QuRT is undefined. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_sem_destroy(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init_val + Initializes a semaphore object with the specified value. + + @datatypes + #qurt_sem_t + + @param[out] sem Pointer to the initialized semaphore object. + @param[in] val Initial value of the semaphore count value. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init_val(qurt_sem_t *sem, unsigned short val); + +/**@ingroup func_qurt_sem_get_val + Gets the semaphore count value.\n + Returns the current count value of the specified semaphore. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Integer semaphore count value + + @dependencies + None. + */ +static inline unsigned short qurt_sem_get_val(qurt_sem_t *sem ){return sem->X.val;} +int qurt_sem_down_cancellable(qurt_sem_t *sem); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SEM_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_shmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_shmem.h new file mode 100755 index 0000000000000..980557323708a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_shmem.h @@ -0,0 +1,89 @@ +#ifndef QURT_SHMEM_H +#define QURT_SHMEM_H + +/** + @file qurt_shmem.h + + @brief + Prototypes of QuRT inter-process shared memory APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MODE_T +#define MODE_T +typedef unsigned int mode_t; +#endif //MODE_T + +/** + * The shm_open() function establishes a connection between a shared memory object and a file descriptor. + * The file descriptor is used by other functions such as mmap() to refer to that shared memory object. + * + * + * @param name Pointer to string naming a shared memory object. Name has to start with "/shm/" + * @param oflag File status flags and file access modes of the open file description. Following + * flags are defined in and supported: + * O_RDONLY: oepn for read access only + * O_RDWR: Open for read or write access + * O_CREAT: If shared memory object doesn't exist, create one. + * @param mode Permission flags (currently ignored) + * + * @return file descriptor (positive number) if operation successful. + * negative error code if failed + * +*/ + +int shm_open(const char * name, int oflag, mode_t mode); + +/** + * The shm_mmap() function create a shared memory mapping in the virtual address space of the + * the calling process. + * + * @param addr The starting address for the new mapping is specified in addr. + * @param len Specifies the lengh of the shared memory region. + * @param prot Describes the desired memory protection of the mapping. Same as the one in mmap of POSIX. + * @param flags Determines whether updates to the mapping is visible or not to other process. Same as + * the one in mmap of POSIX. + * @param fd The starting adddress for the new mapping is returned. + * @param offset unused. + * + * @return The starting adddress for the new mapping is returned. + * negative error code if failed + * +*/ + +void *shm_mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset); + +/** + * The shm_close() function removes a connection between a shared memory object and a file descriptor. + * If there is no file descriptor connects to the shared memory object, the shared memory object will + * be deleted automatically. Shared memory object has same virtual address in any process. This is + * restriction of single virtual address space. + * + * + * @param fd File descriptor of shared memory object + * + * @return 0 if operation successful. + * negative error code if failed + * +*/ + + +int shm_close(int fd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal.h new file mode 100755 index 0000000000000..3a89c53394ad5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal.h @@ -0,0 +1,518 @@ +#ifndef QURT_SIGNAL_H +#define QURT_SIGNAL_H + +/** + @file qurt_signal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup signals_types +@{ */ +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 /**< Wait any. */ +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 /**< Wait all. */ + +/*===================================================================== + Typedefs + ======================================================================*/ + + +/** QuRT signal type. + */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int signals; + unsigned int waiting; + unsigned int queue; + unsigned int attribute; + }X; + /** @endcond */ +} qurt_signal_t; + + +/** QuRT 64-bit signal type. + */ +typedef struct { + /** @cond */ + qurt_signal_t signal_sum; + unsigned long long signals; + unsigned long long waiting; + /** @endcond */ +} qurt_signal_64_t; +/** @} */ /* end_addtogroup signals_types */ +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal_init + Initializes a signal object. + Signal returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_init(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_destroy + Destroys the specified signal object. + + @note1hang Signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_destroy(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting on the signal. + + If a thread is waiting on a signal object for any of the specified set of signals to set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared when the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread waits to set any of the signals, or to set all of + them. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_timed + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set or until timeout. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared after the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value that identifies the individual signals in the signal object to wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] signals Bitmask of signals that are set + @param[in] duration Duration (microseconds) to wait. Must be in the range + [#QURT_TIMER_MIN_DURATION ... #QURT_TIMER_MAX_DURATION] + + @return + #QURT_EOK -- Success; one or more signals were set \n + #QURT_ETIMEDOUT -- Timed-out \n + #QURT_EINVALID -- Duration out of range + + @dependencies + Timed-waiting support in the kernel. +*/ +/* ======================================================================*/ +int qurt_signal_wait_timed(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, unsigned int *signals, unsigned long long int duration); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_any + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on the thread. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_any(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_all + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_all(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to set the signal, and 0 indicates not to set it. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 32-bit word with current signals + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_get(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_clear + Clear signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_clear(qurt_signal_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal_wait_cancellable + @xreflabel{hdr:qurt_signal_wait_cancellable} + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] return_mask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_signal_wait_cancellable(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, + unsigned int *return_mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_init + Initializes a 64-bit signal object.\n + The signal argument returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore. + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_init(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_destroy + Destroys the specified signal object. + + @note1hang 64-bit signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_destroy(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_wait + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value, which identifies the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_wait(qurt_signal_64_t *signal, unsigned long long mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set it. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifiying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_64_set(qurt_signal_64_t *signal, unsigned long long mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_64_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 64-bit double word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_get(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_clear + Clears signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_clear(qurt_signal_64_t *signal, unsigned long long mask); + +#ifdef __cplusplus +} +#endif + +#endif /* QURT_SIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal2.h new file mode 100755 index 0000000000000..43975100cbf75 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_signal2.h @@ -0,0 +1,340 @@ +#ifndef QURT_SIGNAL2_H +#define QURT_SIGNAL2_H + +/** + @file qurt_signal2.h + @brief Prototypes of kernel signal2 API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 + +/*===================================================================== + Typedefs + ======================================================================*/ + +/** @addtogroup signals2_types +@{ */ +/** qurt_signal2 type. + */ +typedef union { + /** @cond */ + struct{ + unsigned int cur_mask; /* Current set of signal bits that are set. */ + unsigned int sig_state; /* Current state. */ + /* Bit 0 -- in anysignal wait. */ + /* Bit 1 -- in allsignal wait. */ + /* Bit 2 -- in interrupt wait. */ + /* Bits 31-3 -- reference count field. */ + unsigned int queue; /* Kernel-maintained futex queue value. */ + unsigned int wait_mask; /* When sig_state indicates a waiter is present, this is the wait mask. */ + }; + unsigned long long int raw; + /** @endcond */ +} qurt_signal2_t; +/* @} */ /* end_addtogroup signals2_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_init + + @deprecated use #qurt_signal_init instead. + + Initializes a signal2 object. + Signal returns the initialized object. + The signal object is initially cleared. + + Objects of type signal2 solve a potential race condition between + set() and destroy() operations. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + Each mutex-based object has an associated + kernel resource(s), therefore users must call qurt_signal2_destroy() + when this object no longer in use. + */ +/* ======================================================================*/ +void qurt_signal2_init(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_destroy + + @deprecated use #qurt_signal_destroy instead. + + Destroys the specified signal object. + + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont Application code should destroy a signal2 object prior to deallocating it. + Calling qurt_signal2_destroy() before deallocating a + signal2 object ensures completion of all qurt_signal2_set() calls. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_destroy(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait + + @deprecated use #qurt_signal_wait instead. + + Suspends the current thread until the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ANY, the thread will be awakened when + any of the signals specified in the mask are set. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ALL, the thread will be awakened only + when all the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to wait on. + @param[in] attribute Specifies whether the thread waits for any of the signals to be set, or for all of + them to be set. Values:\n + - QURT_SIGNAL_ATTR_WAIT_ANY \n + - QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_any + + @deprecated use #qurt_signal_wait_any instead. + + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened when any of the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_any(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_all + + @deprecated use #qurt_signal_wait_all instead. + + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened only when all the signals specified in the mask are set. + + @note1hang At most one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_all(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_set + + @deprecated use #qurt_signal_set instead. + + Sets signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_get + + @deprecated use #qurt_signal_get instead. + + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the signal object to access. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_get(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_clear + + @deprecated use #qurt_signal_clear instead. + + Clear signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_clear(qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal2_wait_cancellable + + @deprecated use #qurt_signal_wait_cancellable instead. + + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] p_returnmask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +int qurt_signal2_wait_cancellable(qurt_signal2_t *signal, + unsigned int mask, + unsigned int attribute, + unsigned int *p_returnmask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SIGNAL2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_space.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_space.h new file mode 100755 index 0000000000000..2c3f9e4496697 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_space.h @@ -0,0 +1,230 @@ +#ifndef QURT_SPACE_H +#define QURT_SPACE_H +/** + @file qurt_space.h + @brief Prototypes of QuRT process control APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** This flag is a request to the OS to suspend the processes just before calling main() +But it is going to be obsoleted and replaced by QURT_PROCESS_SUSPEND_ON_STARTUP */ +#define SPAWNN_FLAG_SUSPEND_ON_STARTUP QURT_PROCESS_SUSPEND_ON_STARTUP + +/** + * Creates and starts a process from ELF of a specified name. The slash symbols + * "/" or "\" are ignored. Do not include the directory name in the input. This function + * accepts the the SPAWN flags. Multiple SPAWN flags can be specified by OR'ing the flags. + * + * @param name ELF name of the executable. Name shall not contain directories, + * use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf" + * + * @param return + Process ID -- Success \n + Negative error code -- failure\n + #QURT_EPRIVILEGE -- Caller does not have enough privilege for this operation\n + #QURT_EMEM -- Not enough memory to perform the operation \n + #QURT_EFAILED -- Operation failed \n + #QURT_ENOTALLOWED -- Operation not allowed \n + #QURT_ENOREGISTERED -- Not registered \n + #QURT_ENORESOURCE -- Resource exhaustion \n + #QURT_EINVALID -- Invalid argument value +*/ + +int qurt_spawn_flags(const char * name, int flags); + +/** + Creates and starts a process from an ELF of the specified name. The slash symbols + "/" or "\" are ignored. Do not include the directory name in the input. + + @param name ELF name of the executable. Name shall not contain directories, + use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf". + + @return + Process ID -- Success. \m + Negative error code -- Failure. + +*/ +static inline int qurt_spawn(const char *name) +{ + return qurt_spawn_flags(name,0); +} + +/** + * Returns the process ID of the current process. + * + * @return + * Process ID + * +*/ +#define qurt_getpid qurt_process_get_id + +/** + * The qurt_wait() function waits for status change in a child process. It could be used by parent + * process to block on any child process terminates. + * + * This API returns error if there are no user processes or all user processes got detached. + * + * @param status Pointer to status variable. The variable provides the status value of child process. + * The value comes from exit() system call made by child process. + * + * @return + Process ID of the child process that changes status -- Success \n + * Negative error code -- Failure + * +*/ + +int qurt_wait(int *status); + + +/** @cond */ +/* APIs that allow registering callbacks on spawn of user pd */ +typedef void (*QURT_SPAWN_PFN)(int client_handle, void *data_ptr); //no return, since we won't be error checking it in spawn +typedef int (*QURT_CB_PFN)(int client_handle, void *user_data, void *info); +typedef union { + QURT_SPAWN_PFN spawn_pfn; + QURT_CB_PFN cb_pfn; +} qurt_process_callback_pfn_t; +/** @endcond */ + +/** @cond internal_only */ + +/**@ingroup func_qurt_event_register +Sets the specified bits by mask in the signal passed by the caller. The signal gets set +when the client handle indicated by value goes away (at process exit). Multiple clients can register for the signal +to be set. + +@datatypes + +@param[in] type QURT_PROCESS_EXIT is the only event that can be registered for. +@param[in] value Indicates the client handle of the process for which the event is registered. +@param[in] signal Pointer to the signal object to set when the event occurs. +@param[in] mask Mask bits to set in the signal. +@param[out] data Pointer to the variable that would receive the exit code of the exiting process. +@param[in] datasize Size of the data variable. + +@return +#QURT_EOK -- Success \n +#QURT_EMEM -- Not enough memory to allocate resources \n +#QURT_EVAL -- Invalid values passed to the API + +@dependencies +None. +*/ +int qurt_event_register(int type, int value, qurt_signal_t *psig, unsigned int mask, void *data, unsigned int data_size); + +/**@ingroup func_qurt_callback_register_onspawn +Allows registering for a callback on spawn of any user process. + +@datatypes +#QURT_SPAWN_PFN + +@param[in] pFn Callback function to call when any user process is spawned. +@param[in] user_data Pointer to the argument that the callback must be called with. + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_callback_register_onspawn(QURT_SPAWN_PFN pFn, void *user_data); + +/**@ingroup func_qurt_callback_deregister_onspawn +Allows de-registering callback on spawn. + +@param[in] callback_handle Handle returned by qurt_callback_register_onspawn. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_callback_deregister_onspawn(int callback_handle); + +/**@ingroup func_qurt_process_callback_register +Allows registering for a callback during or after image loading. +Generic callback types: + Functions similarly to qurt_callback_register_onspawn(). Callback is called after process is + loaded, before process thread starts. Callback has no return value and has no info provided + from OS. + pFn - QURT_SPAWN_PFN + type - QURT_PROCESS_CB_GENERIC + arg1 - not used + arg2 - not used + arg3 - not used +Note callback types: + Callback is called during process loading: before segment loading(QURT_PROCESS_NOTE_CB_PRE_MAP), + or after segment loading (QURT_PROCESS_NOTE_CB_POST_MAP). OS provides info to the callback. info + argument in callback is populated with pointer to the mapped note corresponding to the callback. + Callback has return value, loader fails if callback returns a value that is not QURT_EOK. + pFn - QURT_CB_PFN + type - QURT_PROCESS_NOTE_CB_PRE_MAP or QURT_PROCESS_NOTE_CB_POST_MAP + arg1 - note type (ex: NOTE_TYPE_POOL_INFO, NOTE_TYPE_SEGMENT_INFO, NOTE_TYPE_ARB_INFO) + arg2 - note name + arg3 - not used + +@datatypes + +@param[in] pFn Callback function to call +@param[in] type Callback type +@param[in] user_data Pointer to the argument that the callback must be called with. +@param[in] arg1 Arguments interpreted by OS based on callback type +@param[in] arg2 Arguments interpreted by OS based on callback type +@param[in] arg3 Arguments interpreted by OS based on callback type (currently not used) + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_process_callback_register(qurt_process_callback_pfn_t pFn, + qurt_process_cb_type_t type, + void *user_data, + qurt_process_callback_arg_t arg1, + qurt_process_callback_arg_t arg2, + qurt_process_callback_arg_t arg3); + + + +/**@ingroup func_qurt_process_callback_deregister +Allows de-registering callback for imate loading. +@param[in] callback_handle Handle returned by qurt_process_callback_register. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_process_callback_deregister(int callback_handle); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SPACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_consts.h new file mode 100755 index 0000000000000..48a8b6a38c402 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_consts.h @@ -0,0 +1,32 @@ +#ifndef QURT_SRM_CONSTS_H +#define QURT_SRM_CONSTS_H +/** + @file qurt_srm_consts.h + @brief Type definitions for srm + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2020-2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +#define QURT_SRM_WAKEUP_REQUEST 1U << 0 /**< Value = 1: Send wakeup request to the SRM server. */ +#define QURT_SRM_SET_HANDLE 1U << 1 /**< Value = 2: Set the client handle for a new SRM client. */ +#define QURT_SRM_ALLOC_KERNEL_PAGES 1U << 2 /**< Value = 4: Allocate pages from the kernel VA space. */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_driver.h new file mode 100755 index 0000000000000..5489e3dddbcca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_srm_driver.h @@ -0,0 +1,140 @@ +#ifndef QURT_SRM_DRIVER_H +#define QURT_SRM_DRIVER_H +/** + @file qurt_srm_driver.h + @brief Definitions, macros, and prototypes used by SRM drivers. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + + =============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Define qurt_srm_driver_t structure, which represents +|| the "registration" object for an SRM driver. +*/ +/** @cond internal_only */ +struct _qurt_srm_driver { + const char *name; + qurt_qdi_obj_t *obj; +}; + +typedef struct _qurt_srm_driver qurt_srm_driver_t; + +/* +|| qurt_srm_object_invoke() is an internal equivalent to qurt_qdi_handle_invoke(). +|| It behaves the same, but it takes a QDI object pointer instead of a handle. +*/ + +#define qurt_srm_object_invoke(o,m,...) \ + _QDMPASTE(_QDMSOI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__) +#define _QDMSOI3(a,b,c) qurt_srm_oi3(a,b,c) +#define _QDMSOI4(a,b,c,d) qurt_srm_oi4(a,b,c,(int)(d)) +#define _QDMSOI5(a,b,c,d,e) qurt_srm_oi5(a,b,c,(int)(d),(int)(e)) +#define _QDMSOI6(a,b,c,d,e,f) qurt_srm_oi6(a,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMSOI7(a,b,c,d,e,f,g) qurt_srm_oi7(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMSOI8(a,b,c,d,e,f,g,h) qurt_srm_oi8(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMSOI9(a,b,c,d,e,f,g,h,i) qurt_srm_oi9(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMSOI10(a,b,c,d,e,f,g,h,i,j) qurt_srm_oi10(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMSOI11(a,b,c,d,e,f,g,h,i,j,k) qurt_srm_oi11(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMSOI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_srm_oi12(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) + +int qurt_srm_oi3(int, qurt_qdi_obj_t *, int); +int qurt_srm_oi4(int, qurt_qdi_obj_t *, int, int); +int qurt_srm_oi5(int, qurt_qdi_obj_t *, int, int, int); +int qurt_srm_oi6(int, qurt_qdi_obj_t *, int, int, int, int); +int qurt_srm_oi7(int, qurt_qdi_obj_t *, int, int, int, int, int); +int qurt_srm_oi8(int, qurt_qdi_obj_t *, int, int, int, int, int, int); +int qurt_srm_oi9(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int); +int qurt_srm_oi10(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int); +int qurt_srm_oi11(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int); +int qurt_srm_oi12(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int, int); + +#define QDI_SRM_INIT 192 + +/* +|| QURT_SRM_DECLARE_DRIVER() declares an SRM driver to the SRM infrastructure. +|| +|| The three arguments are: +|| unique_id -- Unique C identifier, unused but must be a unique global symbol. +|| name -- Name of the driver by which an SRM client attempts to open it. +|| obj -- Pointer to the singleton object of the driver, which handles things such as +|| initialization and QDI_OPEN requests. +*/ + +#define QURT_SRM_DECLARE_DRIVER(unique_id, xname, xobj) \ + __attribute__((section(".srm.rodata.user.main.DECL"))) const qurt_srm_driver_t unique_id = \ + { .name = xname, .obj = xobj } + + +/*@ingroup func_qurt_srm_mapping_create + Creates a memory mapping in pagetable with specified attributes + + @param[in] client_handle Client handle representing the process for which + mapping would be created. + @param[in] pageno_virt pointer to the virtual page. NULL indicates SRM + would indicate the virtual memory. + @param[in] pageno_phys physical page to be used for the mapping + @param[in] page_count number of 4k pages to be mapped + @param[in] cache_attr cache attributes for the mapping + @param[in] perm permissions to be used for the mapping + + @return value greater than 0 indicates a handle which can be passed to + qdi_close() to remove the mapping. Negative value indicates + an error. + + @dependencies + None. +*/ +int qurt_srm_mapping_create(int client_handle, + unsigned *pageno_virt, + unsigned pageno_phys, + unsigned page_count, + qurt_mem_cache_mode_t cache_attr, + qurt_perm_t perm); + + +/**@ingroup func_qurt_srm_get_pid + Gets the PID for the client_handle that is passed. + + @param[in] client_handle Client handle for which PID is required. + + @return PID of the client + Negative PID value '-1' will be returned in case of Error + + @dependencies + None. +*/ +unsigned qurt_srm_get_pid(int client_handle); + + +/*@ingroup func_qurt_srm_get_thread_id + Gets the thread id of the client requesting a service from SRM + + @param[in] None. + + @return thead id of client thread + + @dependencies + None. +*/ +qurt_thread_t qurt_srm_get_client_thread_id(void); + +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_DRIVER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_stid.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_stid.h new file mode 100755 index 0000000000000..379f46aaa4b80 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_stid.h @@ -0,0 +1,73 @@ +#ifndef QURT_STID_H +#define QURT_STID_H +/** + @file qurt_stid.h + Prototypes of software thread identifier(stid) interface APIs. + A stid is 8 bit identifier that can be assigned to a software thread. + The performance monitor logic uses stid as a counting match criteria + for maskable events. stid is also used by the hardware debugger + (ISDB) to match breakpoints. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2024 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_stid_alloc + Allocate a unique stid + + @param[in] pid Process identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - Allocation success + QURT_ENORESOURCE - No stid available for allocation + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_stid_alloc(unsigned int pid, unsigned int *stid); + +/**@ingroup func_qurt_stid_release + Release the stid. + + + @param[in] pid Process identifier + @param[in] stid STID to release + + @note1hang + User shall ensure to clear the released stid from process or thread(s) + to default value (QURT_STID_DEFAULT) before releasing that stid + + @return + QURT_EOK - Release success + QURT_ENOTALLOWED - Operation not allowed for a pid + QURT_EINVALID - Invalid stid + + @dependencies + None. + */ +int qurt_stid_release(unsigned int pid, unsigned int stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_STID_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread.h new file mode 100755 index 0000000000000..499699e7c72e2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread.h @@ -0,0 +1,1260 @@ +#ifndef QURT_THREAD_H +#define QURT_THREAD_H +/** + @file qurt_thread.h + @brief Prototypes of Thread API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2020-2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +#include +#include "qurt_pmu.h" +#include "qurt_api_version.h" +#endif /* __ASSEMBLER__ */ +#include "qurt_consts.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/* + Bitmask configuration to select DSP hardware threads. + To select all the hardware threads, use #QURT_THREAD_CFG_BITMASK_ALL + and the following: \n + - For QDSP6 V2/V3, all six hardware threads are selected \n + - For QDSP6 V3L, all four hardware threads are selected \n + - For QDSP6 V4, all three hardware threads are selected + */ + +#define QURT_THREAD_CFG_BITMASK_HT0 0x00000001 /**< HTO. */ +#define QURT_THREAD_CFG_BITMASK_HT1 0x00000002 /**< HT1. */ +#define QURT_THREAD_CFG_BITMASK_HT2 0x00000004 /**< HT2. */ +#define QURT_THREAD_CFG_BITMASK_HT3 0x00000008 /**< HT3. */ +#define QURT_THREAD_CFG_BITMASK_HT4 0x00000010 /**< HT4. */ +#define QURT_THREAD_CFG_BITMASK_HT5 0x00000020 /**< HT5. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{sec:qurt_thread_cfg} */ + +#define QURT_THREAD_CFG_BITMASK_ALL 0x000000ffU /**< Select all the hardware threads. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_CFG_USE_RAM 0x00000000 /**< Use RAM. */ +#define QURT_THREAD_CFG_USE_TCM 0x00000100 /**< Use TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_BUS_PRIO_DISABLED 0 /**< Thread internal bus priority disabled. */ +#define QURT_THREAD_BUS_PRIO_ENABLED 1 /**< Thread internal bus priority enabled. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_AUTOSTACK_DISABLED 0 /**< Thread has autostack v2 feature disabled. */ +#define QURT_THREAD_AUTOSTACK_ENABLED 1 /**< Thread has autostack v2 feature enabled. */ + +/* + Macros for QuRT thread attributes. + */ +#define QURT_HTHREAD_L1I_PREFETCH 0x1 /**< Enables hardware L1 instruction cache prefetching. */ +#define QURT_HTHREAD_L1D_PREFETCH 0x2 /**< Enables hardware L1 data cache prefetching. */ +#define QURT_HTHREAD_L2I_PREFETCH 0x4 /**< Enables hardware L2 instruction cache prefetching. */ +#define QURT_HTHREAD_L2D_PREFETCH 0x8 /**< Enables hardware L2 data cache prefetching. */ +#define QURT_HTHREAD_DCFETCH 0x10 /**< Enables DC fetch to the provided virtual address. + DC fetch indicates the hardware that a data memory access is likely. + Instructions are dropped when there is high bus utilization. */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{hdr:partition_tcm} */ +/* + Below value is used to create legacy QuRT threads by default. + If a thread has this as the detach_state, the thread can be joined + on until it exits. When we are able to change default behavior of all + QuRT threads to JOINABLE (posix default), we can remove this legacy + behavior. +*/ +#define QURT_THREAD_ATTR_CREATE_LEGACY 0U /**< Create a legacy QuRT thread by default. If a thread has this as a detach state, the thread can be joined on until it exits. */ +#define QURT_THREAD_ATTR_CREATE_JOINABLE 1U /**< Create a joinable thread. */ +#define QURT_THREAD_ATTR_CREATE_DETACHED 2U /**< Create a detached thread. */ +/** @} */ /* end_addtogroup thread_macros */ + + +#define QURT_THREAD_ATTR_NAME_MAXLEN 16 /**< Maximum name length. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_RAM 0 /**< Creates threads in RAM/DDR. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_TCM 1 /**< Creates threads in TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT QURT_THREAD_ATTR_TCB_PARTITION_RAM /**< Backward compatibility. */ +#define QURT_THREAD_ATTR_PRIORITY_DEFAULT 254 /**< Priority.*/ +#define QURT_THREAD_ATTR_ASID_DEFAULT 0 /**< ASID. */ +#define QURT_THREAD_ATTR_AFFINITY_DEFAULT (-1) /**< Affinity. */ +#define QURT_THREAD_ATTR_BUS_PRIO_DEFAULT 255 /**< Bus priority. */ +#define QURT_THREAD_ATTR_AUTOSTACK_DEFAULT 0 /**< Default autostack v2 disabled thread. */ +#define QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT (-2) /**< Timetest ID. */ +#define QURT_THREAD_ATTR_STID_DEFAULT QURT_STID_DEFAULT /**< STID. */ +#define QURT_THREAD_ATTR_STID_ENABLE 1 /**< Indicate to allocate STID during thread creation. */ + +#define QURT_PRIORITY_FLOOR_DEFAULT 255U /**< Default floor. */ +/** @} */ /* end_addtogroup thread_macros */ + +// Option for suspending thread +#define QURT_THREAD_SUSPEND_SYNCHRONOUS 0x0U // bit#0 +#define QURT_THREAD_SUSPEND_ASYNCHRONOUS 0x1U // bit#0 +#define QURT_THREAD_SUSPEND_KEEP_HMX 0x0U // bit#1 +#define QURT_THREAD_SUSPEND_DETACH_HMX 0x2U // bit#1 + +// Option for resuming thread +#define QURT_THREAD_RESUME_DEFAULT 0x0 + +// Thread property IDs +#define QURT_THREAD_PROPERTY_SUSPENDABLE 0x0U +#define QURT_THREAD_PROPERTY_RESUMABLE 0x1 + +// Thread group +#define QURT_THREAD_DEFAULT_GROUP_ID 0x0U +#define QURT_THREAD_GROUP_ID_MASK 0x3FU + +/** @endcond*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup thread_types +@{ */ +/** @cond rest_reg_dist */ +typedef unsigned int qurt_cache_partition_t; /**< QuRT cache partition type. */ + +#define CCCC_PARTITION 0U /**< Use the CCCC page attribute bits to determine the main or auxiliary partition. */ +#define MAIN_PARTITION 1U /**< Use the main partition. */ +#define AUX_PARTITION 2U /**< Use the auxiliary partition. */ +#define MINIMUM_PARTITION 3U /**< Use the minimum. Allocates the least amount of cache (no-allocate policy possible) for this thread. */ +/** @endcond */ + +/** Thread ID type. */ +typedef unsigned int qurt_thread_t; + +/** @cond rest_reg_dist */ +/** Thread attributes. */ +typedef struct _qurt_thread_attr { + + char name[QURT_THREAD_ATTR_NAME_MAXLEN]; /**< Thread name. */ + unsigned char tcb_partition; /**< Indicates whether the thread TCB resides in RAM or + on chip memory (TCM). */ + unsigned char stid; /**< Software thread ID used to configure the stid register + for profiling purposes. */ + unsigned short priority; /**< Thread priority. */ + unsigned char autostack:1; /**< Autostack v2 enabled thread. */ + unsigned char group_id:6; /**< Group ID. */ + unsigned char reserved:1; /**< Reserved bits. */ + unsigned char bus_priority; /**< Internal bus priority. */ + unsigned short timetest_id; /**< Timetest ID. */ + unsigned int stack_size; /**< Thread stack size. */ + void *stack_addr; /**< Pointer to the stack address base. The range of the stack is + (stack_addr, stack_addr+stack_size-1). */ + unsigned short detach_state; /**< Detach state of the thread. */ + +} qurt_thread_attr_t; +/** @endcond */ + +/** @cond rest_reg_dist */ +/** Dynamic TLS attributes. */ +typedef struct qurt_tls_info { + unsigned int module_id; /**< Module ID of the loaded dynamic linked library. */ + unsigned int tls_start; /**< Start address of the TLS data. */ + unsigned int tls_data_end; /**< End address of the TLS RW data. */ + unsigned int tls_end; /**< End address of the TLS data. */ +}qurt_tls_info; +/** @endcond */ + +/** @} */ /* end_addtogroup thread_types */ + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_thread_attr_init + Initializes the structure used to set the thread attributes when a thread is created. + After an attribute structure is initialized, Explicity set the individual attributes in the structure + using the thread attribute operations. + + The initialize operation sets the following default attribute values: \n + - Name -- NULL string \n + - TCB partition -- QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT + - Priority -- QURT_THREAD_ATTR_PRIORITY_DEFAULT \n + - Autostack -- QURT_THREAD_ATTR_AUTOSTACK_DEFAULT \n + - Bus priority -- QURT_THREAD_ATTR_BUS_PRIO_DEFAULT \n + - Timetest ID -- QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT \n + - stack_size -- 0 \n + - stack_addr -- NULL \n + - detach state -- #QURT_THREAD_ATTR_CREATE_LEGACY \n + - STID -- #QURT_THREAD_ATTR_STID_DEFAULT + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_init (qurt_thread_attr_t *attr) +{ + + attr->name[0] = '\0'; + attr->tcb_partition = QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT; + attr->priority = QURT_THREAD_ATTR_PRIORITY_DEFAULT; + attr->autostack = QURT_THREAD_ATTR_AUTOSTACK_DEFAULT; /* Default attribute for autostack v2*/ + attr->bus_priority = QURT_THREAD_ATTR_BUS_PRIO_DEFAULT; + attr->timetest_id = (unsigned short)QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT; + attr->stack_size = 0; + attr->stack_addr = NULL; + attr->detach_state = QURT_THREAD_ATTR_CREATE_LEGACY; + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + attr->group_id = QURT_THREAD_DEFAULT_GROUP_ID; +} + +/**@ingroup func_qurt_thread_attr_set_name + Sets the thread name attribute.\n + This function specifies the name to use by a thread. + Thread names identify a thread during debugging or profiling. + Maximum name length is 16 charactes \n + @note1hang Thread names differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] name Pointer to the character string containing the thread name. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_name (qurt_thread_attr_t *attr, const char *name) +{ + strlcpy (attr->name, name, QURT_THREAD_ATTR_NAME_MAXLEN); + attr->name[QURT_THREAD_ATTR_NAME_MAXLEN - 1] = '\0'; +} + + +/**@ingroup func_qurt_thread_attr_set_tcb_partition + Sets the thread TCB partition attribute. + Specifies the memory type where a TCB of a thread is allocated. + Allocates TCBs in RAM or TCM/LPM. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] tcb_partition TCB partition. Values:\n + - 0 -- TCB resides in RAM \n + - 1 -- TCB resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_tcb_partition (qurt_thread_attr_t *attr, unsigned char tcb_partition) +{ + attr->tcb_partition = tcb_partition; +} + +/**@ingroup func_qurt_thread_attr_set_priority + Sets the thread priority to assign to a thread. + Thread priorities are specified as numeric values in the range 1 to 254, with 1 representing + the highest priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] priority Thread priority. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_priority (qurt_thread_attr_t *attr, unsigned short priority) +{ + attr->priority = priority; +} + +/**@ingroup func_qurt_thread_attr_set_detachstate + Sets the thread detach state with which thread is created. + Thread detach state is either joinable or detached; specified by the following values: + - #QURT_THREAD_ATTR_CREATE_JOINABLE \n + - #QURT_THREAD_ATTR_CREATE_DETACHED \n + + When a detached thread is created (QURT_THREAD_ATTR_CREATE_DETACHED), its thread + ID and other resources are reclaimed as soon as the thread exits. When a joinable thread + is created (QURT_THREAD_ATTR_CREATE_JOINABLE), it is assumed that some + thread waits to join on it using a qurt_thread_join() call. + By default, detached state is QURT_THREAD_ATTR_CREATE_LEGACY + If detached state is QURT_THREAD_ATTR_CREATE_LEGACY then other + thread can join before thread exits but it will not wait other thread to join. + + @note1hang For a joinable thread (QURT_THREAD_ATTR_CREATE_JOINABLE), it is very + important that some thread joins on it after it terminates, otherwise + the resources of that thread are not reclaimed, causing memory leaks. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] detachstate Thread detach state. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_detachstate (qurt_thread_attr_t *attr, unsigned short detachstate) +{ + if(detachstate == QURT_THREAD_ATTR_CREATE_JOINABLE || detachstate == QURT_THREAD_ATTR_CREATE_DETACHED){ + attr->detach_state = detachstate; + } +} + + +/**@ingroup func_qurt_thread_attr_set_timetest_id + Sets the thread timetest attribute.\n + Specifies the timetest identifier to use by a thread. + + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] timetest_id Timetest identifier value. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_thread_attr_set_timetest_id (qurt_thread_attr_t *attr, unsigned short timetest_id) +{ + attr->timetest_id = timetest_id; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute.\n + Specifies the size of the memory area to use for a call stack of a thread. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_size Size (in bytes) of the thread stack. + + @return + None. + + @dependencies + None. +*/ + +static inline void qurt_thread_attr_set_stack_size (qurt_thread_attr_t *attr, unsigned int stack_size) +{ + attr->stack_size = stack_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size2 + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute for island threads that require a higher guest OS stack size than the stack size + defined in the configuration XML.\n + Specifies the size of the memory area to use for a call stack of an island thread in User and Guest mode. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] user_stack_size Size (in bytes) of the stack usage in User mode. + @param[in] root_stack_size Size (in bytes) of the stack usage in Guest mode. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_size2 (qurt_thread_attr_t *attr, unsigned short user_stack_size, unsigned short root_stack_size) +{ + union qurt_thread_stack_info{ + unsigned int raw_size; + struct{ + unsigned short user_stack; + unsigned short root_stack; + }; + }user_root_stack_size; + user_root_stack_size.user_stack = user_stack_size; + user_root_stack_size.root_stack = root_stack_size; + + attr->stack_size = user_root_stack_size.raw_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_addr + @xreflabel{sec:set_stack_addr} + Sets the thread stack address attribute. \n + Specifies the base address of the memory area to use for a call stack of a thread. + + stack_addr must contain an address value that is 8-byte aligned. + + The thread stack address and stack size (Section @xref{sec:set_stack_size}) specify the memory area used as a + call stack for the thread. \n + @note1hang The user is responsible for allocating the memory area used for the thread + stack. The memory area must be large enough to contain the stack that the thread + creates. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_addr Pointer to the 8-byte aligned address of the thread stack. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_addr (qurt_thread_attr_t *attr, void *stack_addr) +{ + attr->stack_addr = stack_addr; +} + +/**@ingroup func_qurt_thread_attr_set_bus_priority + Sets the internal bus priority state in the Hexagon core for this software thread attribute. + Memory requests generated by the thread with bus priority enabled are + given priority over requests generated by the thread with bus priority disabled. + The default value of bus priority is disabled. + + @note1hang Sets the internal bus priority for Hexagon processor version V60 or greater. + The priority is not propagated to the bus fabric. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + + @param[in] bus_priority Enabling flag. Values: \n + - #QURT_THREAD_BUS_PRIO_DISABLED \n + - #QURT_THREAD_BUS_PRIO_ENABLED @tablebulletend + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_bus_priority ( qurt_thread_attr_t *attr, unsigned short bus_priority) +{ + attr->bus_priority = (unsigned char)bus_priority; +} + +/**@ingroup func_qurt_thread_attr_set_autostack + Enables autostack v2 feature in the thread attributes. + + When autostack is enabled by the subsystem, in the case that + an autostack enabled thread gets framelimit exception, kernel will + allocate more stack for thread and return to normal execution. + + If autostack is not enabled by the subsystem, or it is not enabled + for the thread, the framelimit exception will be fatal. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] autostack Autostack enable or disable flag. Values: \n + - #QURT_THREAD_AUTOSTACK_DISABLED \n + - #QURT_THREAD_AUTOSTACK_ENABLED @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_autostack ( qurt_thread_attr_t *attr, unsigned short autostack) +{ + attr->autostack = (unsigned char)autostack; +} +/**@ingroup qurt_thread_attr_enable_stid + Set STID in the thread attributes. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] enable_stid STID to be set. Values: \n + - #QURT_THREAD_ATTR_STID_DEFAULT (0): Default STID. \n + - #QURT_THREAD_ATTR_STID_ENABLE (1): QuRT assigns an STID that is not already in use \n + - #2 through #255 : User provided STID. @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_enable_stid ( qurt_thread_attr_t *attr, char enable_stid) +{ + if (enable_stid != '\0') { + attr->stid = enable_stid; + } + else + { + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + } +} + +/**@ingroup func_qurt_thread_attr_set_stid + Sets the stid thread attribute. + The default stid value is QURT_THREAD_ATTR_STID_DEFAULT + + @note1hang When a thread is created with non default stid , + the stid set in thread attribute will be assigned to a thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] stid Stid to be set for a thread. + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stid( qurt_thread_attr_t *attr, unsigned int stid){ + attr->stid = stid; +} + +/**@ingroup func_qurt_thread_attr_set_group_id + Sets group id in the thread attributes. + Primordial/first thread has group ID 0. + If a new thread is created without assigning group_id, it + inherits the group ID from its parent thread. + + @note1hang + 1) Group ID can only be set before creating a thread. It cannot be + changed after the thread is created. + 2) If a non-activated group_id is passed, thread creation will fail. + 3) Only a thread with Group ID #0 can set Group ID for its child threads. + 4) If thread with non-zero group ID set the group ID for its child threads, + QuRT will ingore this parameter and child threads will inherit the parent + thread's group ID. But if passed group ID is not activated, thread creation + will still fail. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] group_id Group identifier. Its valid range is 0 ~ 63 + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_group_id(qurt_thread_attr_t *attr, unsigned int group_id) +{ + attr->group_id = group_id & QURT_THREAD_GROUP_ID_MASK; +} + +/**@ingroup func_qurt_thread_set_autostack + Sets autostack enable in the TCB. + + @param[in] Pointer to UGP + + @return + None. + + @dependencies + None. +*/ + +void qurt_thread_set_autostack(void *); + + +/**@ingroup func_qurt_thread_get_name + Gets the thread name of current thread.\n + Returns the thread name of the current thread. + Thread names are assigned to threads as thread attributes, see qurt_thread_attr_set_name(). Thread names + identify a thread during debugging or profiling. + + @param[out] name Pointer to a character string, which specifies the address where the returned thread name is stored. + @param[in] max_len Maximum length of the character string that can be returned. + + @return + None. + + @dependencies + None. +*/ +void qurt_thread_get_name (char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_create + @xreflabel{hdr:qurt_thread_create} + Creates a thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + @param[in] entrypoint C function pointer, which specifies the main function of a thread. + @param[in] arg Pointer to a thread-specific argument structure + + + @return + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_thread_create (qurt_thread_t *thread_id, qurt_thread_attr_t *attr, void (*entrypoint) (void *), void *arg); + +/**@ingroup func_qurt_thread_stop + Stops the current thread, frees the kernel TCB, and yields to the next highest ready thread. + + @return + void + + @dependencies + None. + */ +void qurt_thread_stop(void); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_resume + When a demand-loading paging solution is enabled, this function + will resumes the execution of a thread that was suspended due to + a page miss. + + @param[in] thread_id Thread identifier. + + @return + #QURT_EOK -- Thread successfully resumed. \n + #QURT_EFATAL -- Resume operation failed. + + @dependencies + None. + */ +int qurt_thread_resume(unsigned int thread_id); +/** @endcond */ + +/**@ingroup func_qurt_thread_get_id + Gets the identifier of the current thread.\n + Returns the thread identifier for the current thread. + + @return + Thread identifier -- Identifier of the current thread. + + @dependencies + None. + */ +qurt_thread_t qurt_thread_get_id (void); + + +/**@ingroup func_qurt_thread_get_l2cache_partition + Returns the current value of the L2 cache partition assigned to the caller thread.\n + + @return + Value of the #qurt_cache_partition_t data type. + + @dependencies + None. + */ +qurt_cache_partition_t qurt_thread_get_l2cache_partition (void); + +/**@ingroup func_qurt_thread_set_timetest_id + Sets the timetest identifier of the current thread. + Timetest identifiers are used to identify a thread during debugging or profiling.\n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @param[in] tid Timetest identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_timetest_id (unsigned short tid); + +/**@ingroup func_qurt_thread_set_cache_partition + Sets the cache partition for the current thread. This function uses the qurt_cache_partition_t type + to select the cache partition of the current thread for the L1 Icache, L1 Dcache, and L2 cache. + + @datatypes + #qurt_cache_partition_t + + @param[in] l1_icache L1 I cache partition. + @param[in] l1_dcache L1 D cache partition. + @param[in] l2_cache L2 cache partition. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_cache_partition(qurt_cache_partition_t l1_icache, qurt_cache_partition_t l1_dcache, qurt_cache_partition_t l2_cache); + + +/**@ingroup func_qurt_thread_get_timetest_id + Gets the timetest identifier of the current thread.\n + Returns the timetest identifier of the current thread.\n + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @return + Integer -- Timetest identifier. + + @dependencies + None. + */ +unsigned short qurt_thread_get_timetest_id (void); + +/**@ingroup func_qurt_thread_exit + @xreflabel{sec:qurt_thread_exit} + Stops the current thread, awakens threads joined to it, then destroys the stopped + thread. + + Threads that are suspended on the current thread (by performing a thread join + Section @xref{sec:thread_join}) are awakened and passed a user-defined status value + that indicates the status of the stopped thread. + + @note1hang Exit must be called in the context of the thread to stop. + + @param[in] status User-defined thread exit status value. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_exit(int status); + +/**@ingroup func_qurt_thread_join + @xreflabel{sec:thread_join} + Waits for a specified thread to finish; the specified thread is another thread within + the same process. + The caller thread is suspended until the specified thread exits. When the unspecified thread + exits, the caller thread is awakened. \n + @note1hang If the specified thread has already exited, this function returns immediately + with the result value #QURT_ENOTHREAD. \n + @note1cont Two threads cannot call qurt_thread_join to wait for the same thread to finish. + If this occurs, QuRT generates an exception (see Section @xref{sec:exceptionHandling}). + + @param[in] tid Thread identifier. + @param[out] status Destination variable for thread exit status. Returns an application-defined + value that indicates the termination status of the specified thread. + + @return + #QURT_ENOTHREAD -- Thread has already exited. \n + #QURT_EOK -- Thread successfully joined with valid status value. + + @dependencies + None. + */ +int qurt_thread_join(unsigned int tid, int *status); + +/**@ingroup qurt_thread_detach + @xreflabel{sec:thread_detach} + Detaches a joinable thread. The specified thread is another thread within the + same process. Create the thread as a joinable thread; only joinable threads + can be detached. + If a joinable thread is detached, it finishes execution and exits. + + @param[in] tid Thread identifier. + + @return + #QURT_ENOTHREAD -- Thread specifed by TID does not exist. \n + #QURT_EOK -- Thread successfully detached. + + @dependencies + None. + */ +int qurt_thread_detach(unsigned int tid); + + +/**@ingroup func_qurt_thread_get_priority + Gets the priority of the specified thread. \n + Returns the thread priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. \n + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + + @return + -1 -- Invalid thread identifier. \n + 1 through 254 -- Thread priority value. + + @dependencies + None. + */ +int qurt_thread_get_priority (qurt_thread_t threadid); + +/**@ingroup func_qurt_thread_set_priority + Sets the priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. For more + information, see Section @xref{sec:AppDev}. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + @param[in] newprio New thread priority value. + + @return + 0 -- Priority successfully set. \n + -1 -- Invalid thread identifier. \n + + @dependencies + None. + */ +int qurt_thread_set_priority (qurt_thread_t threadid, unsigned short newprio); + + + +/**@ingroup func_qurt_thread_attr_get + Gets the attributes of the specified thread. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[out] attr Pointer to the destination structure for thread attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid argument. + + @dependencies + None. + */ +int qurt_thread_attr_get (qurt_thread_t thread_id, qurt_thread_attr_t *attr); + + + +/**@ingroup func_qurt_thread_get_tls_base + Gets the base address of thread local storage (TLS) of a dynamically loaded module + for the current thread. + + @datatypes + #qurt_tls_info + + @param[in] info Pointer to the TLS information for a module. + + @return + Pointer to the TLS object for the dynamically loaded module.\n + NULL -- TLS information is invalid. + + @dependencies + None. + */ +void * qurt_thread_get_tls_base(qurt_tls_info* info); + +/**@ingroup func_qurt_thread_pktcount_get + Gets the PKTCOUNT of a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + PKTCOUNT + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_get (qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_pktcount_set + Sets the PKTCOUNT for the current QuRT thread. + + @return + Value to which pktcount is set. + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_set (long long int); + +/**@ingroup func_qurt_thread_stid_get + Gets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + STID + + @dependencies + None. + */ + +char qurt_thread_stid_get(qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_stid_get2 + Returns the set stid for a thread + + @param[in] thread_id thread identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - success + QURT_ENOTALLOWED - operation not allowed for a thread + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_thread_stid_get2(unsigned int thread_id, unsigned int *stid); + +/**@ingroup func_qurt_thread_stid_set + Sets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] stid Thread identifier. + + @return + #QURT_EOK -- STID set created. \n + #QURT_EFAILED -- STID not set. + + @dependencies + None. + */ + +int qurt_thread_stid_set(char stid); + +/**@ingroup qurt_thread_stid_set2 + Sets the stid for a specified thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[in] stid Stid to be set for a thread. + + @return + QURT_EOK -- Success + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_EVAL -- Failure because of invalid inputs. + + @dependencies + None. +*/ +int qurt_thread_stid_set2(unsigned int thread_id, unsigned int stid); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_get_running_ids + Returns the thread IDs of the running threads in the system; use only during fatal error handling. + + @datatypes + #qurt_thread_t + + @param[in,out] * Array of thread identifier of size #QURT_MAX_HTHREAD_LIMIT + 1. + + @return + #QURT_EINVALID -- Incorrect argument \n + #QURT_ENOTALLOWED -- API not called during error handling \n + #QURT_EOK -- Success, returns a NULL-terminated array of thread_id + + @dependencies + None. + */ +int qurt_thread_get_running_ids(qurt_thread_t *); +/** @endcond */ + + +/**@ingroup func_qurt_thread_get_thread_id + Gets the thread identifier of the thread with the matching name in the same process + of the caller. + + @datatypes + #qurt_thread_t + + @param[out] thread_id Pointer to the thread identifier. + @param[in] name Pointer to the name of the thread. + + @return + #QURT_EINVALID -- No thread with matching name in the process of the caller \n + #QURT_EOK -- Success + + @dependencies + None. + */ +int qurt_thread_get_thread_id (qurt_thread_t *thread_id, char *name); + +/**@ingroup func_qurt_sleep + Suspends the current thread for the specified amount of time. + + @note1hang Because QuRT timers are deferrable, this call is guaranteed to block + at least for the specified amount of time. If power-collapse is + enabled, the maximum amount of time this call can block depends on + the earliest wakeup from power-collapse past the specified duration. + + @param[in] duration Duration (in microseconds) for which the thread is suspended. + + @return + None. + + @dependencies + None. + */ +void qurt_sleep (unsigned long long int duration); + + +/**@ingroup func_qurt_system_set_priority_floor + Sets a priority floor to move threads with thread priority lower than the floor out of the running state. + Running threads with thread priority lower than the priority floor are moved into the kernel ready queue, and they + are not scheduled to run when the thread priority is lower than the floor. + Later the caller should reset the priority floor back to the default value of QURT_PRIORITY_FLOOR_DEFAULT. + Threads in the kernel ready queue are scheduled to run when the thread priority is higher than the floor. + + The priority floor is set and associated to the user process of the caller. When the caller gets into QuRTOS and + sets a new floor, the new floor is associated to its original user process, not the QuRTOS process. + The floor associated to the user process is reset when the user process exits or is killed, but not at the time + when the user thread of the caller exits. + + The priority floor cannot be set to a priority higher than the thread priority of the caller. + + The priority floor cannot be set to a priority lower than the default #QURT_PRIORITY_FLOOR_DEFAULT system floor. + + This function is not supported in Island mode. + + After the system floor is set above QURT_PRIORITY_FLOOR_DEFAULT, power collapse is skipped, and sleep task + is not scheduled to run. + + @param[in] priority_floor Priority floor. + + @return + #QURT_EOK -- Success \n + #QURT_ENOTALLOWED -- Floor setting is not allowed + + @dependencies + None. + */ +int qurt_system_set_priority_floor (unsigned int priority_floor); + + +/**@ingroup func_qurt_thread_suspend_thread + Suspend a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent process. + After the target thread is suspended, the kernel will not schedule it to run until it is resumed later. + + If the target thread is set as non-suspendable, this function call returns an error without suspending + the target thread. + + If the target thread is already suspended, this function call returns success to confirm + the target thread suspend. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + suspending the target thread. + + If the target thread is running in the guest OS/root process via a QDI call, this function call does not suspend + the target thread in guest OS, but marks the target thread as suspend-pending. The target thread is + suspended when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success even with the #QURT_THREAD_SUSPEND_SYNCHRONOUS option, while the target + thread can runn in the guest OS, and is suspended when exiting the guest OS. + + QuRT debug monitor threads that are in a user process are non-suspendable. This function does not suspend + those threads. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, multiple options can be ORed. \n + #QURT_THREAD_SUSPEND_SYNCHRONOUS (default) -- set to synchronous function call, + the function returns after the thread is completely suspended.\n + #QURT_THREAD_SUSPEND_ASYNCHRONOUS -- set to asynchronous function call, the function returns + after the kernel acts to suspend the target thread. The target thread + might still be running before it is completely suspended. \n + #QURT_THREAD_SUSPEND_KEEP_HMX (default) -- keep the HMX attachment on the target thread + if it locks the HMX with qurt_hmx_lock(). In this case, the HMX cannot be re-used by other threads. \n + #QURT_THREAD_SUSPEND_DETACH_HMX -- detach HMX from the target thread if it locks the HMX with qurt_hmx_lock(). + Later when the target thread resumes, the HMX is re-attached to the thread. Note that, this option is only + supported for the caller from the same user process of the target thread, not for a caller from the parent + process of the target thread, or other processes. With the HMX detach option, Qurt does not save the HMX + context. Thus, the HMX context state will be lost. It is the responsibility of caller to ensure HMX operations + and its context state saving when calling qurt_thread_suspend_thread() with the HMX detach option. + If a thread from another process uses this detach option, QURT_EHMXNOTDETACHABLE will be returned; in this + case, if the caller is qualified to suspend the target thread, the target thread will be moved to suspended + state without HMX detached. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in secure process/CPZ process. + #QURT_EHMXNOTDETACHABLE -- Failure because HMX is not detachable from the target thread. + + @dependencies + None. + */ +int qurt_thread_suspend_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_resume_thread + Resume a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent + process. After the target thread resumes, the kernel scheduler can schedule the thread to run based on + the thread priority. + + There is an option argument in this function, with only one default option as of now, + QURT_THREAD_RESUME_DEFAULT: resume the target thread in default way. + + By default, this is an asynchronous function. The function returns after kernel moves the + target thread from suspended state to runnable state. The thread is scheduled to run based on its + thread priority. + + If the target thread is set as non-resumable, this function call does not resume the target thread. + + If the target thread has already resumed, this function confirms that the target thread resumes + by returning success. + + If the target thread is in a secure user process or CPZ process, this function call returns an error without + resuming the operation. + + If the target thread runs in the guest OS/root process via a QDI call, this function call clears the mark of + suspend-pending on the target thread, and the target thread is not suspended when it exits the + guest OS. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, #QURT_THREAD_RESUME_DEFAULT, which resumes the target thread. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + #QURT_EHMXNOTAVAIL -- Failure because when resume a HMX thread, the HMX is not available/free for the HMX thread resume. + + @dependencies + None. + */ +int qurt_thread_resume_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_set_thread_property + Set a QuRT thread property with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be from the same user process of the target thread, or from its parent process. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + changing the property of the target thread. + + @param[in] thread_id Thread identifier \n + @param[in] property_id Thread property identifier \n + #QURT_THREAD_PROPERTY_SUSPENDABLE -- thread is suspendable. Default is TRUE. \n + #QURT_THREAD_PROPERTY_RESUMEABLE -- thread is resumable. Default is TRUE + @param[in] value Proper value: \n + TRUE(1) -- TRUE for the property \n + FALSE(0) -- FALSE for the property + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_thread_set_thread_property( unsigned int thread_id, unsigned int property_id, unsigned int value ); + +/**@ingroup func_qurt_thread_get_group_id + Get the group id of the thread specified by thread_id.\n + + @param[in] thread_id Thread identifier + @param[out] group_id Pointer to the variable of group identifier + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Thread id is invalid, or the process has no groups enabled \n + #QURT_ENOTALLOWED -- Operation is not allowed \n + + @dependencies + None. +*/ +int qurt_thread_get_group_id(qurt_thread_t thread_id, unsigned int* group_id); + +#endif /* __ASSEMBLER__ */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread_context.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread_context.h new file mode 100755 index 0000000000000..bab09deec8889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_thread_context.h @@ -0,0 +1,234 @@ +#ifndef QURT_THREAD_CONTEXT_H +#define QURT_THREAD_CONTEXT_H +/** + @file qurt_thread_context.h + @brief Kernel thread context structure + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond internal_only */ + +#define THREAD_ITERATOR_END ((qurt_thread_t)(-1)) /**< Thread iterator is complete. */ + + +/**@ingroup func_qurt_thread_iterator_create +Gives the ability to the caller to enumerate threads in the system. + +@return +Handle of the newly created iterator must be passed for +subsequent operations on the iterator. + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_create(void) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_OS_THREAD_ITERATOR_CREATE); +} + +/**@ingroup func_qurt_thread_iterator_next +Iterates over the list of threads in the system. + +@datatypes +#qurt_thread_t + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#THREAD_ITERATOR_END -- iterator has reached the end of the thread list. \n +Other values indicate a valid thread_id. + +@dependencies +None. +*/ +static inline qurt_thread_t qurt_thread_iterator_next(int iter) +{ + return (qurt_thread_t)qurt_qdi_handle_invoke(iter, QDI_OS_THREAD_ITERATOR_NEXT); +} + +/**@ingroup func_qurt_thread_iterator_destroy +Cleans up thread iterator resources. + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#QURT_EOK -- Successful completion of operation \n +#QURT_EFATAL -- Invalid handle passed + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_destroy(int iter) +{ + return qurt_qdi_close(iter); +} + +/**@ingroup func_qurt_thread_context_get_tname +Gets the name of the thread from the specified thread ID. + +@param[in] thread_id Thread for which name is returned. +@param[in,out] name Pointer to the local buffer where name is copied back. +@param[in] max_len Size of the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_tname(unsigned int thread_id, char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_context_get_prio +Gets the priority for the specified thread. + +@param[in] thread_id Thread for which priority is returned. +@param[in,out] prio Pointer to the local variable where priority is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_prio(unsigned int thread_id, unsigned char *prio); + +/**@ingroup func_qurt_thread_context_get_pcycles +Gets pcycles for the specified thread. + +@param[in] thread_id Thread for which processor cycles are returned. +@param[in,out] pcycles Pointer to the local variable where processor cycles are written. + +@return +#QURT_EOK -- Success \n +Failure otherwise. + +@dependencies +None. +*/ +int qurt_thread_context_get_pcycles(unsigned int thread_id, unsigned long long int *pcycles); + +/**@ingroup func_qurt_thread_context_get_stack_base +Gets the stack base address for the specified thread. + +@param[in] thread_id Thread for which stack base address is returned. +@param[in,out] sbase Pointer to the local variable where stack base address is written. + +@return +QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_base(unsigned int thread_id, unsigned int *sbase); + +/**@ingroup func_qurt_thread_context_get_stack_size +Gets the stack size for the specified thread. + +@param[in] thread_id Thread for which stack size is returned. +@param[in,out] ssize Pointer to the local variable where stack size is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_size(unsigned int thread_id, unsigned int *ssize); + +/**@ingroup func_qurt_thread_context_get_pid +Gets the process ID for the specified thread. + +@param[in] thread_id Thread for which process ID is returned. +@param[in,out] pid Pointer to the local variable where process id is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pid(unsigned int thread_id, unsigned int *pid); + +/**@ingroup func_qurt_thread_context_get_pname +Gets the process name for the specified thread. + +@param[in] thread_id Represents the thread for which process name is returned. +@param[in, out] name Pointer to the local buffer where process name is copied back. +@param[in] len Length allocated to the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pname(unsigned int thread_id, char *name, unsigned int len); + +/** @addtogroup thread_types +@{ */ +/** Structure that defines how TCB is interpreted to crash dump tools.*/ +/* Keys are defined in consts.h */ +struct qurt_debug_thread_info { +/** @cond */ + char name[QURT_MAX_NAME_LEN]; /**< Name of the thread. */ + struct { + unsigned key; + unsigned val; + } os_info[40]; + unsigned gen_regs[32]; /**< General mode registers. */ + unsigned user_cregs[32]; /**< User mode registers. */ + unsigned guest_cregs[32]; /**< Guest mode registers. */ + unsigned monitor_cregs[64]; /**< Monitor mode registers. */ +/** @endcond */ +}; /* should add up to 1K */ +/** @} */ /* end_addtogroup thread_types */ + + +/**@ingroup func_qurt_system_tcb_dump_get +Cleans up thread iterator resources. + +@datatypes +#qurt_thread_t + +@param[in] thread_id Thread on which the operation must be performed. +@param[in, out] ptr Pointer to the local buffer where contents are written. +@param[in] size Size of the debug thread information structure obtained by calling + qurt_system_tcb_dump_get_size(). + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_system_tcb_dump_get(qurt_thread_t thread_id, void *ptr, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_CONTEXT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_timer.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_timer.h new file mode 100755 index 0000000000000..7bdfdb8f3c3df --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_timer.h @@ -0,0 +1,560 @@ +#ifndef QURT_TIMER_H +#define QURT_TIMER_H +/** + @file qurt_timer.h + @brief Prototypes of qurt_timer API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include "qurt_anysignal.h" +#include "qurt_signal2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@addtogroup timer_const_macros +@{ */ +/** + Default values. +*/ +/** @xreflabel{hdr:QURT_TIMER_ONESHOT}*/ +#define QURT_TIMER_DEFAULT_TYPE QURT_TIMER_ONESHOT /**< One shot.*/ +#define QURT_TIMER_DEFAULT_DURATION 1000uL /**< Default duration. */ +#define QURT_TIMER_DEFAULT_EXPIRY 0uL /**< Default expiration. */ + +/** + Conversion from microseconds to timer ticks. + */ +#define QURT_TIMER_TIMETICK_FROM_US(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_TIMER_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** Minimum microseconds value is 100 microseconds (sleep timer).*/ +#define QURT_TIMER_MIN_DURATION 100uL + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_TIMER_MAX_DURATION QURT_SYSCLOCK_MAX_DURATION + +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_TIMER_MAX_DURATION_TICKS QURT_SYSCLOCK_MAX_DURATION_TICKS + +/** + Sleep timer error margin for Qtimer is 1,000 ticks ~52 us. +*/ +#define QURT_TIMETICK_ERROR_MARGIN QURT_SYSCLOCK_ERROR_MARGIN + +/* + qurt_timer group defines. +*/ +#define QURT_TIMER_MAX_GROUPS 5U /**< Maximum groups.*/ +#define QURT_TIMER_DEFAULT_GROUP 0U /**< Default groups. */ +/** @} */ /* end_addtogroup timer_const_macros */ + +/** @addtogroup timer_types +@{ */ +/** + QuRT timer types. + */ +typedef enum +{ + QURT_TIMER_ONESHOT = 0, /**< One shot.*/ + /** @xreflabel{hdr:QURT_TIMER_PERIODIC}*/ + QURT_TIMER_PERIODIC /**< Periodic. */ +} qurt_timer_type_t; + + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT timer type.*/ +typedef unsigned int qurt_timer_t; + +/** QuRT timer duration type. */ +typedef unsigned long long qurt_timer_duration_t; + +/** QuRT timer time type. */ +typedef unsigned long long qurt_timer_time_t; + +typedef void (*pfn_t)(void); +/** QuRT timer attribute type. */ +typedef struct +{ + /** @cond */ + unsigned int magic; /**< Magic number to verify the qmsgq_attr_t pointer. */ + + qurt_timer_duration_t duration; /**< Specifies the duration of the new timer. */ + + qurt_timer_time_t expiry; /**< Specifies the absolute expiry of the new timer. */ + + qurt_timer_duration_t remaining; /**< Specifies the remaining time of an active timer. */ + + qurt_timer_type_t type; /**< Specifies the timer type; only #QURT_TIMER_ONESHOT and + #QURT_TIMER_PERIODIC are supported. */ + + unsigned int group; /**< Group number of the timer; the criterion used to disable or enable the set + of timers. */ + pfn_t pFn; /**< Callback other than the signal set */ + /** @endcond */ +} +qurt_timer_attr_t; + +/** @} */ /* end_addtogroup timer_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_timer_stop + @xreflabel{sec:qurt_timer_stop} + Stops a running timer. + The timer must be a one-shot timer. + + @note1hang Restart stopped timers with the timer restart operation, + see Section @xref{sec:qurt_timer_restart}. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one shot timer. \n + #QURT_EMEM -- Out of memory error. + + @dependencies + None. + */ +int qurt_timer_stop (qurt_timer_t timer); + +/**@ingroup func_qurt_timer_restart + @xreflabel{sec:qurt_timer_restart} + Restarts a stopped timer with the specified duration. The timer must be a one-shot timer. + Timers stop after they have expired or after they are explicitly stopped with qurt_timer_stop(). + A restarted timer expires after the specified duration, the starting time is when the function is called. + + @note1hang Timers stop after they have expired or after they are explicitly + stopped with the timer stop operation, see Section @xref{sec:qurt_timer_stop}. + + @datatypes + #qurt_timer_t \n + #qurt_timer_duration_t + + @param[in] timer Timer object. + @param[in] duration Timer duration (in microseconds) before the restarted timer + expires again. + The valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one-shot timer. \n + #QURT_EMEM -- Out-of-memory error. + + @dependencies + None. + */ +int qurt_timer_restart (qurt_timer_t timer, qurt_timer_duration_t duration); + + +/**@ingroup func_qurt_timer_create + Creates a timer.\n + Allocates and initializes a timer object, and starts the timer. + + @note1hang A timer event handler must be defined to wait on the specified signal + to handle the timer event. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t \n + #qurt_anysignal_t + + @param[out] timer Pointer to the created timer object. + @param[in] attr Pointer to the timer attribute structure. + @param[in] signal Pointer to the signal object set when timer expires. + @param[in] mask Signal mask, which specifies the signal to set in the signal object when the + time expires. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to create the timer. \n + #QURT_EINVALID -- One of the arguments in the attr field is invalid. \n + Other error code -- Operation failed. \n + + @dependencies + None. + */ +int qurt_timer_create (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_anysignal_t *signal, unsigned int mask); + +int qurt_timer_create_sig2 (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_timer_attr_init + Initializes the specified timer attribute structure with default attribute values: \n + - Timer duration -- #QURT_TIMER_DEFAULT_DURATION (Section @xref{dox:timers}) \n + - Timer type -- #QURT_TIMER_ONESHOT \n + - Timer group -- #QURT_TIMER_DEFAULT_GROUP + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_init(qurt_timer_attr_t *attr); + + +/*Tech Comm note: removed qurt_timer_attr_set_pfn from documentation 9/10/2020 +@ingroup func_qurt_timer_attr_set_pfn + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + @param[in] pFn pFn. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_pfn(qurt_timer_attr_t *attr, pfn_t pFn); + + +/**@ingroup func_qurt_timer_attr_set_duration + Sets the timer duration in the specified timer attribute structure.\n + + The timer duration specifies the interval (in microseconds) between the creation of the + timer object and the generation of the corresponding timer event. + + The timer duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). Otherwise, the set operation is ignored. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] duration Timer duration (in microseconds). + Valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_attr_set_expiry + Sets the absolute expiry time in the specified timer attribute structure.\n + The timer expiry specifies the absolute time (in microseconds) of the generation of the + corresponding timer event.\n + Timer expiries are relative to when the system first began executing. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_time_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] time Timer expiry. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_expiry(qurt_timer_attr_t *attr, qurt_timer_time_t time); + +/**@ingroup func_qurt_timer_attr_get_duration + Gets the timer duration from the specified timer attribute structure. + The value returned is the duration that was originally set for the timer. + + @note1hang This function does not return the remaining time of an active timer; + use qurt_timer_attr_get_remaining() to get the remaining time. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attributes object + @param[out] duration Pointer to the destination variable for timer duration. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t *duration); + +/**@ingroup func_qurt_timer_attr_get_remaining + Gets the timer remaining duration from the specified timer attribute structure. \n + + The timer remaining duration indicates (in microseconds) how much time remains before + the generation of the next timer event on the corresponding timer. + In most cases this function assumes that the timer attribute structure was obtained by + calling qurt_timer_get_attr(). + + @note1hang This attribute is read-only and thus has no set operation defined for it. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attribute object. + @param[out] remaining Pointer to the destination variable for remaining time. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_remaining(qurt_timer_attr_t *attr, qurt_timer_duration_t *remaining); + +/**@ingroup func_qurt_timer_attr_set_type + Sets the timer type in the specified timer attribute structure. + + The timer type specifies the functional behavior of the timer: \n + - A one-shot timer (#QURT_TIMER_ONESHOT) waits for the specified timer duration + and then generates a single timer event. After this the timer is nonfunctional. \n + - A periodic timer (#QURT_TIMER_PERIODIC) repeatedly waits for the specified + timer duration and then generates a timer event. The result is a series of timer + events with interval equal to the timer duration. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] type Timer type. Values are: \n + - #QURT_TIMER_ONESHOT -- One-shot timer. \n + - #QURT_TIMER_PERIODIC -- Periodic timer. @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_type(qurt_timer_attr_t *attr, qurt_timer_type_t type); + +/**@ingroup func_qurt_timer_attr_get_type + Gets the timer type from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] type Pointer to the destination variable for the timer type. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_type(qurt_timer_attr_t *attr, qurt_timer_type_t *type); + +/**@ingroup func_qurt_timer_attr_set_group + Sets the timer group identifier in the specified timer attribute structure.\n + The timer group identifier specifies the group that the timer belongs to. Timer groups are + used to enable or disable one or more timers in a single operation. \n + The timer group identifier value must be between 0 and (#QURT_TIMER_MAX_GROUPS - 1). + See Section @xref{dox:timers}. + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the timer attribute object. + @param[in] group Timer group identifier; + Valid range is 0 to (#QURT_TIMER_MAX_GROUPS - 1). + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_group(qurt_timer_attr_t *attr, unsigned int group); + +/**@ingroup func_qurt_timer_attr_get_group + Gets the timer group identifier from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] group Pointer to the destination variable for the timer group identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_group(qurt_timer_attr_t *attr, unsigned int *group); + +/**@ingroup func_qurt_timer_get_attr + @xreflabel{hdr:qurt_timer_get_attr} + Gets the timer attributes of the specified timer when it was created. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t + + @param[in] timer Timer object. + @param[out] attr Pointer to the destination structure for timer attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_get_attr(qurt_timer_t timer, qurt_timer_attr_t *attr); + +/**@ingroup func_qurt_timer_delete + Deletes the timer.\n + Destroys the specified timer and deallocates the timer object. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_delete(qurt_timer_t timer); + +/**@ingroup func_qurt_timer_sleep + Suspends the current thread for the specified amount of time. + The sleep duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). + + @datatypes + #qurt_timer_duration_t + + @param[in] duration Interval (in microseconds) between when the thread is suspended + and when it is re-awakened. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to perform the operation. + + @dependencies + None. + */ + +int qurt_timer_sleep(qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_group_disable + Disables all timers that are assigned to the specified timer group. + If a specified timer is already disabled, ignore it. + If a specified timer is expired, do not process it. + If the specified timer group is empty, do nothing. + + @note1hang When a timer is disabled its remaining time does not change, thus it + cannot generate a timer event. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_disable (unsigned int group); + +/**@ingroup func_qurt_timer_group_enable + Enables all timers that are assigned to the specified timer group. + If a specified timer is already enabled, ignore it. + If a specified timer is expired, process it. + If the specified timer group is empty, do nothing. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_enable (unsigned int group); + + +/** + Notifies the timer server recovery from power collapse. The server + must account for any missed interrupts during power collapse. + */ +void qurt_timer_recover_pc (void); + +/** + Determines whether the Qtimer is initialized. + + @return + 0 -- Not initialized. \n + Nonzero -- Initialized. + */ +static inline int qurt_timer_is_init (void) {return 1;} + +/**@ingroup func_qurt_timer_get_ticks + Gets current ticks. The ticks are accumulated since the RTOS + has started. Each tick is equal to a single timer clock + cycle, where the frequency is 32 KHz on RGPT or 19.2 MHz on Qtimer. + + @return + Ticks since system started. + */ +unsigned long long qurt_timer_get_ticks (void); + +#define qurt_timer_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TIMER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tlb.h new file mode 100755 index 0000000000000..b1b2d261d31c0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tlb.h @@ -0,0 +1,215 @@ +#ifndef QURT_TLB_H +#define QURT_TLB_H + +/** + @file qurt_tlb.h + @brief Prototypes of TLB API + The TLB APIs allow explicit control of the portion of TLB between TLB_first_replaceble and TLB_LAST_REPLACEABLE. + Both are nonconfigurable for the time being. This portion of TLB is permanently assigned/locked unless manually removed + by qurt_tlb_remove. Implementation does not change depending on the configuration, such as whether CONFIG_STATIC is set or not. + In CONFIG_STATIC=y, TLB_LAST_REPLACEABLE is set to the last TLB index, which indicates that the entire TLB is permanently + assigned and is not backed up by page table (page table does not exist). TLB indicies are maintained through a 64-bit bitmask. + A new entry is placed in the first available slot. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tlb_entry_create + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (such as if the address is not aligned with the + size), the entry is created and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the ASID argument to -1. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr Physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry is not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry is not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry is not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_t paddr, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_create_64 + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (the address is not aligned with the + size), the entry is not created, and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the asid argument to -1. + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr_64 64-bit physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry was not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry was not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry was not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create_64 (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_delete + Deletes the specified TLB entry from the TLB of the Hexagon processor. + If the specified entry does not exist, no deletion occurs and an error result is returned. + + @param[in] entry_id TLB entry identifier. + + @return + #QURT_EOK -- TLB entry successfully deleted. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_delete (unsigned int entry_id); + +/**@ingroup func_qurt_tlb_entry_query + Searches for the specified TLB entry in the TLB of the Hexagon processor. + If the TLB entry is found, its entry identifier is returned. + + @datatypes + #qurt_addr_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_query (unsigned int *entry_id, qurt_addr_t vaddr, int asid); + +/**@ingroup func_qurt_tlb_entry_set + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[in] entry 64-bit TLB entry to store. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set (unsigned int entry_id, unsigned long long int entry); + +/**@ingroup func_qurt_tlb_entry_get + Gets the TLB entry. \n + Returns the specified 64-bit TLB entry in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[out] entry 64-bit TLB entry. + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_get (unsigned int entry_id, unsigned long long int *entry); + +/**@ingroup func_qurt_tlb_get_pager_physaddrs + Searches the TLB of the Hexagon processor, and returns all physical addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_phys_addrs Pointer to the return array of pager physical addresses. + + @return + Integer -- Number of addresses returned in array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_physaddr(unsigned int** pager_phys_addrs); + +/**@ingroup func_qurt_tlb_get_pager_virtaddr + Searches the TLB of the Hexagon processor, and returns all virtual addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_virt_addrs Pointer to the return array of pager virtual addresses. + + @return + Integer -- Number of addresses returned in the array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_virtaddr(unsigned int** pager_virt_addrs); + + +/**@ingroup func_qurt_tlb_entry_set2 + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. An additional option can be passed + to lock the TLB entry in the TLB of the Hexagon processor. + + @param[in] id TLB entry identifier. + @param[in] tlb 64-bit TLB entry to store. + @param[in] lock Nonzero value indicates that the TLB entry must be locked in the hardware TLB. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set2(unsigned id, unsigned long long tlb, unsigned lock); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLB_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tls.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tls.h new file mode 100755 index 0000000000000..6ec3b39ff5cb0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_tls.h @@ -0,0 +1,100 @@ +#ifndef QURT_TLS_H +#define QURT_TLS_H +/** + @file qurt_tls.h + @brief Prototypes of TLS APIs + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tls_create_key + @xreflabel{sec:tls_create_key} + Creates a key for accessing a thread local storage data item.\n + Subsequent get and set operations use the key value. + + @note1hang The destructor function performs any clean-up operations needed by a thread + local storage item when its containing thread is deleted (Section @xref{sec:qurt_thread_exit}). + + @param[out] key Pointer to the newly created thread local storage key value. + @param[in] destructor Pointer to the key-specific destructor function. Passing NULL + specifies that no destructor function is defined for the key. + + @return + #QURT_EOK -- Key successfully created. \n + #QURT_ETLSAVAIL -- No free TLS key available. + + @dependencies + None. + */ +int qurt_tls_create_key (int *key, void (*destructor)(void *)); + +/**@ingroup func_qurt_tls_set_specific + Stores a data item to thread local storage along with the specified key. + + @param[in] key Thread local storage key value. + @param[in] value Pointer to user data value to store. + + @return + #QURT_EOK -- Data item successfully stored. \n + #QURT_EINVALID -- Invalid key. \n + #QURT_EFAILED -- Invoked from a non-thread context. + */ +int qurt_tls_set_specific (int key, const void *value); + +/**@ingroup func_qurt_tls_get_specific + Loads the data item from thread local storage. \n + Returns the data item that is stored in thread local storage with the specified key. + The data item is always a pointer to user data. + + @param[in] key Thread local storage key value. + + @return + Pointer -- Data item indexed by key in thread local storage. \n + 0 (NULL) -- Key out of range. + + @dependencies + None. + */ +void * __attribute__((section(".text.qurt_tls_get_specific "))) qurt_tls_get_specific (int key); + + +/**@ingroup func_qurt_tls_delete_key + Deletes the specified key from thread local storage. + + @note1hang Explicitly deleting a key does not execute any destructor function that is + associated with the key (Section @xref{sec:tls_create_key}). + + @param[in] key Thread local storage key value to delete. + + @return + #QURT_EOK -- Key successfully deleted. \n + #QURT_ETLSENTRY -- Key already free. + + @dependencies + None. + */ +int qurt_tls_delete_key (int key); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_trace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_trace.h new file mode 100755 index 0000000000000..541f8f1d34bf6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_trace.h @@ -0,0 +1,317 @@ +#ifndef QURT_TRACE_H +#define QURT_TRACE_H +/** + @file qurt_trace.h + @brief Prototypes of system call tracing helpers API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + GLOBAL VARIABLES +=============================================================================*/ +/** @cond internal_only */ +/** @addtogroup etm_macros +@{ */ +/* ETM trace types. */ +#define QURT_ETM_TYPE_PC_ADDR (1U<<0) /**< PC address.*/ +#define QURT_ETM_TYPE_MEMORY_ADDR (1U<<1) /**< Memory address. */ +#define QURT_ETM_TYPE_TESTBUS (1U<<2) /**< Test bus. */ +#define QURT_ETM_TYPE_CYCLE_ACCURATE (1U<<3) /**< Cycle accurate. */ +#define QURT_ETM_TYPE_CYCLE_COARSE (1U<<4) /**< Cycle coarse. */ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR) /**< PC and memory address. */ +#define QURT_ETM_TYPE_PC_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC address and test bus. */ +#define QURT_ETM_TYPE_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< Memory address and test bus.*/ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC, memory address, and test bus. */ + +/* ETM routes. */ +#define QURT_ETM_ROUTE_TO_QDSS 0U /**< ETM route to QDSS. */ +#define QURT_ETM_ROUTE_TO_Q6ETB 1U /**< ETM route to Q6ETB. */ + +/* ETM filters. */ +#define QURT_ETM_TRACE_FILTER_ALL_DEFAULT 0U /*< Filter all as default. */ +#define QURT_ETM_TRACE_FILTER_HNUM0 (1U<<0) /*< Filter HNUM0. */ +#define QURT_ETM_TRACE_FILTER_HNUM1 (1U<<1) /*< Filter HNUM1. */ +#define QURT_ETM_TRACE_FILTER_HNUM2 (1U<<2) /*< Filter HNUM2. */ +#define QURT_ETM_TRACE_FILTER_HNUM3 (1U<<3) /*< Filter HNUM3. */ +#define QURT_ETM_TRACE_FILTER_HNUM4 (1U<<4) /*< Filter HNUM4. */ +#define QURT_ETM_TRACE_FILTER_HNUM5 (1U<<5) /*< Filter HNUM5. */ +#define QURT_ETM_TRACE_FILTER_HNUM6 (1U<<6) /*< Filter HNUM6. */ +#define QURT_ETM_TRACE_FILTER_HNUM7 (1U<<7) /*< Filter HNUM7. */ +#define QURT_ETM_TRACE_FILTER_HNUM8 (1U<<8) /*< Filter HNUM8. */ +#define QURT_ETM_TRACE_FILTER_HNUM9 (1U<<9) /*< Filter HNUM9. */ +#define QURT_ETM_TRACE_FILTER_HNUM10 (1U<<10) /*< Filter HNUM10. */ +#define QURT_ETM_TRACE_FILTER_HNUM11 (1U<<11) /*< Filter HNUM11. */ +#define QURT_ETM_TRACE_FILTER_HNUM12 (1U<<12) /*< Filter HNUM12. */ +#define QURT_ETM_TRACE_FILTER_HNUM13 (1U<<13) /*< Filter HNUM13. */ +#define QURT_ETM_TRACE_FILTER_HNUM14 (1U<<14) /*< Filter HNUM14. */ +#define QURT_ETM_TRACE_FILTER_HNUM15 (1U<<15) /*< Filter HNUM15. */ +#define QURT_ETM_TRACE_FILTER_ALL QURT_ETM_TRACE_FILTER_ALL_DEFAULT + +#define QURT_ETM_TRACE_FILTER_CLUSTER0 (1<<16) /*< Filter trace cluster0 address. */ +#define QURT_ETM_TRACE_FILTER_CLUSTER1 (1<<17) /*< Filter trace cluster1 address. */ +#define QURT_ETM_TRACE_FILTER_PC_RANGE (1<<19) /*< Filter PC address range. */ + +/* ETM memory source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< ETM memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< ETM memory source of SAC* is data. */ + +/* Period between synchronization traces */ +#define QURT_ETM_ASYNC_PERIOD 0 /**< Async.*/ +#define QURT_ETM_ISYNC_PERIOD 1 /**< Isync.*/ +#define QURT_ETM_GSYNC_PERIOD 2 /**< Gsync. */ + +/* ETM enable flags */ +#define QURT_ETM_OFF 0U /**< ETM off. */ +#define QURT_ETM_ON 1U /**< ETM on. */ +/** @endcond */ +/** @} */ /* end_addtogroup etm_macros */ + +/** @addtogroup function_tracing_macro +@{ */ +/* ETM setup return values */ +#define QURT_ETM_SETUP_OK 0 /**< ETM setup OK. */ +#define QURT_ETM_SETUP_ERR 1 /**< ETM setup error. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* ETM breakpoint types */ +#define QURT_ETM_READWRITE_BRKPT 0U /**< ETM read/write breakpoint. */ +#define QURT_ETM_READ_BRKPT 1U /**< ETM read breakpoint. */ +#define QURT_ETM_WRITE_BRKPT 2U /**< ETM write breakpoint. */ +#define QURT_ETM_BRKPT_INVALIDATE 3U /**< Invalidate breakpoint. */ +/** @addtogroup function_tracing_macro +@{ */ +/* ATB status flags */ +#define QURT_ATB_OFF 0 /**< ATB off. */ +#define QURT_ATB_ON 1 /**< ATB on. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* DTM enable flags */ +#define QURT_DTM_OFF 0 /**< DTM off. */ +#define QURT_DTM_ON 1 /**< DTM on. */ + +/** @addtogroup function_tracing_datatypes +@{ */ +/**STM trace information. */ +typedef struct qurt_stm_trace_info { + /** @cond */ + unsigned int stm_port_addr[6]; /* STM port address to which trace data must be written.*/ + unsigned int thread_event_id; /* Event ID for context switches.*/ + unsigned int interrupt_event_id; /* Event ID for interrupts. */ + unsigned int marker; /* Marker value that must be written at the beginning of the trace. */ + /** @endcond */ +} qurt_stm_trace_info_t; +/** @} */ /* end_addtogroup function_tracing_datatypes */ +/*============================================================================= + GLOBAL FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_trace_get_marker + Gets the kernel trace marker.\n + Returns the current value of the kernel trace marker. + The marker consists of a hardware thread identifier and an index into the kernel trace + buffer. The trace buffer records kernel events. + + @note1hang Using this function with qurt_trace_changed() + determines whether certain kernel events occurred in a block of code. + + @return + Integer -- Kernel trace marker. + + @dependencies + None. +*/ +unsigned int qurt_trace_get_marker(void); + +/**@ingroup func_qurt_trace_changed + Determines whether specific kernel events have occurred. \n + Returns a value that indicates whether the specified kernel events are recorded in the + kernel trace buffer since the specified kernel trace marker was obtained. + + The prev_trace_marker parameter specifies a kernel trace marker that was obtained by calling + qurt_trace_get_marker(). + @cond rest_dist For more information on the mask value, see the description of the trace_mask element in + @xhyperref{80VB41992,80-VB419-92}. \n @endcond + + @note1hang Used with qurt_trace_get_marker(), this function determines whether + certain kernel events occurred in a block of code.\n + @note1cont This function cannot determine whether a specific kernel event type has + occurred unless that event type has been enabled in the trace_mask element + of the system configuration file. \n + @note1cont QuRT supports the recording of interrupt and context switch events only (such as + a trace_mask value of 0x3). + + @param[in] prev_trace_marker Previous kernel trace marker. + @param[in] trace_mask Mask value that indicates which kernel events to check for. + + @returns + 1 -- Kernel events of the specified type have occurred since the + specified trace marker was obtained.\n + 0 -- No kernel events of the specified type have occurred since the + specified trace marker was obtained. + + @dependencies + None. +*/ +int qurt_trace_changed(unsigned int prev_trace_marker, unsigned int trace_mask); + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup function_tracing_macro +@{ */ +#ifndef QURT_DEBUG +#define QURT_TRACE(str, ...) __VA_ARGS__ + /**< Function tracing is implemented with the QURT_TRACE debug macro, which + optionally generates printf statements both before and after every function call that is + passed as a macro argument. + + For example, in the following macro calls in the source code: + @code + QURT_TRACE(myfunc, my_func(33)) + + @endcode + generates the following debug output: + @code + myfile:nnn: my_func >>> calling my_func(33) + myfile:nnn: my_func >>> returned my_func(33) + @endcode + The debug output includes the source file and line number of the function call, along with + the text of the call. Compile the client source file with -D __FILENAME__ + defined for its file name. + + The library function qurt_printf() generates the debug output. + The QURT_DEBUG symbol controls generation of the debug output. If this symbol is + not defined, function tracing is not generated.\n + @note1hang The debug macro is accessed through the QuRT API header file. + */ +#else +#define QURT_TRACE(str, ...) \ + do { \ + qurt_printf("%s:%d: %s: >>> calling %s\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + __VA_ARGS__; \ + qurt_printf("%s:%d: %s: <<< %s returned\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + } while (0); +#endif +/** @} */ /* end_addtogroup function_tracing_macro */ + +/**@ingroup func_qurt_etm_set_pc_range + Sets the PC address range for ETM filtering. + Depending on the Hexagon core design, a maximum of four PC ranges are supported. + + @param[in] range_num 0 to 3. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_pc_range(unsigned int range_num, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_range + Sets the address range for ETM filtering. + It allows the user to select the source type of addresses - QURT_ETM_SOURCE_PC and QURT_ETM_SOURCE_DATA. + + @param[in] addr_source_type Type of the address source:\n + - #QURT_ETM_SOURCE_PC \n + - #QURT_ETM_SOURCE_DATA @tablebulletend + @param[in] trig_block_num 0 to 3. + @param[in] pid pid of the process + 1. Any valid PID number will enable the ASID based trace filtering. + 2. QURT_ETM_NO_PID - Disable the ASID based trace filtering. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_range(unsigned int addr_source_type, unsigned int trig_block_num, unsigned int pid, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_atb + Sets the advanced trace bus (ATB) state to notify QuRT that the ATB is actively enabled or disabled. + QuRT performs the corresponding actions at low power management. + + @param[in] flag Values: \n + #QURT_ATB_ON \n + #QURT_ATB_OFF + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure + + @dependencies + None. +*/ +unsigned int qurt_etm_set_atb(unsigned int flag); + +/**@ingroup func_qurt_etm_set_sync_period + Sets the period for types of synchronization trace packets. \n + ASYNC defines the period between alignment synchronization packets. + Period is in terms of bytes in the packet stream. \n + ISYNC defines the period between instruction synchronization packets. + Period is per thread and is defined as the bytes sent out for that thread. \n + GSYNC is the defined period in thread cycles between GSYNC packets. + + @param[in] sync_type Type of synchronization packets: \n + #QURT_ETM_ASYNC_PERIOD \n + #QURT_ETM_ISYNC_PERIOD \n + #QURT_ETM_GSYNC_PERIOD + @param[in] period Period value. + + @return + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. + */ +unsigned int qurt_etm_set_sync_period(unsigned int sync_type, unsigned int period); + +/**@ingroup func_qurt_stm_trace_set_config + Sets up a STM port for tracing events. + + @datatypes + #qurt_stm_trace_info_t + + @param[in] stm_config_info Pointer to the STM trace information used to set up the trace + in the kernel. + The strucure must have the following:\n + - One port address per hardware thread \n + - Event ID for context switches \n + - Event ID for interrupt tracing n + - Header or marker to identify the beginning of the trace. @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Failure; possibly because the passed port address is not in the page table. + + @dependencies + None. + */ +unsigned int qurt_stm_trace_set_config(qurt_stm_trace_info_t *stm_config_info); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TRACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_types.h new file mode 100755 index 0000000000000..bdb83a3fe2fb2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_types.h @@ -0,0 +1,294 @@ +#ifndef QURT_TYPES_H +#define QURT_TYPES_H +/** + @file qurt_types.h + @brief Contains types common to all configurations + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +//#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define PGA_BITFIELD_MASK(hi,lo) (((~0u)>>(31U-((hi)-(lo))))<<(lo)) +#define PGA_BITFIELD_GET(x,hi,lo) (((x)&PGA_BITFIELD_MASK((hi),(lo)))>>(lo)) +#define PGA_BITFIELD_INS(hi,lo,v) (((v)<<(lo))&PGA_BITFIELD_MASK((hi),(lo))) +#define PGA_BITFIELD_SET(x,hi,lo,v) ((x)=((x)&~PGA_BITFIELD_MASK((hi),(lo)))|PGA_BITFIELD_INS((hi),(lo),(v))) +#define QURT_PGATTR_C_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 3U, 0U) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 5U, 4U) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_C_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 3U, 0U, (v)) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 5U, 4U, (v)) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_MKRAW(v) ((qurt_pgattr_t){.pga_value = (v)}) +#define QURT_PGATTR_MK(c,a) QURT_PGATTR_MKRAW(PGA_BITFIELD_INS(3U,0U,(c))|PGA_BITFIELD_INS(5U,4U,(a))) + +/*return types for qurt_island_get_status2*/ +#define QURT_ISLAND_MODE_NORMAL 0U /**< Normal operating mode */ +#define QURT_ISLAND_MODE_ISLAND 1U /**< Island mode */ +#define QURT_ISLAND_MODE_EXITING 2U /**< In transition from Island mode to Normal mode */ + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/** @addtogroup memory_management_types +@{ */ +typedef unsigned int qurt_addr_t; /**< QuRT address type.*/ +typedef unsigned int qurt_paddr_t; /**< QuRT physical memory address type. */ +/** @cond rest_reg_dist */ +typedef unsigned long long qurt_addr_64_t; /**< QuRT 64-bit memory address type. */ +typedef unsigned long long qurt_paddr_64_t; /**< QuRT 64-bit physical memory address type. */ +typedef unsigned int qurt_mem_region_t; /**< QuRT memory regions type. */ +typedef unsigned int qurt_mem_fs_region_t; /**< QuRT memory FS region type. */ +/**@endcond */ +typedef unsigned int qurt_mem_pool_t; /**< QuRT memory pool type.*/ +typedef unsigned int qurt_size_t; /**< QuRT size type. */ +/** @cond */ +typedef unsigned long long qurt_mmu_entry_t;/**< QuRT MMU entry type. */ +#define QURT_PHYSPOOL_NAME_LEN (32) +typedef char qurt_physpool_name_t[QURT_PHYSPOOL_NAME_LEN]; + + +/* + * Mapping type + * + * QMEM_MAPPING_VIRTUAL is the default mode, in which the system + * picks up the available range of the virtual address, and maps it to + * available contiguous physical addresses. Physical-to-virtual + * is not guaranteed to be 1:1; both virtual and physical memory is + * contiguous. + * + * In QMEM_MAPPING_IDEMPOTENT mode, the user provides the physical address; + * the kernel allocates 1:1 physical-to-virtual memory. Primary use of + * of this mapping is to allocate physical-to-virtual memory 1:1. + * + * In QMEM_MAPPING_PHYS_CONTIGUOUS mode, the virtual address might + * not be the same as the physical address. But the physical address of the + * memory region is guaranteed to be contiguous starting at the provided + * address, it is required to provide a fixed physical address. The primary + * use of this mapping is to allocate physical memory from a particular + * address, where 1:1 physical-to-virtual is not required. + * + * QMEM_MAPPING_NONE mode must be used to reserve a virtual memory + * area (VMA); no physical memory is reserved or mapped to this virtual + * space; all standard qmem_region APIs apply to a VMA, however physical + * address is always INVALID_ADDR. qmem_region_create() in this mode + * returns a handle to the VMA, both virt_addr and phys_addr must + * be set to INVALID_ADDR, kernel allocates any available virtual + * memory of the specified size. Obtain the starting virtual address + * of VMA through qmem_region_attr_getvirtaddr(). + * Primary purpose of this mapping mode is to provide a mechanism for + * delayed binding in QuRT, for example reserve virtual memory and map it at + * some later time to possibly discontiguous physical blocks. Thus, a + * single VMA can be partitioned among several physical-virtual mappings + * created via qmem_region_create() with QMEM_VIRTUAL_FIXED mapping mode. + * Each VMA keeps track of associated mapped regions. + * Deletion of VMA succeeds only if all associated "virtual_fixed" + * regions are freed prior to VMA deletion. + * + * Use QMEM_MAPPING_VIRTUAL_FIXED mode to create a region + * from virtual space that has been reserved via qmem_region_create() + * with QMEM_MAPPING_NONE mapping. A valid virt_add is required, if + * phys_addr is specified, the kernel attempts to map it accordingly, + * if no phys_addr is specified, kernel maps any available physical + * memory. All standard qmem_region APIs apply to such region. Remapping + * a virtual range without prior freeing of the region is not permitted. + * When such region is deleted its corresponding VMA remains intact. + * + * QMEM_MAPPING_PHYS_DISCONTIGUOUS mode can obtain contiguous + * virtual memory but physical memory can be discontiguous. This method + * tries to club small physical memory blocks to obtain requested + * memory and is useful in case where there is no contiguous full block + * of requested size. If client does not need contiguous physical memory, + * (for example, if client does not use physical addressing), this helps + * use smaller physical memory blocks rather than using contiguous memory. + * Note: When memory is allocated through this method, physical address is + * not returned to the caller using the qurt_mem_region_attr_get() API as there might + * not be a single physical address. + * + */ +/**@endcond */ +/** QuRT memory region mapping type. */ +typedef enum { + QURT_MEM_MAPPING_VIRTUAL=0, /**< Default mode. The region virtual address range maps to an + available contiguous area of physical memory. For the most + efficient use of virtual memory, the QuRT system + chooses the base address in physical memory. This works for most memory + use cases.*/ + QURT_MEM_MAPPING_PHYS_CONTIGUOUS = 1, /**< The region virtual address space must be mapped to a + contiguous area of physical memory. This is necessary when the + memory region is accessed by external devices that bypass Hexagon + virtual memory addressing. The base address in physical + memory must be explicitly specified.*/ + QURT_MEM_MAPPING_IDEMPOTENT=2, /**< Region virtual address space maps + to the identical area of physical memory. */ + QURT_MEM_MAPPING_VIRTUAL_FIXED=3, /**< Virtual address space of the region maps either to the + specified area of physical memory or (if no area is specified) + to available physical memory. Use this mapping to create + regions from virtual space that was reserved by calling + qurt_mem_region_create() with mapping. */ + QURT_MEM_MAPPING_NONE=4, /**< Reserves a virtual memory area (VMA). Remapping a virtual range is not + permitted without first deleting the memory region. When such a region is + deleted, its corresponding virtual memory addressing remains intact. */ + QURT_MEM_MAPPING_VIRTUAL_RANDOM=7, /**< System chooses a random virtual address and + maps it to available contiguous physical addresses.*/ + QURT_MEM_MAPPING_PHYS_DISCONTIGUOUS=8, /**< While virtual memory is contiguous, allocates in discontiguous physical + memory blocks. This helps when there are smaller contiguous blocks + than the requested size. + Physical address is not provided as part of the get_attr call */ + QURT_MEM_MAPPING_INVALID=10, /**< Reserved as an invalid mapping type. */ +} qurt_mem_mapping_t; + + +/** QuRT cache mode type. */ +typedef enum { + QURT_MEM_CACHE_WRITEBACK=7, /**< Write back. */ + QURT_MEM_CACHE_NONE_SHARED=6, /**< Normal uncached memory that can be shared with other subsystems.*/ + QURT_MEM_CACHE_WRITETHROUGH=5, /**< Write through. */ + QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE=0, /**< Write back non-L2-cacheable.*/ + QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE=1, /**< Write through non-L2-cacheable. */ + QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE=QURT_MEM_CACHE_WRITEBACK, /**< Write back L2 cacheable. */ + QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE=QURT_MEM_CACHE_WRITETHROUGH, /**< Write through L2 cacheable. */ + QURT_MEM_CACHE_DEVICE = 4, /**< Volatile memory-mapped device. Access to device memory cannot be cancelled by interrupts, re-ordered, or replayed.*/ + QURT_MEM_CACHE_NONE = 4, /**< Deprecated -- use #QURT_MEM_CACHE_DEVICE instead. */ + QURT_MEM_CACHE_DEVICE_SFC = 2, /**< Enables placing limitations on the number of outstanding transactions. */ + QURT_MEM_CACHE_INVALID=10, /**< Reserved as an invalid cache type. */ +} qurt_mem_cache_mode_t; + +/** Memory access permission. */ +#define QURT_PERM_NONE 0x0U /**< No permission. */ +#define QURT_PERM_READ 0x1U /**< Read permission. */ +#define QURT_PERM_WRITE 0x2U /**< Write permission. */ +#define QURT_PERM_EXECUTE 0x4U /**< Execution permission. */ +#define QURT_PERM_NODUMP 0x8U + /**< Skip dumping the mapping. During process domain dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and DSP process + crashed before the mapping is removed. */ +#define QURT_PERM_FULL QURT_PERM_READ | QURT_PERM_WRITE | QURT_PERM_EXECUTE /**< Read, write, and execute permission. */ + +typedef unsigned char qurt_perm_t; + + +/** @cond rest_reg_dist*/ +/** QuRT cache type; specifies data cache or instruction cache. */ +typedef enum { + QURT_MEM_ICACHE, /**< Instruction cache.*/ + QURT_MEM_DCACHE /**< Data cache.*/ +} qurt_mem_cache_type_t; + +/** QuRT cache operation code type. */ +typedef enum { + QURT_MEM_CACHE_FLUSH, /**< Flush. */ + QURT_MEM_CACHE_INVALIDATE, /**< Invalidate */ + QURT_MEM_CACHE_FLUSH_INVALIDATE, /**< Flush invalidate. */ + QURT_MEM_CACHE_FLUSH_ALL, /**< Flush all. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_ALL, /**< Flush invalidate all. */ + QURT_MEM_CACHE_TABLE_FLUSH_INVALIDATE, /**< Table flush invalidate. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_L2, /**< L2 flush invalidate.*/ +} qurt_mem_cache_op_t; + +/** QuRT memory region type. */ +typedef enum { + QURT_MEM_REGION_LOCAL=0, /**< Local. */ + QURT_MEM_REGION_SHARED=1, /**< Shared.*/ + QURT_MEM_REGION_USER_ACCESS=2, /**< User access. */ + QURT_MEM_REGION_FS=4, /**< FS. */ + QURT_MEM_REGION_INVALID=10, /**< Reserved as an invalid region type. */ +} qurt_mem_region_type_t; + +/* Cache and bus attributes are combined into a value of this type for convenience, + and macros for combining and extracting fields are defined here. */ +/** @cond */ +struct qurt_pgattr { + unsigned pga_value; /**< PGA value.*/ +}; +typedef struct qurt_pgattr qurt_pgattr_t; +/** @endcond */ +/** QuRT memory region attributes type.*/ +/* QMEM_MAPPING_IDEMPOTENT and QMEM_MAPPING_PHYS_CONTIGUOUS mode can specify physaddr. + virtaddr cannot be specified for a memory region, it can only be queried by the + qmem_attr_getvirtaddr() function. + */ +typedef struct { + /** @cond */ + qurt_mem_mapping_t mapping_type; + unsigned char perms; + unsigned short owner; + qurt_pgattr_t pga; + unsigned ppn; //physical page number (physical>>12) + qurt_addr_t virtaddr; + qurt_mem_region_type_t type; + qurt_size_t size; + /** @endcond */ +} qurt_mem_region_attr_t; + + +/** QuRT user physical memory pool type. */ +typedef struct { + /** @cond */ + char name[32]; + struct ranges{ + unsigned int start; + unsigned int size; + } ranges[MAX_POOL_RANGES]; + /** @endcond */ +} qurt_mem_pool_attr_t; + +/** QuRT memory pool status type.*/ +typedef struct _qurt_mem_pool_status { + + qurt_size_t contig_size; /**< Largest contiguous free memory in bytes. */ + qurt_size_t free_size; /**< Total free memory in bytes. */ + qurt_size_t total_size; /**< Total declared memory in bytes. */ + +} qurt_mem_pool_status_t; + +typedef enum { + HEXAGON_L1_I_CACHE = 0, /**< Hexagon L1 instruction cache. */ + HEXAGON_L1_D_CACHE = 1, /**< Hexagon L1 data cache. */ + HEXAGON_L2_CACHE = 2 /**< Hexagon L2 cache. */ +} qurt_cache_type_t; + +typedef enum { + FULL_SIZE = 0, /**< Fully shared cache, without partitioning. */ + HALF_SIZE = 1, /**< 1/2 for main, 1/2 for auxiliary. */ + THREE_QUARTER_SIZE = 2, /**< 3/4 for main, 1/4 for auxiliary. */ + SEVEN_EIGHTHS_SIZE = 3 /**< 7/8 for main, 1/8 for auxiliary; for L2 cache only. */ +} qurt_cache_partition_size_t; + +typedef enum { + QURT_PROCESS_CB_GENERIC, /**< generic unconditional cb called after image loading. */ + QURT_PROCESS_NOTE_CB_PRE_MAP, /**< note cb called before segment loading. */ + QURT_PROCESS_NOTE_CB_POST_MAP /**< note cb called after segment loading. */ +} qurt_process_cb_type_t; + +typedef union { + void *ptr; + int num; +} qurt_process_callback_arg_t; + + +/**@endcond*/ + +/** @} */ /* end_addtogroup memory_management_types */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TYPES_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_user_dma.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_user_dma.h new file mode 100755 index 0000000000000..e05a6429fd703 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_user_dma.h @@ -0,0 +1,44 @@ +#ifndef QURT_USER_DMA_H +#define QURT_USER_DMA_H + +/** + @file qurt_user_dma.h + @brief Definitions, macros, and prototypes used for handling user DMA. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_user_dma_dmsyncht + Sends the DMSyncht command to the user DMA engine. + + Call this function to ensure all posted DMA memory operations are + complete. + + This stalls the current thread until the instruction + is complete and returns. + + @return + QURT_EOK - On dmsyncht completion \n + QURT_ENOTSUPPORTED - User DMA not supported + + @dependencies + None. +*/ +int qurt_user_dma_dmsyncht(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_vtlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_vtlb.h new file mode 100755 index 0000000000000..e064042e447ac --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/include/qurt/qurt_vtlb.h @@ -0,0 +1,76 @@ +/*============================================================================= + + qurt_vtlb.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef QURT_VTLB_H +#define QURT_VTLB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Names starting with "qurt_i_vtlb" are the internal low-level functions. +|| These should be considered subject to change. +*/ + +int qurt_i_vtlb_entry_create(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension); + +int qurt_i_vtlb_entry_create_with_pid(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension, + unsigned target_pid); + +int qurt_i_vtlb_entry_delete(unsigned index); + +int qurt_i_vtlb_entry_read(unsigned index, unsigned *tlbinfo); + +int qurt_i_vtlb_entry_write(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension); + +int qurt_i_vtlb_entry_write_with_pid(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension, unsigned target_pid); + +int qurt_i_vtlb_entry_probe(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex); + +int qurt_i_vtlb_entry_probe_with_pid(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex, unsigned target_pid); + + +int qurt_i_vtlb_statistics(unsigned *stats); // Returns stats[0] -- total number of VTLB entries + // stats[1] -- number of available VTLB entries + // stats[2] -- max size of VTLB tree since boot + +//can return index to an entry that was specialed, change it to take addresses instead of pages +int qurt_i_vtlb_set_special(int index, unsigned pageno, unsigned asid, unsigned size); + +int qurt_i_vtlb_queue_ppage(unsigned pageno, unsigned vtlb_index); + +#define QURT_VTLB_EXT_DEFAULT 0U +#define QURT_VTLB_EXT_LOCKED 1U +#define QURT_VTLB_EXT_EXCLUDE_DUMP 2U /* Temporary ability to skip certain mappings in pd dump */ +#define QURT_VTLB_EXT_FREELIST 0x800000u + +#define QURT_VTLB_ERR_OVERLAP -64 +#define QURT_VTLB_ERR_TREE_NO_SPACE -65 +#define QURT_VTLB_ERR_INVALID_SIZE -68 +#define QURT_VTLB_ERR_INVALID_EXT -69 +#define QURT_VTLB_ERR_DEL_PGT_LOCKED -70 +#define QURT_VTLB_ERR_PGT_LOCK_CNT -71 + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_VTLB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libposix.a new file mode 100755 index 0000000000000..fd0c274b7ca0e Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurt.a new file mode 100755 index 0000000000000..23238a59eaa87 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurtcfs.a new file mode 100755 index 0000000000000..85f9ad9d41bce Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_island.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_island.a new file mode 100755 index 0000000000000..b4a6a40af02a8 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_island.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_main.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_main.a new file mode 100755 index 0000000000000..472857ff02a1f Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/libtimer_main.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libposix.a new file mode 100755 index 0000000000000..566d5c66d3f03 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurt.a new file mode 100755 index 0000000000000..fffad1d70a51c Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurtcfs.a new file mode 100755 index 0000000000000..85f9ad9d41bce Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libtimer.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libtimer.a new file mode 100755 index 0000000000000..89aa8ae9e03bb Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev68/lib/pic/libtimer.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/confname.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/confname.h new file mode 100755 index 0000000000000..d9ca3135501e3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/confname.h @@ -0,0 +1,528 @@ +#ifndef CONFNAME_H +#define CONFNAME_H +/** + @file confname.h + @brief Named literals for 'name' argument of sysconf, pathconf + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly. Instead include unistd.h. For now since + toolchain doesnt provide a hook by including bits/confname.h, we stick this + header in QuRT's sys/types.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum +{ + _PC_LINK_MAX, +#define _PC_LINK_MAX _PC_LINK_MAX + _PC_MAX_CANON, +#define _PC_MAX_CANON _PC_MAX_CANON + _PC_MAX_INPUT, +#define _PC_MAX_INPUT _PC_MAX_INPUT + _PC_NAME_MAX, +#define _PC_NAME_MAX _PC_NAME_MAX + _PC_PATH_MAX, +#define _PC_PATH_MAX _PC_PATH_MAX + _PC_PIPE_BUF, +#define _PC_PIPE_BUF _PC_PIPE_BUF + _PC_CHOWN_RESTRICTED, +#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED + _PC_NO_TRUNC, +#define _PC_NO_TRUNC _PC_NO_TRUNC + _PC_VDISABLE, +#define _PC_VDISABLE _PC_VDISABLE + _PC_SYNC_IO, +#define _PC_SYNC_IO _PC_SYNC_IO + _PC_ASYNC_IO, +#define _PC_ASYNC_IO _PC_ASYNC_IO + _PC_PRIO_IO, +#define _PC_PRIO_IO _PC_PRIO_IO + _PC_SOCK_MAXBUF, +#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF + _PC_FILESIZEBITS, +#define _PC_FILESIZEBITS _PC_FILESIZEBITS + _PC_REC_INCR_XFER_SIZE, +#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE + _PC_REC_MAX_XFER_SIZE, +#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE + _PC_REC_MIN_XFER_SIZE, +#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE + _PC_REC_XFER_ALIGN, +#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN + _PC_ALLOC_SIZE_MIN, +#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN + _PC_SYMLINK_MAX, +#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX + _PC_2_SYMLINKS +#define _PC_2_SYMLINKS _PC_2_SYMLINKS +}; + +/* Values for the argument to `sysconf'. */ +enum +{ + _SC_ARG_MAX, +#define _SC_ARG_MAX _SC_ARG_MAX + _SC_CHILD_MAX, +#define _SC_CHILD_MAX _SC_CHILD_MAX + _SC_CLK_TCK, +#define _SC_CLK_TCK _SC_CLK_TCK + _SC_NGROUPS_MAX, +#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX + _SC_OPEN_MAX, +#define _SC_OPEN_MAX _SC_OPEN_MAX + _SC_STREAM_MAX, +#define _SC_STREAM_MAX _SC_STREAM_MAX + _SC_TZNAME_MAX, +#define _SC_TZNAME_MAX _SC_TZNAME_MAX + _SC_JOB_CONTROL, +#define _SC_JOB_CONTROL _SC_JOB_CONTROL + _SC_SAVED_IDS, +#define _SC_SAVED_IDS _SC_SAVED_IDS + _SC_REALTIME_SIGNALS, +#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + _SC_PRIORITY_SCHEDULING, +#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + _SC_TIMERS, +#define _SC_TIMERS _SC_TIMERS + _SC_ASYNCHRONOUS_IO, +#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + _SC_PRIORITIZED_IO, +#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO + _SC_SYNCHRONIZED_IO, +#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + _SC_FSYNC, +#define _SC_FSYNC _SC_FSYNC + _SC_MAPPED_FILES, +#define _SC_MAPPED_FILES _SC_MAPPED_FILES + _SC_MEMLOCK, +#define _SC_MEMLOCK _SC_MEMLOCK + _SC_MEMLOCK_RANGE, +#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + _SC_MEMORY_PROTECTION, +#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + _SC_MESSAGE_PASSING, +#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING + _SC_SEMAPHORES, +#define _SC_SEMAPHORES _SC_SEMAPHORES + _SC_SHARED_MEMORY_OBJECTS, +#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + _SC_AIO_LISTIO_MAX, +#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX + _SC_AIO_MAX, +#define _SC_AIO_MAX _SC_AIO_MAX + _SC_AIO_PRIO_DELTA_MAX, +#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX + _SC_DELAYTIMER_MAX, +#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX + _SC_MQ_OPEN_MAX, +#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX + _SC_MQ_PRIO_MAX, +#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX + _SC_VERSION, +#define _SC_VERSION _SC_VERSION + _SC_PAGESIZE, +#define _SC_PAGESIZE _SC_PAGESIZE +#define _SC_PAGE_SIZE _SC_PAGESIZE + _SC_RTSIG_MAX, +#define _SC_RTSIG_MAX _SC_RTSIG_MAX + _SC_SEM_NSEMS_MAX, +#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX + _SC_SEM_VALUE_MAX, +#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX + _SC_SIGQUEUE_MAX, +#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX + _SC_TIMER_MAX, +#define _SC_TIMER_MAX _SC_TIMER_MAX + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, +#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX + _SC_BC_DIM_MAX, +#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX + _SC_BC_SCALE_MAX, +#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX + _SC_BC_STRING_MAX, +#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX + _SC_COLL_WEIGHTS_MAX, +#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX + _SC_EQUIV_CLASS_MAX, +#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX + _SC_EXPR_NEST_MAX, +#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX + _SC_LINE_MAX, +#define _SC_LINE_MAX _SC_LINE_MAX + _SC_RE_DUP_MAX, +#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX + _SC_CHARCLASS_NAME_MAX, +#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX + + _SC_2_VERSION, +#define _SC_2_VERSION _SC_2_VERSION + _SC_2_C_BIND, +#define _SC_2_C_BIND _SC_2_C_BIND + _SC_2_C_DEV, +#define _SC_2_C_DEV _SC_2_C_DEV + _SC_2_FORT_DEV, +#define _SC_2_FORT_DEV _SC_2_FORT_DEV + _SC_2_FORT_RUN, +#define _SC_2_FORT_RUN _SC_2_FORT_RUN + _SC_2_SW_DEV, +#define _SC_2_SW_DEV _SC_2_SW_DEV + _SC_2_LOCALEDEF, +#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF + + _SC_PII, +#define _SC_PII _SC_PII + _SC_PII_XTI, +#define _SC_PII_XTI _SC_PII_XTI + _SC_PII_SOCKET, +#define _SC_PII_SOCKET _SC_PII_SOCKET + _SC_PII_INTERNET, +#define _SC_PII_INTERNET _SC_PII_INTERNET + _SC_PII_OSI, +#define _SC_PII_OSI _SC_PII_OSI + _SC_POLL, +#define _SC_POLL _SC_POLL + _SC_SELECT, +#define _SC_SELECT _SC_SELECT + _SC_UIO_MAXIOV, +#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV + _SC_IOV_MAX = _SC_UIO_MAXIOV, +#define _SC_IOV_MAX _SC_IOV_MAX + _SC_PII_INTERNET_STREAM, +#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM + _SC_PII_INTERNET_DGRAM, +#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM + _SC_PII_OSI_COTS, +#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS + _SC_PII_OSI_CLTS, +#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS + _SC_PII_OSI_M, +#define _SC_PII_OSI_M _SC_PII_OSI_M + _SC_T_IOV_MAX, +#define _SC_T_IOV_MAX _SC_T_IOV_MAX + + /* Values according to POSIX 1003.1c (POSIX threads). */ + _SC_THREADS, +#define _SC_THREADS _SC_THREADS + _SC_THREAD_SAFE_FUNCTIONS, +#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + _SC_GETGR_R_SIZE_MAX, +#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX + _SC_GETPW_R_SIZE_MAX, +#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX + _SC_LOGIN_NAME_MAX, +#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX + _SC_TTY_NAME_MAX, +#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX + _SC_THREAD_DESTRUCTOR_ITERATIONS, +#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + _SC_THREAD_KEYS_MAX, +#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + _SC_THREAD_STACK_MIN, +#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN + _SC_THREAD_THREADS_MAX, +#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + _SC_THREAD_ATTR_STACKADDR, +#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + _SC_THREAD_ATTR_STACKSIZE, +#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + _SC_THREAD_PRIORITY_SCHEDULING, +#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + _SC_THREAD_PRIO_INHERIT, +#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + _SC_THREAD_PRIO_PROTECT, +#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + _SC_THREAD_PROCESS_SHARED, +#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + + _SC_NPROCESSORS_CONF, +#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF + _SC_NPROCESSORS_ONLN, +#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN + _SC_PHYS_PAGES, +#define _SC_PHYS_PAGES _SC_PHYS_PAGES + _SC_AVPHYS_PAGES, +#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES + _SC_ATEXIT_MAX, +#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX + _SC_PASS_MAX, +#define _SC_PASS_MAX _SC_PASS_MAX + + _SC_XOPEN_VERSION, +#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION + _SC_XOPEN_XCU_VERSION, +#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION + _SC_XOPEN_UNIX, +#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX + _SC_XOPEN_CRYPT, +#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT + _SC_XOPEN_ENH_I18N, +#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + _SC_XOPEN_SHM, +#define _SC_XOPEN_SHM _SC_XOPEN_SHM + + _SC_2_CHAR_TERM, +#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM + _SC_2_C_VERSION, +#define _SC_2_C_VERSION _SC_2_C_VERSION + _SC_2_UPE, +#define _SC_2_UPE _SC_2_UPE + + _SC_XOPEN_XPG2, +#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2 + _SC_XOPEN_XPG3, +#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3 + _SC_XOPEN_XPG4, +#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4 + + _SC_CHAR_BIT, +#define _SC_CHAR_BIT _SC_CHAR_BIT + _SC_CHAR_MAX, +#define _SC_CHAR_MAX _SC_CHAR_MAX + _SC_CHAR_MIN, +#define _SC_CHAR_MIN _SC_CHAR_MIN + _SC_INT_MAX, +#define _SC_INT_MAX _SC_INT_MAX + _SC_INT_MIN, +#define _SC_INT_MIN _SC_INT_MIN + _SC_LONG_BIT, +#define _SC_LONG_BIT _SC_LONG_BIT + _SC_WORD_BIT, +#define _SC_WORD_BIT _SC_WORD_BIT + _SC_MB_LEN_MAX, +#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX + _SC_NZERO, +#define _SC_NZERO _SC_NZERO + _SC_SSIZE_MAX, +#define _SC_SSIZE_MAX _SC_SSIZE_MAX + _SC_SCHAR_MAX, +#define _SC_SCHAR_MAX _SC_SCHAR_MAX + _SC_SCHAR_MIN, +#define _SC_SCHAR_MIN _SC_SCHAR_MIN + _SC_SHRT_MAX, +#define _SC_SHRT_MAX _SC_SHRT_MAX + _SC_SHRT_MIN, +#define _SC_SHRT_MIN _SC_SHRT_MIN + _SC_UCHAR_MAX, +#define _SC_UCHAR_MAX _SC_UCHAR_MAX + _SC_UINT_MAX, +#define _SC_UINT_MAX _SC_UINT_MAX + _SC_ULONG_MAX, +#define _SC_ULONG_MAX _SC_ULONG_MAX + _SC_USHRT_MAX, +#define _SC_USHRT_MAX _SC_USHRT_MAX + + _SC_NL_ARGMAX, +#define _SC_NL_ARGMAX _SC_NL_ARGMAX + _SC_NL_LANGMAX, +#define _SC_NL_LANGMAX _SC_NL_LANGMAX + _SC_NL_MSGMAX, +#define _SC_NL_MSGMAX _SC_NL_MSGMAX + _SC_NL_NMAX, +#define _SC_NL_NMAX _SC_NL_NMAX + _SC_NL_SETMAX, +#define _SC_NL_SETMAX _SC_NL_SETMAX + _SC_NL_TEXTMAX, +#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX + + _SC_XBS5_ILP32_OFF32, +#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32 + _SC_XBS5_ILP32_OFFBIG, +#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG + _SC_XBS5_LP64_OFF64, +#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64 + _SC_XBS5_LPBIG_OFFBIG, +#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG + + _SC_XOPEN_LEGACY, +#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY + _SC_XOPEN_REALTIME, +#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME + _SC_XOPEN_REALTIME_THREADS, +#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + _SC_ADVISORY_INFO, +#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO + _SC_BARRIERS, +#define _SC_BARRIERS _SC_BARRIERS + _SC_BASE, +#define _SC_BASE _SC_BASE + _SC_C_LANG_SUPPORT, +#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT + _SC_C_LANG_SUPPORT_R, +#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R + _SC_CLOCK_SELECTION, +#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION + _SC_CPUTIME, +#define _SC_CPUTIME _SC_CPUTIME + _SC_THREAD_CPUTIME, +#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME + _SC_DEVICE_IO, +#define _SC_DEVICE_IO _SC_DEVICE_IO + _SC_DEVICE_SPECIFIC, +#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC + _SC_DEVICE_SPECIFIC_R, +#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R + _SC_FD_MGMT, +#define _SC_FD_MGMT _SC_FD_MGMT + _SC_FIFO, +#define _SC_FIFO _SC_FIFO + _SC_PIPE, +#define _SC_PIPE _SC_PIPE + _SC_FILE_ATTRIBUTES, +#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES + _SC_FILE_LOCKING, +#define _SC_FILE_LOCKING _SC_FILE_LOCKING + _SC_FILE_SYSTEM, +#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM + _SC_MONOTONIC_CLOCK, +#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + _SC_MULTI_PROCESS, +#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS + _SC_SINGLE_PROCESS, +#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS + _SC_NETWORKING, +#define _SC_NETWORKING _SC_NETWORKING + _SC_READER_WRITER_LOCKS, +#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + _SC_SPIN_LOCKS, +#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS + _SC_REGEXP, +#define _SC_REGEXP _SC_REGEXP + _SC_REGEX_VERSION, +#define _SC_REGEX_VERSION _SC_REGEX_VERSION + _SC_SHELL, +#define _SC_SHELL _SC_SHELL + _SC_SIGNALS, +#define _SC_SIGNALS _SC_SIGNALS + _SC_SPAWN, +#define _SC_SPAWN _SC_SPAWN + _SC_SPORADIC_SERVER, +#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER + _SC_THREAD_SPORADIC_SERVER, +#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + _SC_SYSTEM_DATABASE, +#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE + _SC_SYSTEM_DATABASE_R, +#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R + _SC_TIMEOUTS, +#define _SC_TIMEOUTS _SC_TIMEOUTS + _SC_TYPED_MEMORY_OBJECTS, +#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + _SC_USER_GROUPS, +#define _SC_USER_GROUPS _SC_USER_GROUPS + _SC_USER_GROUPS_R, +#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R + _SC_2_PBS, +#define _SC_2_PBS _SC_2_PBS + _SC_2_PBS_ACCOUNTING, +#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + _SC_2_PBS_LOCATE, +#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE + _SC_2_PBS_MESSAGE, +#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE + _SC_2_PBS_TRACK, +#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK + _SC_SYMLOOP_MAX, +#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX + _SC_STREAMS, +#define _SC_STREAMS _SC_STREAMS + _SC_2_PBS_CHECKPOINT, +#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + + _SC_V6_ILP32_OFF32, +#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + _SC_V6_ILP32_OFFBIG, +#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + _SC_V6_LP64_OFF64, +#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + _SC_V6_LPBIG_OFFBIG, +#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + + _SC_HOST_NAME_MAX, +#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX + _SC_TRACE, +#define _SC_TRACE _SC_TRACE + _SC_TRACE_EVENT_FILTER, +#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + _SC_TRACE_INHERIT, +#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT + _SC_TRACE_LOG, +#define _SC_TRACE_LOG _SC_TRACE_LOG + + _SC_LEVEL1_ICACHE_SIZE, +#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE + _SC_LEVEL1_ICACHE_ASSOC, +#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC + _SC_LEVEL1_ICACHE_LINESIZE, +#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE + _SC_LEVEL1_DCACHE_SIZE, +#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE + _SC_LEVEL1_DCACHE_ASSOC, +#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC + _SC_LEVEL1_DCACHE_LINESIZE, +#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE + _SC_LEVEL2_CACHE_SIZE, +#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE + _SC_LEVEL2_CACHE_ASSOC, +#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC + _SC_LEVEL2_CACHE_LINESIZE, +#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE + _SC_LEVEL3_CACHE_SIZE, +#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE + _SC_LEVEL3_CACHE_ASSOC, +#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC + _SC_LEVEL3_CACHE_LINESIZE, +#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE + _SC_LEVEL4_CACHE_SIZE, +#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE + _SC_LEVEL4_CACHE_ASSOC, +#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC + _SC_LEVEL4_CACHE_LINESIZE, +#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE + /* Leave room here, maybe we need a few more cache levels some day. */ + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, +#define _SC_IPV6 _SC_IPV6 + _SC_RAW_SOCKETS, +#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS + + _SC_V7_ILP32_OFF32, +#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32 + _SC_V7_ILP32_OFFBIG, +#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG + _SC_V7_LP64_OFF64, +#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64 + _SC_V7_LPBIG_OFFBIG, +#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG + + _SC_SS_REPL_MAX, +#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX + + _SC_TRACE_EVENT_NAME_MAX, +#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + _SC_TRACE_NAME_MAX, +#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + _SC_TRACE_SYS_MAX, +#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + _SC_TRACE_USER_EVENT_MAX, +#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + + _SC_XOPEN_STREAMS, +#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS + + _SC_THREAD_ROBUST_PRIO_INHERIT, +#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT + _SC_THREAD_ROBUST_PRIO_PROTECT +#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT + +}; +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/posix1_lim.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/posix1_lim.h new file mode 100755 index 0000000000000..0739958c5a6c4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/bits/posix1_lim.h @@ -0,0 +1,34 @@ +#ifndef POSIX1_LIM_H +#define POSIX1_LIM_H +/** + @file posix1_lim.h + @brief POSIX Minimum values + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +TODO + This header should be ideally relocated under api/posix/bits (something that + doesnt exist today) and be included from api/posix/bits/limits.h which inturn + should be included from toolchain's limits.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +#ifndef _POSIX_PATH_MAX +/** @brief Maximum number of bytes in a pathname, including the terminating + nul character */ +#define _POSIX_PATH_MAX 256 +#endif + +#ifndef _POSIX_SEM_NSEMS_MAX +/** @brief Maximum number of semaphores that a process may have */ +#define _POSIX_SEM_NSEMS_MAX 16 +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/common/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/common/time.h new file mode 100755 index 0000000000000..76b0d39ab7039 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/common/time.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/fcntl.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/fcntl.h new file mode 100755 index 0000000000000..c80ec98a449b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/fcntl.h @@ -0,0 +1,51 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/*========================================================================== + * FILE: fcntl.h + * + * SERVICES: POSIX fcntl.h + * + * DESCRIPTION: The header is needed by the open() and fcntl() + * system calls, which have a variety of parameters and + * flags. They are described here. + * + * The formats of the calls to each of these are: + * + * open(path, oflag [,mode]) open a file + * fcntl(fd, cmd [,arg]) get or set file attributes + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Oflag values for open(). POSIX Table 6-4. */ +#define POSIX_O_CREAT 0x100 /* creat file if it doesn't exist */ +#define POSIX_O_EXCL 0x200 /* exclusive use flag */ +#define POSIX_O_NOCTTY 0x400 /* do not assign a controlling terminal */ +#define POSIX_O_TRUNC 0x1000 /* truncate flag */ + +/* File status flags for open() and fcntl(). POSIX Table 6-5. */ +#define POSIX_O_APPEND 0x2000 /* set append mode */ +#define POSIX_O_NONBLOCK 0x4000 /* no delay */ + +/* File access modes for open() and fcntl(). POSIX Table 6-6. */ +#define POSIX_O_RDONLY 0 /* open(name, POSIX_O_RDONLY) opens read only */ +#define POSIX_O_WRONLY 1 /* open(name, POSIX_O_WRONLY) opens write only */ +#define POSIX_O_RDWR 2 /* open(name, POSIX_O_RDWR) opens read/write */ + +/* Mask for use with file access modes. POSIX Table 6-7. */ +#define POSIX_O_ACCMODE 0x3 /* mask for file access modes */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FCNTL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/hooks/unistd.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/hooks/unistd.h new file mode 100755 index 0000000000000..1c618bfe36b4f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/hooks/unistd.h @@ -0,0 +1,115 @@ +#ifndef UNISTD_H +#define UNISTD_H +/** + @file posix/hooks/unistd.h + @brief POSIX related declarations in that are missing in toolchain + header + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly! Instead include unistd.h. + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include /* For various POSIX ID types from toolchain headers */ + +#ifdef __cplusplus +extern "C" { +#endif +extern long pathconf (char const * path, int name); + +/* Process*/ + +/** The getppid() function shall return the parent process ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the parent process ID + */ +pid_t getppid(void); + +/** The getpgid() function shall return the process group ID of the process whose process ID is equal to pid + * Please refer to POSIX standard for details. + * @param thread [in] process ID + * @param value_ptr [out] process group ID + */ +pid_t getpgid(pid_t pid); + +/** The getpgrp() function shall return the process group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] process group ID of the calling process + */ +pid_t getpgrp(void); + +/**The getuid() function shall return the real user ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the real user ID of the calling process. + */ +uid_t getuid(void); + +/** The geteuid() function shall return the effective user ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective user ID of the calling process + */ +uid_t geteuid(void); + +/** The getegid() function shall return the effective group ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective group ID of the calling process. + */ +gid_t getegid(void); + +/** The getgid() function shall return the real group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] real group ID of the calling process. + */ + gid_t getgid(void); + +/** seteuid set effective user ID + * Please refer to POSIX standard for details. + * @param thread [in] effective user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int seteuid(uid_t uid); + +/** setpgrp - set the process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setpgrp(void); + +/** setuid - set user ID + * Please refer to POSIX standard for details. + * @param thread [in] user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setuid(uid_t uid); + +/** setpgid - set process group ID for job control + * Please refer to POSIX standard for details. + * @param thread [in] PID of process, PGID to be set + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setpgid(pid_t pid, pid_t pgid); + +/** setsid - create session and set process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setsid(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/mqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/mqueue.h new file mode 100755 index 0000000000000..74dcc2fa202c6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/mqueue.h @@ -0,0 +1,203 @@ +#ifndef _POSIX_MQUEUE_H_ +#define _POSIX_MQUEUE_H_ + +/*========================================================================== + * FILE: mqueue.h + * + * SERVICES: POSIX Message Queue API interface + * + * DESCRIPTION: POSIX Message Queue API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technlogies, Inc. + *==========================================================================*/ + +#include /*ssize_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MQ_PRIO_MAX 255 /* max priority */ +#define MQ_PRIO_DEFAULT 0 /* default priority */ + +typedef int mqd_t; + +struct mq_attr +{ + long mq_flags; /* message queue flags */ + long mq_maxmsg; /* maximum number of messages */ + long mq_msgsize; /* maximum message size */ + long mq_curmsgs; /* number of messages currently queued */ +}; + +typedef struct mq_attr mqueue_attr; + +/** \details + * This provides POSIX Message Queue API. + * + * mq_notify is not supported. + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * it only supports Message sending and receiving within one process. + * Message sending and receiving among processes are not supported. + */ + +/** \defgroup mqueue POSIX Message Queue API */ +/** \ingroup mqueue */ +/** @{ */ + +/** Open a message queue. + * Please refer to POSIX standard for details. + */ +mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */...); + +/** Close a message queue. + * Please refer to POSIX standard for details. + */ +int mq_close(mqd_t mq_desc); + +/** Remove a message queue. + * Please refer to POSIX standard for details. + */ +int mq_unlink(const char *name); + +/** Send a message to a message queue. + * Please refer to POSIX standard for details. + * + * If the queue is full, instead of blocking the sender, this function + * will return -1 with errno EAGAIN, in this implementation. This behavior + * may change in the future. + */ +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); + +/** Send a message to a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); + +/** Receive a message from a message queue. + * Please refer to POSIX standard for details. + */ +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); + +/** Receive a message from a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msg_prio, const struct timespec *restrict abs_timeout); + +/** Get message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); + +/** Set message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, struct mq_attr *restrict omqstat); + +/** @} */ + +#define NBBY 8U /* number of bits in a byte */ + +/* + * Select uses bit masks of file descriptors in longs. These macros + * manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here should + * be enough for most uses. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256U +#endif + +typedef unsigned long fd_mask; +#define NFDBITS (sizeof(fd_mask) * (unsigned int)NBBY) /* bits per mask */ + +#ifndef howmany +#define howmany(x, y) (((x) + ((y) - 1U)) / (y)) +#endif + +//equivalent of fd_set fpr WINNT env +typedef struct fd_set +{ + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +/** \addtogroup mqueue */ +/** @{ */ + +/** Sets the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_SET(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] |= (1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Clears the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_CLR(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] &= ~(1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise. + */ +#define FD_ISSET(n, p) ((unsigned long)(p)->fds_bits[((unsigned int) (n)) / NFDBITS] & (unsigned long)((unsigned)1U << (((unsigned int) (n)) % NFDBITS))) + +/** Copies the file descriptor set. + */ +#define FD_COPY(f, t) (void)(memcpy)((t), (f), sizeof(*(f))) + +/** Initializes the file descriptor set fdset to have zero bits for all file descriptors. + */ +#define FD_ZERO(p) (void)memset((p), 0, sizeof(*(p))) + +/** Error check the file descriptor set. + */ +#define FD_BAD(fd) ((fd) < 0 /*|| fd >= fd_arraylen || fd_array[fd].obj == 0*/) + +/*! Wait for both message queues and signals. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int pselect(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict sigmask); + +/*! Wait for multiple message queues. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout); + +/** @} */ + +/* this function is needed for test framework which needs to clean up memory when teardown */ +void _mq_teardown(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread.h new file mode 100755 index 0000000000000..f64242e8dc683 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread.h @@ -0,0 +1,287 @@ +#ifndef QURT_PTHREAD_H +#define QURT_PTHREAD_H + +/*========================================================================== + * FILE: pthread.h + * + * SERVICES: POSIX pthread API interface + * + * DESCRIPTION: POSIX pthread API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016,2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *========================================================================== + * + * EDIT HISTORY FOR MODULE + * + * This section contains comments describing changes made to the module. + * Notice that changes are listed in reverse chronological order. + * + * + * + * when who what, where, why + * -------- --- ------------------------------------------------------- + * 10/13/08 cz Initial version. + *==========================================================================*/ + +#include +#include "sys/sched.h" /* For struct sched_param */ +#include "sys/errno.h" /* error values */ +#include +#include +#include +#include +#include +#include "pthread_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* the range of the set supported by the kernel data type used to represent CPU sets. */ +#define CONFIG_NR_CPUS QURT_THREAD_CFG_BITMASK_ALL + +#define UNIMPLEMENTED(FUNC, RETURNTYPE, ARGS) static inline RETURNTYPE FUNC ARGS { qurt_printf("Unimplemented: %s... exiting\n", __FUNCTION__); exit(1); } + +/** @brief Magic (non-portable) value for a stack's address to enable usage + of auto-stack feature (if available) */ +#define PTHREAD_AUTO_STACK_MAGIC_ADDR_NP ((void *)0xFFF) + +/** \details + * This provides POSIX thread API. + * + */ + +/** \defgroup pthread POSIX pthread API */ +/** \ingroup pthread */ +/** @{ */ + +/** Compare Two Threads. + * Please refer to POSIX standard for details. + */ +static inline int pthread_equal(pthread_t t1, pthread_t t2) +{ + return (t1 == t2) ? 1 : 0; +} + +/** Create Thread. + * Please refer to POSIX standard for details. + */ +int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void *(*start)(void *), void *arg); + +/** Terminate Calling Thread. + * Please refer to POSIX standard for details. + */ +void pthread_exit(void *value_ptr); + +/** Wait for thread termination. + * Please refer to POSIX standard for details. + * @param thread [in] the thread to be joined + * @param value_ptr [out] the pointer of the exit status + */ +int pthread_join(pthread_t thread, void **value_ptr); + +/** Detach a joinable thread. + * Please refer to POSIX standard for details. + * @param id [in] id of the tread the thread to be detached. + */ +int pthread_detach(pthread_t id); + +/** Dynamic package initialisation + * Please refer to POSIX standard for details. + */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + +pthread_t pthread_self(void); +int pthread_cancel(pthread_t thread); +static inline void pthread_yield(void) +{ + return; +} + +int pthread_kill(pthread_t thread, int sig); + +/** + * @brief Return name of thread + * @warning Donot call this in the error handling path as it may cause deadlock + * due to underlying OS calls + * @param thread [in] thread Thread whose name is to be retrieved + * @param name [out] name Buffer used to return thread name + * @param len [in] len Number of bytes available in name + * @return 0 on success, ESRCH, ERANGE on failure + */ +extern int pthread_getname_np (pthread_t thread, char * name, size_t len); + +int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param); +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); +int pthread_setschedprio(pthread_t thread, int prio); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); + +/* Attribute functions */ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const sched_param *restrict param); +int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, sched_param *restrict param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr); +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void ** stackaddr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); +int pthread_attr_setscope(pthread_attr_t *attr, int scope); +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_getguardsize(const pthread_attr_t * attr, size_t * guardsize); +int pthread_attr_setautostack(pthread_attr_t *attr); +int pthread_attr_setbuspriority(pthread_attr_t *attr, unsigned short bus_priority); + +/* Qualcomm additions to pthread get/set attribute functions */ +int pthread_attr_setthreadname(pthread_attr_t *attr, const char * name); +int pthread_attr_getthreadname(const pthread_attr_t *attr, char * name, int size); +int pthread_attr_settimetestid(pthread_attr_t *attr, unsigned int tid); +int pthread_attr_gettimetestid(const pthread_attr_t *attr, unsigned int* tid); + +/* Mutexes */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling); +int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling); + +/* For Mutex with type PTHREAD_MUTEX_NORMAL, Priority Inheritance is not + * supported even PTHREAD_PRIO_INHERIT is defined since QURT does not support + * this kind of Mutex */ +int pthread_mutexattr_init(pthread_mutexattr_t *attr); +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling); + +/* Spinlocks */ +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); + +/* Condition variables */ +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); +int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); +int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock); +int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock); +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *time); + +/* Barriers */ +int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); +int pthread_barrier_destroy(pthread_barrier_t *barrier); +int pthread_barrier_wait(pthread_barrier_t *barrier); +int pthread_barrierattr_init(pthread_barrierattr_t *attr); +int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); + + +/*Read-Write locks*/ +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +int pthread_rwlock_rdlock(pthread_rwlock_t *); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *); +int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); +int pthread_rwlock_unlock(pthread_rwlock_t *); + + +/** please refer to POSIX standard document + */ +int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/** set CPU affinity attribute in thread attributes object. + + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [in] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpuset specified a CPU that was outside the set supported + by the kernel. (The kernel configuration option + CONFIG_NR_CPUS defines the range of the set supported by + the kernel data type used to represent CPU sets.) + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); + +/** get CPU affinity attribute in thread attributes object. + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [out] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpusetsize is smaller than the size of the affinity mask + used by the kernel. + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset); + +/* TLS */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_getattr_np(pthread_t thread, pthread_attr_t * restrict attr); + +/** @} */ + +/* Calling non-pthread calls this function to create pthred tcb w/o creating actual thread */ +int pthread_fake(pthread_t * restrict thread, const pthread_attr_t * restrict attr); +int pthread_fake_destroy(pthread_t thread); + +//amitkulk: move these to unistd.h after we move that header within qurt +int posix_memalign(void **memptr, size_t alignment, size_t size); +void exit(int status); +#ifdef __cplusplus +} +#endif + +#endif /* QURT_PTHREAD_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread_types.h new file mode 100755 index 0000000000000..51c3b9dbca243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/pthread_types.h @@ -0,0 +1,193 @@ +#ifndef _PTHREAD_TYPES_H_ +#define _PTHREAD_TYPES_H_ + +/*========================================================================== + * FILE: pthread_types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2016, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif + +#define _SSIZE_T + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PTHREAD_MAX_THREADS 512U + +#define PTHREAD_NAME_LEN 16 +#define PTHREAD_MIN_STACKSIZE 512 //4096 +#define PTHREAD_MAX_STACKSIZE 1048576 +#define PTHREAD_DEFAULT_STACKSIZE 16384 + +#define PTHREAD_STACK_MIN (4096U*2U) +#define PTHREAD_MIN_PRIORITY 0U +#define PTHREAD_MAX_PRIORITY 255U +#define PTHREAD_DEFAULT_PRIORITY 1 + +/*Mutex initialization status*/ +#define PTHREAD_MUTEX_ATTR_UNINITIALIZED 0 +#define PTHREAD_MUTEX_ATTR_INITIALIZED 1 + +/*Conditional attributes initialization status*/ +#define PTHREAD_COND_ATTR_UNINITIALIZED 0 +#define PTHREAD_COND_ATTR_INITIALIZED 1 + +#define PTHREAD_DEFAULT_NAME "Anonymous" + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFFU) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFFU) + +/* mutex and cond_var shared */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* mutex type */ +#define PTHREAD_MUTEX_ERRORCHECK 0 +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT 3 + +/* mutex protocol */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_SPINLOCK_UNLOCKED 0 +#define PTHREAD_SPINLOCK_LOCKED 1 + +#define PTHREAD_ONCE_INIT (0) + +#define PTHREAD_MUTEX_OPAQUE //ToDo: amitkulk: debug + +typedef signed int ssize_t; + +/*detatchstate of a pthread*/ +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 0 + +/*contention scope*/ +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 + +/*scheduler*/ +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Types and structure definitions + * + */ +typedef unsigned int cpu_set_t; + +typedef unsigned int pthread_t; + +typedef struct pthread_attr_t +{ + void *stackaddr; + int internal_stack; /* this flag==1 means the stack needs to be freed by posix */ + size_t stacksize; + int priority; + unsigned short timetest_id; + /* This flag indicate if thread will be autostack thread*/ + unsigned short autostack:1; + /* This flag is to indicate thread's bus_priority high/low + bus_priority = 0 -- Bus_priority is low + bus_priority = 1 -- Bus_priority is high + bus_priority = 3 -- Bus_priority is default (takes the default set for the process) + */ + unsigned short bus_priority:2; + unsigned short reserved:13; + cpu_set_t cpumask; + char name[PTHREAD_NAME_LEN]; + /* This flag indicates whether pthread lib should create thread contexts for other OSALs */ + /* This is used internally by POSIX and not available for general usage */ + int ext_context; + int detachstate; +} pthread_attr_t; + +//mutex attr +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +struct pthread_mutexattr_t +{ + int is_initialized; + int type; + int pshared; + int protocol; +}; + +typedef unsigned int pthread_mutex_t; + +typedef unsigned int pthread_spinlock_t; + +typedef struct pthread_condattr_t +{ + int is_initialized; + int pshared; + clockid_t clock_id; +} pthread_condattr_t; + +typedef unsigned int pthread_cond_t; + +typedef struct pthread_barrierattr_t +{ + int is_initialized; + int pshared; +} pthread_barrierattr_t; + +typedef unsigned int pthread_barrier_t; + +typedef int pthread_key_t; + +typedef int pthread_once_t; + + +/*Read-Write locks*/ +#define PTW32_RWLOCK_MAGIC 0xfacade2 +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +#ifdef __cplusplus +} +#endif + +#endif /* _PTHERAD_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sched.h new file mode 100755 index 0000000000000..faf3365be9f82 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sched.h @@ -0,0 +1,21 @@ +/*============================================================================= + + sched.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include "sys/sched.h" + +#endif //__SCHED_H__ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/semaphore.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/semaphore.h new file mode 100755 index 0000000000000..d9145b295ae62 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/semaphore.h @@ -0,0 +1,114 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +/*========================================================================== + * FILE: semaphore.h + * + * SERVICES: POSIX semaphore API interface + * + * DESCRIPTION: POSIX semaphore API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ +#include // Get all C sys types - includes POSIX specific +#include "sys/errno.h" // error values + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** User facing semaphore container with opaque pointer to implementation */ +typedef struct +{ + unsigned int *opaque; +} sem_t; +#define _SEM_T + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* constant definitions */ +#define SEM_FAILED ((sem_t*) 0) + +/* @todo siqbal Should we put such configuration items in a common place + instead of this user-facing header? */ +#define SEM_VALUE_MAX ((unsigned int) 30) // If need be increase this + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/** \details + * POSIX standard comes with two kinds of semaphores: named and unnamed + * semaphores. + * + * This implementation of POSIX kernel API provide unnamed & named semaphore. + * + * + * sem_timedwait() is not provided. + */ + +/** \defgroup semaphore POSIX Semaphore API */ + +/** \ingroup semaphore */ +/** @{ */ + +/** Initialize an unnamed semaphore. + * Please refer to POSIX standard for details. + * @param pshared [in] This implementation does not support non-zero value, + * i.e., semaphore cannot be shared between processes in this implementation. + */ +int sem_init(sem_t *sem, int pshared, unsigned int value); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_wait(sem_t *sem); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_trywait(sem_t *sem); + +/** Unlock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_post(sem_t *sem); + +/** Get the value of a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_getvalue(sem_t *sem, int *value); + +/** Destroy an unnamed semaphore. + * Please refer to POSIX standard for details. + */ +int sem_destroy(sem_t *sem); + +/** creates and initializes a named semaphore. + * Please refer to POSIX standard for details. + */ +sem_t * sem_open(const char* name , int oflag , ...); + +/** closes a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_close(sem_t *sem); + +/** unlinkes a named semaphore. + * Please refer to POSIX standard for details. + */ +int sem_unlink(const char *name); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SEMAPHORE_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/signal.h new file mode 100755 index 0000000000000..35cb1f1a9a319 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/signal.h @@ -0,0 +1,201 @@ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/*========================================================================== + * FILE: signal.h + * + * SERVICES: POSIX Signal API interface + * + * DESCRIPTION: POSIX Signal API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX signal bits */ + +#define POSIX_MSG 7 /* POSIX msg type used in Qube API */ +#define POSIX_NOTIF 8 /* POSIX msg type used in Qube API */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ + +#define SIGRTMIN 10 +#define SIGRTMAX 32 + +/* Notification Types. */ +/* No asynchronous notification is delivered when the event of interest occurs. */ +#define SIGEV_NONE 0 +/* The signal specified in sigev_signo shall be generated for the process when + the event of interest occurs. */ +#define SIGEV_SIGNAL 1 +/* A notification function is called to perform notification. */ +#define SIGEV_THREAD 2 +#define SA_SIGINFO 1 + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +typedef unsigned long int sigset_t; + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent sigevent; +struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; +}; + +typedef struct siginfo_t siginfo_t; +struct siginfo_t +{ + int si_signo; + int si_code; + union sigval si_value; +/* int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band;*/ +}; +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_sigaction)(int, siginfo_t *, void *); +}; + +/* Signal functions */ + +/** \details + * This provides POSIX Signal API. Please note that this + * implementation does not fully comply with POSIX standard. + * + * In POSIX standard, Signal can be used as 'interrupt', which means + * an incoming signal will interrupt a running thread. After the + * registered signal handler is executed, the thread will resume. + * This behavior cannot be implemented w/o modifying L4 or QURT kernel. + * On the ohter hand, appliation need to be carefully written to avoid + * problems caused by 'interrupting' signals. + * + * Therefore, in this implementation of POSIX signal, thread will + * only receive signals when it explicitly waits for signals, i.e., when + * the thread calls either sigwait() or sigsuspend(). + * + * Therefore, pthread_sigmask(), which set or get signal mask for a thread, + * is not supported, since the signal mask will be set by sigwait() and + * sigsuspend(). + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * only threads can send and receive signals. The functions related to + * signal operations with processes, such as kill(), sigqueue(), + * sigprocmask(), are not provided. + * + * Queued signal is not supported. + * + * Applications will use signals from SIGRTMIN to SIGRTMAX. + * + * SIGEV_SIGNAL and SIGEV_THREAD are supported. SIGEV_NONE is not + * supported. + * + */ + +/** \defgroup signal POSIX Signal API */ +/** \ingroup signal */ +/** @{ */ + +/** Wait for signals. This implementation does not support queued signals. + * + * Please refer to POSIX standard for details. + */ +int sigwait(const sigset_t *restrict set, int *restrict sig); + +/** Examine and Change Signal Action. + * Please refer to POSIX standard for details. + * + * @param act [in] A pointer to the sigaction structure that describes the + * action to be taken for the signal. Can be NULL. + * The following flags for sa_flags field in struct sigaction are not + * supported: SA_NOCLDSTOP, SA_ONSTACK, SA_RESETHAND, SA_RESTART, + * SA_NOCLDWAIT and SA_NODEFER. Only flag SA_SIGINFO is supported. + * + * @note Define sigaction as macro to avoid a warning when included from + * C++ code - it's causing a "sigaction(...) hides constructor for + * 'struct sigaction'" warning. + */ +/*lint -esym(123,sigaction) Suppress "macro used with no arguments" */ +#define sigaction(sig,act,oact) _sigaction((sig),(act),(oact)) + +/** Wait for signals. + * Please refer to POSIX standard for details. + */ +int sigsuspend(const sigset_t *sigmask); + +/** Add Signal to Signal Set. + * Please refer to POSIX standard for details. + */ +int sigaddset(sigset_t *set, int signo); + +/** Delete Signal from Signal Set. + * Please refer to POSIX standard for details. + */ +int sigdelset(sigset_t *set, int signo); + +/** Initialize and Empty Signal Set. + * Please refer to POSIX standard for details. + */ +int sigemptyset(sigset_t *set); + +/** Initialize and Fill Signal Set. + * Please refer to POSIX standard for details. + */ +int sigfillset(sigset_t *set); + +/** Test for Signal in Signal Set. + * Please refer to POSIX standard for details. + */ +int sigismember(const sigset_t *set, int signo); + +/** @} */ + +/* this is not a public api function */ +int _sigaction(int sig, const struct sigaction *act, struct sigaction *oact); + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +/** Wait for the time interval specified in the timespec structure referenced + * by timeout. This implementation does not support queued signals. + * For struct siginfo_t, si_code and si_value are ignored in this implementation. + * + * Please refer to POSIX standard for details. + */ +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SIGNAL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/errno.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/errno.h new file mode 100755 index 0000000000000..b9edf57bab6c3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/errno.h @@ -0,0 +1,20 @@ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +/*========================================================================== + * FILE: errno.h + * + * SERVICES: POSIX errno header file + * + * DESCRIPTION: POSIX errno based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#ifndef EOK +#define EOK 0 +#endif + +#endif /* _SYS_ERRNO_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/sched.h new file mode 100755 index 0000000000000..2acc34d821725 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/sched.h @@ -0,0 +1,67 @@ +#ifndef _POSIX_SCHED_H_ +#define _POSIX_SCHED_H_ + +/*========================================================================== + * FILE: sched.c + * + * SERVICES: POSIX Thread sched API interface + * + * DESCRIPTION: POSIX Thread sched API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCHED_FIFO 0 /* First in, first out (FIFO) scheduling policy. */ +#define SCHED_RR 1 /* Round robin scheduling policy. */ +#define SCHED_SPORADIC 2 /* Sporadic server scheduling policy. */ +#define SCHED_OTHER 3 /* Another scheduling policy. */ + +typedef struct sched_param sched_param; +struct sched_param +{ + void *unimplemented; + int sched_priority; +}; + +/** \details + * This provides POSIX sched API. + */ + +/** \defgroup sched POSIX sched API */ +/** \ingroup sched */ +/** @{ */ + +/** Relinquish the CPU. + * Please refer to POSIX standard for details. + */ +static inline int sched_yield(void) +{ + return 0; +} + +/** Get the maximum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_max(int policy); + +/** Get the minimum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_min(int policy); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SCHED_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/types.h new file mode 100755 index 0000000000000..700026f9f9e4e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/sys/types.h @@ -0,0 +1,35 @@ +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/*========================================================================== + * FILE: types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#if !defined( _PID_T ) || !defined( __pid_t_defined ) +/* POSIX defines pid_t as signed 32-bit type. Hexagon toolchain's header + defines it as unsigned 32-bit type citing conflict with QuRT POSIX + compatibility later. If any such conflicts exist, we should fix them. + pid_t is being defined *BEFORE* inclusion of generic/sys/types.h + *INTENTIONALLY* to fix this */ +typedef int pid_t; +#define _PID_T +#define __pid_t_defined +#endif +#include +#include +#include +#include + +#ifndef __DEFINED_off_t +typedef long off_t; +#define __DEFINED_off_t +#endif + +#endif /* _SYS_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/time.h new file mode 100755 index 0000000000000..13aeb1ea9920d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/posix/time.h @@ -0,0 +1,142 @@ +#ifndef _POSIX_TIME_H_ +#define _POSIX_TIME_H_ + +/*========================================================================== + * FILE: time.h + * + * SERVICES: POSIX Timer API interface + * + * DESCRIPTION: POSIX Timer API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *==========================================================================*/ + + +#include + +typedef int clockid_t; /* ignored */ +#define _CLOCKID_T +#define _PROVIDE_POSIX_TIME_DECLS 1 +#include +/* @todo anandj sys/time.h has definition for struct timeval but is not + included by generic/time.h */ +#include + +#define CLOCK_FREQ_NOT_DEFINED -1 +/* Frequency of Sclk used */ +#define TIME_CONV_SCLK_FREQ 19200000 + +#define RES_CONV_FACTOR1 1 +#define RES_CONV_FACTOR2 1000000000 + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +#endif + +#if !defined(CLOCK_MONOTONIC) +# define CLOCK_MONOTONIC 1 +#endif + +#if !defined(CLOCK_THREAD_CPUTIME_ID) +# define CLOCK_THREAD_CPUTIME_ID 2 +#endif + +#if !defined(CLOCK_PROCESS_CPUTIME_ID) +# define CLOCK_PROCESS_CPUTIME_ID 3 +#endif + +#if !defined(CLOCK_MONOTONIC_RAW) +# define CLOCK_MONOTONIC_RAW 4 +#endif + +#if !defined(CLOCK_REALTIME_COARSE) +# define CLOCK_REALTIME_COARSE 5 +#endif + +#if !defined(CLOCK_MONOTONIC_COARSE) +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +#if !defined(CLOCK_BOOTTIME) +# define CLOCK_BOOTTIME 7 +#endif + +struct itimerspec +{ + struct timespec it_interval; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer functions */ + +/** \details + * POSIX timers can be either of two types: a one-shot type or a periodic + * type. + * + * A one-shot is an armed timer that is set to an expiration time relative + * to either a current time or an absolute time. The timer expires once and + * is disarmed. + * + * A periodic timer is armed with an initial expiration time and a repetition + * interval. Every time the interval timer + * expires, the timer is reloaded with the repetition interval. The timer + * is then rearmed. + */ + +/** \defgroup timer POSIX Timer API */ + +/** \ingroup timer */ +/** @{ */ + +/** Create a POSIX timer. + * Please refer to POSIX standard for details. + * @param clockid [in] ignored in this implementation + * @param evp [in] if non-NULL, points to a sigevent structure. This + * structure, allocated by the application, defines the asynchronous + * notification to occur when the timer expires. If the evp argument is + * NULL, the effect is as if the evp argument pointed to a sigevent + * structure with the sigev_notify member having the value SIGEV_SIGNAL, + * the sigev_signo having a default signal number (SIGALRM), and the + * sigev_value member having the value of the timer ID. + */ +int timer_create(clockid_t clockid, struct sigevent *restrict evp, + timer_t *restrict timerid); + +/** Delete a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_delete(timer_t timerid); + +/** Get the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_gettime(timer_t timerid, struct itimerspec *value); + + +/** Set the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + * @param flags [in] ignored in this implementation + */ +int timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); +/** Obtain ID of a process CPU-time clock + * @param pid [in] Process ID + * @param clock_id [out] Clock ID + * @return Error values as per POSIX standard + */ +int clock_getcpuclockid (pid_t pid, clockid_t * clock_id); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_TIME_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qube/qube.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qube/qube.h new file mode 100755 index 0000000000000..1e31e2deedb38 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qube/qube.h @@ -0,0 +1,51 @@ +#ifndef QUBE_H +#define QUBE_H +/*============================================================================= + + qube.h -- H E A D E R F I L E + +GENERAL DESCRIPTION + Prototypes of qpd API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Define Error codes as QuRT error codes preceed with QURT_ */ +#ifndef EOK +#define EOK QURT_EOK +#endif /* EOK */ +#ifndef EVAL +#define EVAL QURT_EVAL +#endif /* EVAL */ +#ifndef EMEM +#define EMEM QURT_EMEM +#endif /* EMEM */ +#ifndef EINVALID +#define EINVALID QURT_EINVALID +#endif /* EINVALID */ + + +/*============================================================================= + FUNCTION DECLARATIONS +=============================================================================*/ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QUBE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops.h new file mode 100755 index 0000000000000..0a9a9f8ba7db5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops.h @@ -0,0 +1,197 @@ +#ifndef ATOMIC_OPS_H +#define ATOMIC_OPS_H +/** + @file atomic_ops.h + + @brief Type definitions backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * Author: Carlos Dyonisio + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_plain_word_t; + +/*-------------------------------------------------------------------------*/ + /* Atomic Ops API. */ + +/* + * IMPORTANT! + * If you plan to change the structure atomic_word_t, please add the new + * elements after value. For more information, read the comment in + * arch/arm/libs/atomic_ops/v5/src/arm_atomic_ops.spp:66 + */ + +typedef struct { + volatile atomic_plain_word_t value; +} atomic_word_t; + +#define ATOMIC_INIT(i) { (i) } + +static inline void +atomic_init(atomic_word_t *a, atomic_plain_word_t v) +{ + a->value = v; +} + +#if defined(ARCH_ARM) && defined(ARCH_VER) && (ARCH_VER < 6) && \ + (!defined(__ATOMIC_OPS_IN_KERNEL__) || defined(MACHINE_SMP)) + +/* + * If it is ARMv4/v5, the function declarations may change + * and are defined in the arch specific header file, + * as some of then cannot be declared static because of + * the assembler implementation. + */ + +#else + +/* Arithmetic operations. */ + +void atomic_sub(atomic_word_t *target, atomic_plain_word_t v); + +/* Architecture independent definitions. */ + +static inline atomic_plain_word_t atomic_read(atomic_word_t *target) +{ + return target->value; +} + +typedef unsigned long long atomic64_plain_word_t; + +typedef struct { + volatile atomic64_plain_word_t value; +} atomic64_word_t; + +static inline void +atomic64_init(atomic64_word_t *a, atomic64_plain_word_t v) +{ + a->value = v; +} + +/********************* + Support 64-bit + *********************/ + +atomic64_plain_word_t atomic64_set(atomic64_word_t* target, + atomic64_plain_word_t value); + +void atomic64_xor(atomic64_word_t* target, + atomic64_plain_word_t mask); + +/*---------------------------------------------------------------------------*/ + +/* Architecture independent definitions. */ + +static inline atomic64_plain_word_t atomic64_read(atomic64_word_t *target) +{ + return target->value; +} + +#endif + + +/* Architecture dependent definitions. */ +#include + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops_plat.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops_plat.h new file mode 100755 index 0000000000000..b54b3ff83d978 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/atomic_ops_plat.h @@ -0,0 +1,86 @@ +#ifndef ATOMIC_OPS_PLAT_H +#define ATOMIC_OPS_PLAT_H +/** + @file atomic_ops_plat.h + + @brief Prototypes of atomic operations API backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define atomic_set(a,b) qurt_atomic_set((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and(a,b) qurt_atomic_and((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and_return(a,b) qurt_atomic_and_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or(a,b) qurt_atomic_or((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or_return(a,b) qurt_atomic_or_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor(a,b) qurt_atomic_xor((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor_return(a,b) qurt_atomic_xor_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_set_bit(a,b) qurt_atomic_set_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_clear_bit(a,b) qurt_atomic_clear_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_change_bit(a,b) qurt_atomic_change_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add(a,b) qurt_atomic_add((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_return(a,b) qurt_atomic_add_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_unless(a,b,c) qurt_atomic_add_unless((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_sub(a,b) qurt_atomic_sub((unsigned int *)(a),(unsigned int)(b)) +#define atomic_sub_return(a,b) qurt_atomic_sub_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_inc(a) qurt_atomic_inc((unsigned int *)(a)) +#define atomic_inc_return(a) qurt_atomic_inc_return((unsigned int *)(a)) +#define atomic_dec(a) qurt_atomic_dec((unsigned int *)(a)) +#define atomic_dec_return(a) qurt_atomic_dec_return((unsigned int *)(a)) +#define atomic_compare_and_set(a,b,c) qurt_atomic_compare_and_set((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_barrier qurt_atomic_barrier +#define atomic_barrier_write qurt_atomic_barrier_write +#define atomic_barrier_write_smp qurt_atomic_barrier_write_smp +#define atomic_barrier_read_smp qurt_atomic_barrier_read_smp +#define atomic_barrier_smp qurt_atomic_barrier_smp + +/*============================ + * 64 bits support + *============================ */ +#define atomic64_set(a,b) qurt_atomic64_set((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and(a,b) qurt_atomic64_and((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and_return(a,b) qurt_atomic64_and_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or(a,b) qurt_atomic64_or((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or_return(a,b) qurt_atomic64_or_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor(a,b) qurt_atomic64_xor((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor_return(a,b) qurt_atomic64_xor_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_set_bit(a,b) qurt_atomic64_set_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_clear_bit(a,b) qurt_atomic64_clear_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_change_bit(a,b) qurt_atomic64_change_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add(a,b) qurt_atomic64_add((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add_return(a,b) qurt_atomic64_add_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub(a,b) qurt_atomic64_sub((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub_return(a,b) qurt_atomic64_sub_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_inc(a) qurt_atomic64_inc((unsigned long long *)(a)) +#define atomic64_inc_return(a) qurt_atomic64_inc_return((unsigned long long *)(a)) +#define atomic64_dec(a) qurt_atomic64_dec((unsigned long long *)(a)) +#define atomic64_dec_return(a) qurt_atomic64_dec_return((unsigned long long *)(a)) +#define atomic64_compare_and_set(a,b,c) qurt_atomic64_compare_and_set((unsigned long long *)(a),(unsigned long long )(b),(unsigned long long )(c)) +#define atomic64_barrier qurt_atomic64_barrier +#define atomic64_barrier_write qurt_atomic64_barrier_write +#define atomic64_barrier_write_smp qurt_atomic64_barrier_write_smp +#define atomic64_barrier_read_smp qurt_atomic64_barrier_read_smp +#define atomic64_barrier_smp qurt_atomic64_barrier_smp + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_PLAT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt.h new file mode 100755 index 0000000000000..4d25c9b2b6243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt.h @@ -0,0 +1,111 @@ +#ifndef QURT_H +#define QURT_H + +/** + @file qurt.h + @brief Contains kernel header files that provide kernel OS API functions, constants, and + definitions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013,2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +/*====================================================================== + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Notice that changes are listed in reverse chronological + * order. + * + * + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------ + * 2011-02-25 op Add Header file + 2012-12-16 cm (Tech Pubs) Edited/added Doxygen comments and markup. + ======================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "qurt_consts.h" +#include "qurt_api_version.h" +#include "qurt_alloc.h" +#include "qurt_futex.h" +#include "qurt_mutex.h" +#include "qurt_pipe.h" +#include "qurt_printf.h" +#include "qurt_assert.h" +#include "qurt_thread.h" +#include "qurt_trace.h" +#include "qurt_cycles.h" +#include "qurt_profile.h" +#include "qurt_sem.h" +#include "qurt_cond.h" +#include "qurt_barrier.h" +#include "qurt_fastint.h" +#include "qurt_allsignal.h" +#include "qurt_anysignal.h" +#include "qurt_signal.h" +#include "qurt_rmutex.h" +#include "qurt_pimutex.h" +#include "qurt_signal2.h" +#include "qurt_rmutex2.h" +#include "qurt_pimutex2.h" +#include "qurt_int.h" +#include "qurt_lifo.h" +#include "qurt_power.h" +#include "qurt_event.h" +#include "qurt_pmu.h" +#include "qurt_stid.h" +//#include "qurt_version.h" +#include "qurt_tlb.h" +#include "qurt_vtlb.h" +#include "qurt_memory.h" +#include "qurt_qdi.h" +#include "qurt_sclk.h" +#include "qurt_space.h" +#include "qurt_process.h" +#include "qurt_timer.h" +#include "qurt_tls.h" +#include "qurt_thread_context.h" +#include "qurt_hvx.h" +#include "qurt_hmx.h" +#include "qurt_mailbox.h" +#include "qurt_island.h" +#include "qurt_qdi_proxy.h" +#include "qurt_l2cfg.h" +#include "qurt_mmap.h" +#include "qurt_isr.h" +#include "qurt_busywait.h" +#include "qurt_ecc.h" +#include "qurt_callback.h" +#include "qurt_error.h" +#include "qurt_except.h" +#include "qurt_mq.h" +#include "qurt_user_dma.h" +#include "qurt_fs_hub.h" +#include "qurt_os_services.h" + +#ifndef MAIN_ONLY +#define INCLUDE_ISLAND_CONTENTS +#endif +#ifndef ISLAND_ONLY +#define INCLUDE_MAIN_CONTENTS +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_alloc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_alloc.h new file mode 100755 index 0000000000000..da37a4c0a714e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_alloc.h @@ -0,0 +1,145 @@ +#ifndef QURT_ALLOC_H +#define QURT_ALLOC_H + +/** + @file qurt_alloc.h + @brief Prototypes of kernel memory allocation API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_malloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated memory area. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] size Size (in bytes) of the memory area. + + @return + Nonzero -- Pointer to the allocated memory area. \n + 0 -- Not enough memory in heap to allocate memory area. + + @dependencies + None. + + */ +/* ======================================================================*/ +void *qurt_malloc( unsigned int size); + +/*======================================================================*/ +/**@ingroup func_qurt_calloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated array. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] elsize Size (in bytes) of each array element. + @param[in] num Number of array elements. + + @return + Nonzero -- Pointer to allocated array.\n + Zero -- Not enough memory in heap to allocate array. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_calloc(unsigned int elsize, unsigned int num); + +/*======================================================================*/ +/**@ingroup func_qurt_realloc + Reallocates memory on the heap. \n + Changes the size of a memory area that is already allocated on the QuRT system heap. + The reallocate memory operation is functionally similar to realloc. It accepts a pointer + to an existing memory area on the heap, and resizes the memory area to the specified size + while preserving the original contents of the memory area. + + @note1hang This function might change the address of the memory area. + If the value of ptr is NULL, this function is equivalent to + qurt_malloc(). + If the value of new_size is 0, it is equivalent to qurt_free(). + If the memory area is expanded, the added memory is not initialized. + + @param[in] *ptr Pointer to the address of the memory area. + @param[in] newsize Size (in bytes) of the reallocated memory area. + + @return + Nonzero -- Pointer to reallocated memory area. \n + 0 -- Not enough memory in heap to reallocate the memory area. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_realloc(void *ptr, int newsize); + +/*======================================================================*/ +/**@ingroup func_qurt_free + Frees allocated memory from the heap.\n + Deallocates the specified memory from the QuRT system heap. + + @param[in] *ptr Pointer to the address of the memory to deallocate. + + @return + None. + + @dependencies + The memory item that the ptr value specifies must have been previously + allocated using one of the qurt_calloc(), + qurt_malloc(), or qurt_realloc() memory allocation functions. + Otherwise the behavior of QuRT is undefined. + + */ + /* ======================================================================*/ +void qurt_free( void *ptr); + + +void *qurt_memalign(unsigned int alignment, unsigned int size); + +/* +|| Macro to define a static heap for a QuRT program. +|| +|| Usage: +|| Declare at the top-level of any C source file that +|| is part of the build (and is guaranteed +|| to actually be pulled into the build). Place +|| it in the same function with main(): +|| +|| QURT_DECLARE_STATIC_HEAP(512000); +|| +|| The only argument is the size in bytes, and it is +|| rounded up to the nearest 64 bytes (size of an +|| L2 cache block). +|| +*/ + +#define QURT_DECLARE_STATIC_HEAP(sz) \ + static struct qurt_static_heap { \ + char space[(sz)] __attribute__((aligned(64))); \ + } static_heap[1]; \ + void * const override_heap_Base = &static_heap[0]; \ + void * const override_heap_Limit = &static_heap[1] + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLOC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_allsignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_allsignal.h new file mode 100755 index 0000000000000..5dc89e495130d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_allsignal.h @@ -0,0 +1,176 @@ + +#ifndef QURT_ALLSIGNAL_H +#define QURT_ALLSIGNAL_H + +/** + @file qurt_allsignal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup all_signal_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** +qurt_signal_t supersedes qurt_allsignal_t. This type definition was added for backwards compatibility. */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int waiting; /**< */ + unsigned int signals_in; /**< */ + unsigned int queue; /**< */ + unsigned int reserved; /**< */ + }X; + /** @endcond */ +} qurt_allsignal_t; +/** @} */ /* end_addtogroup all_signal_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_init + Initializes an all-signal object.\n + The all-signal object is initially cleared. + + @datatypes + #qurt_allsignal_t + + @param[out] signal Pointer to the all-signal object to initialize. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_init(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_destroy + Destroys the specified all-signal object.\n + @note1hang All-signal objects must be destroyed when they are no longer in use. + Failure to do this causes resource leaks in the QuRT kernel. \n + @note1cont All-signal objects must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_destroy(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_get + Gets signal values from the all-signal object. + + Returns the current signal values of the specified all-signal object. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to access. + + @return + Bitmask with current signal values. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_allsignal_get(qurt_allsignal_t *signal) +{ return signal->X.signals_in; } + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_wait + Waits on the all-signal object.\n + Suspends the current thread until all of the specified signals are set. + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 that it is not to be waited on. + + If a signal is set in an all-signal object, and a thread is waiting on the all-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + Unlike any-signals, all-signals do not need to explicitly clear any set signals in an all-signal + object before waiting on them again -- clearing is done automatically by the wait + operation. + + @note1hang At most, one thread can wait on an all-signal object at any given time. + Because signal clearing is done by the wait operation, no clear operation is + defined for all-signals. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to wait on. + @param[in] mask Signal mask value, which identifies the individual signals in the all-signal object + to wait on. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_wait(qurt_allsignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_set + Set signals in the specified all-signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit + value of 1 indicates that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the all-signal object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_set(qurt_allsignal_t *signal, unsigned int mask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLSIGNAL_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_anysignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_anysignal.h new file mode 100755 index 0000000000000..9619e2de562b4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_anysignal.h @@ -0,0 +1,225 @@ +#ifndef QURT_ANYSIGNAL_H +#define QURT_ANYSIGNAL_H +/** + @file qurt_anysignal.h + Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +Copyright (c) 2021 Qualcomm Technologies, Inc. +All rights reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== +Typedefs +======================================================================*/ + +/**@ingroup anysignals_types + qurt_signal_t supersedes qurt_anysignal_t. This type definition was added for backwards compatibility. */ +typedef qurt_signal_t qurt_anysignal_t; + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_init + Initializes an any-signal object.\n + The any-signal object is initially cleared. + + @datatypes + #qurt_anysignal_t + + @param[out] signal Pointer to the initialized any-signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_init(qurt_anysignal_t *signal) +{ + qurt_signal_init(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_destroy + Destroys the specified any-signal object. + + @note1hang Any-signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Any-signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_destroy(qurt_anysignal_t *signal) +{ + qurt_signal_destroy(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait + Wait on the any-signal object. \n + Suspends the current thread until any one of the specified signals is set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread is waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + + @return + Bitmask of current signal values. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_wait(qurt_anysignal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_set + Sets signals in the specified any-signal object. \n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be set, and 0 indicates not to set the sigmal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the any-signal object. + + @return + Bitmask of old signal values (before set). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_set(qurt_anysignal_t *signal, unsigned int mask); + + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_get + Gets signal values from the any-signal object.\n + Returns the current signal values of the specified any-signal object. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to access. + + @return + A bitmask with the current signal values of the specified any-signal object. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_get(qurt_anysignal_t *signal) +{ + return qurt_signal_get(signal); +} + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_clear + @xreflabel{sec:anysignal_clear} + Clears signals in the specified any-signal object.\n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object, which specifies the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + clear in the any-signal object. + + @return + Bitmask -- Old signal values (before clear). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_clear(qurt_anysignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait_timed + Waits on the any-signal object. \n + Suspends the current thread until any of the specified signals is set or timeout expires. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread was waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + @param[out] signals Bitmask of current signal values. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- timeout + #QURT_EINVALID -- Duration out of range + + @dependencies + None. + */ +/* ======================================================================*/ + +int qurt_anysignal_wait_timed(qurt_anysignal_t *signal, unsigned int mask, unsigned int *signals, unsigned long long int duration); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ANYSIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_api_version.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_api_version.h new file mode 100755 index 0000000000000..dfe53ae755054 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_api_version.h @@ -0,0 +1,77 @@ +#ifndef QURT_API_VERSION_H +#define QURT_API_VERSION_H +/*============================================================================== + +qurt_api_version.h + +GENERAL DESCRIPTION + API version file + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +/*============================================================================== + CONSTANTS AND DEFINITIONS +==============================================================================*/ +/** + * Each field of the QURT_API_VERSION definitions is an 8-bit unsigned integer. + * Main release has first 3 fields updated - Major, Minor and Release. + * - QURT_API_VERSION = Major, Minor, Release. + * Patch releases are supported by adding the extra field. + * - QURT_API_VERSION = Major, Minor, Release, Patch. + */ +// Major version is incremented for incompatible API changes. +#define QURT_API_VER_MAJOR 1 + +// Minor version is incremented for backward-compatible enhancements in the API +// set. +#define QURT_API_VER_MINOR 4 + +// RELEASE version is incremented for each release within a `MAJOR.MINOR` +// release. +#define QURT_API_VER_RELEASE 1 + +// Patch version is incremented when new API content is introduced on older LTS +// release. +#define QURT_API_VER_PATCH 0 + +/* Update the QURT_API_VERSION function macro. */ +#define QURT_API_VERSION_ENCODE(major, minor, release, patch) \ + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | \ + (((release) & 0xFF) << 8) | ((patch) & 0xFF)) + +/* Update the QURT_API_VERSION Macro. */ +#define QURT_API_VERSION \ + QURT_API_VERSION_ENCODE(QURT_API_VER_MAJOR, QURT_API_VER_MINOR, \ + QURT_API_VER_RELEASE, QURT_API_VER_PATCH) + +/** Usage: + * + * #if QURT_API_VERSION >= QURT_API_VERSION_ENCODE(1,4,0,0) + * qurt_func_2(a,b,c); + * #else + * qurt_func(a); + * #endif + * + */ +/* + Gets the QuRT API version. + + @return + QuRT API version. + + @dependencies + None. + */ +unsigned int qurt_api_version(void); + +#endif /* QURT_API_VERSION_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_assert.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_assert.h new file mode 100755 index 0000000000000..13cc2afd2e973 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_assert.h @@ -0,0 +1,51 @@ +#ifndef QURT_ASSERT_H +#define QURT_ASSERT_H +/** + @file qurt_assert.h + @brief Prototypes of qurt_assert API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@ingroup func_qurt_assert_error + Writes diagnostic information to the debug buffer, and raises an error to the QuRT kernel. + + @datatypes + None. + + @param[in] filename Pointer to the file name string. + @param[in] lineno Line number. + + @return + None. + + @dependencies + None. + */ +void qurt_assert_error(const char *filename, int lineno) __attribute__((noreturn)); + +#define qurt_assert(cond) ((cond)?(void)0:qurt_assert_error(__QURTFILENAME__,__LINE__)) + +/** @} */ /* end_ingroup func_qurt_assert */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ASSERT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_atomic_ops.h new file mode 100755 index 0000000000000..d9b2cff7d737c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_atomic_ops.h @@ -0,0 +1,1298 @@ +#ifndef QURT_ATOMIC_OPS_H +#define QURT_ATOMIC_OPS_H +/** + @file qurt_atomic_ops.h + @brief Prototypes of kernel atomic operations API. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * + * This file is only included by the main atomic_ops.h, so all of that + * file's definitions are available. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +///* Sanity check to ensure the smp flag is set in machines.py */ +//#if defined(__ATOMIC_OPS_IN_KERNEL__) && !defined(MACHINE_SMP) && CONFIG_NUM_UNITS > 1 +//#error CONFIG_NUM_UNITS > 1 but smp not defined in machines.py. +//#endif +#define QURT_INLINE __attribute__((always_inline)) + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_atomic_set + Sets the atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value Value to set. + + @return + Value successfuly set. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_set(unsigned int* target, unsigned int value) +{ + unsigned long tmp; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " memw_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic_and + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + None + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_and(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_and_return + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + AND result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_and_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_or + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_or(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_or_return + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + Returns the OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_or_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_xor + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_xor(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_xor_return + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_xor_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_set_bit + Sets a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_set_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_clear_bit + Clears a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_clear_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_change_bit + Toggles a bit in a atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_change_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1fU; + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_add(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add_return + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_add_unless + Adds the delta value to an atomic variable unless the current value in the target + matches the unless variable. + + @note1hang The function retries until load lock and store conditional + are successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] delta Value to add to the current value. + @param[in] unless Perform the addition only when the current value is not + equal to this unless value. + @return + TRUE -- 1 - Addition was performed. \n + FALSE -- 0 - Addition was not done. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_unless(unsigned int* target, + unsigned int delta, + unsigned int unless) +{ + unsigned int current_val; + unsigned int new_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%3)\n" + " p0 = cmp.eq(%0, %5)\n" + " if p0 jump 2f\n" + " %1 = add(%0, %4)\n" + " memw_locked(%3, p0) = %1\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"=&r" (new_val),"+m" (*target) + : "r" (target), "r" (delta), "r" (unless) + : "p0"); + + return (unsigned int)(current_val != unless); +} + +/**@ingroup func_qurt_atomic_sub + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_sub(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_sub_return + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_sub_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_inc + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_inc(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_inc_return + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_inc_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_dec + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_dec(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_dec_return + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_dec_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_compare_and_set + Compares the current value of the atomic variable with the + specified value and set to a new value when compare is successful. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val Old value to compare. + @param[in] new_val New value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE --Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_compare_and_set(unsigned int* target, + unsigned int old_val, + unsigned int new_val) +{ + unsigned int current_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memw_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (unsigned int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic_barrier + Allows the compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_barrier(void) +{ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); +} + + +/**@ingroup func_qurt_atomic64_set + Sets the 64-bit atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value 64-bit value to set. + + @return + Successfuly set value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_set(unsigned long long* target, unsigned long long value) +{ + unsigned long long tmp; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " memd_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic64_and_return + Bitwise AND operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise AND. + + @return + AND result of 64-bit atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_and_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_or + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_or(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_or_return + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_or_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_xor_return + Bitwise XOR operation of 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_xor_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_set_bit + Sets a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_set_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_clear_bit + Clears a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_clear_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_change_bit + Toggles a bit in a 64-bit atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_change_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_add(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add_return + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_add_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_sub_return + Subtracts a 64-bit integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_sub_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_inc + Increments a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_inc(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_inc_return + Increments a 64-bit atomic variable by one + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_inc_return(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_dec_return + Decrements a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_dec_return(unsigned long long *target) +{ + unsigned long long result; + long long minus1 = 0xFFFFFFFFFFFFFFFFLL; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (minus1) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_compare_and_set + Compares the current value of an 64-bit atomic variable with + the specified value and sets to a new value when compare is successful. + + @note1hang The function keep retrying until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val 64-bit old value to compare. + @param[in] new_val 64-bit new value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE -- Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE int +qurt_atomic64_compare_and_set(unsigned long long *target, + unsigned long long old_val, + unsigned long long new_val) +{ + unsigned long long current_val; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memd_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic64_barrier + Allows compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_barrier(void) +{ + /** @cond */ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); + /** @endcond */ +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_barrier.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_barrier.h new file mode 100755 index 0000000000000..7c6f787d43bc2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_barrier.h @@ -0,0 +1,140 @@ +#ifndef QURT_BARRIER_H +#define QURT_BARRIER_H + +/** + @file qurt_barrier.h + @brief Prototypes of Kernel barrier API functions. + + EXTERNALIZED FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup barrier_types +@{ */ +/*===================================================================== + Constants and macros +======================================================================*/ +#define QURT_BARRIER_SERIAL_THREAD 1 /**< Serial thread. */ +#define QURT_BARRIER_OTHER 0 /**< Other. */ + +#ifndef ASM +#include + +/*===================================================================== +Typedefs +======================================================================*/ + +/** QuRT barrier type. + */ +typedef union { + /** @cond */ + struct { + unsigned short threads_left; + unsigned short count; + unsigned int threads_total; + unsigned int queue; + unsigned int reserved; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_barrier_t; + +/** @} */ /* end_addtogroup barrier_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_init + Initializes a barrier object. + + @datatypes + #qurt_barrier_t + + @param[out] barrier Pointer to the barrier object to initialize. + @param[in] threads_total Total number of threads to synchronize on the barrier. + + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_init(qurt_barrier_t *barrier, unsigned int threads_total); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_destroy + Destroys the specified barrier. + + @note1hang Barriers must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Barriers must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to destroy. + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_destroy(qurt_barrier_t *barrier); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_wait + Waits on the barrier.\n + Suspends the current thread on the specified barrier. \n + The function return value indicates whether the thread was the last one to + synchronize on the barrier. + When a thread waits on a barrier, it is suspended on the barrier: \n + - If the total number of threads waiting on the barrier is less than the assigned value + of the barrier, no other action occurs. \n + - If the total number of threads waiting on the barrier equals the assigned value of the + barrier, all threads currently waiting on the barrier are awakened, allowing them to + execute past the barrier. + + @note1hang After its waiting threads are awakened, a barrier is automatically reset + and can be used again in the program without the need for re-initialization. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to wait on. + + @return + #QURT_BARRIER_OTHER -- Current thread awakened from barrier. \n + #QURT_BARRIER_SERIAL_THREAD -- Current thread is last caller of barrier. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_wait(qurt_barrier_t *barrier); + + +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BARRIER_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_busywait.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_busywait.h new file mode 100755 index 0000000000000..a4dab80a2520a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_busywait.h @@ -0,0 +1,62 @@ +#ifndef QURT_BUSYWAIT_H +#define QURT_BUSYWAIT_H + +/** + @file qurt_busywait.h + @brief Implementation of the busywait() function for + hardware based blocking waits that use the QTIMER as a reference. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ============================================================================*/ +/*============================================================================= + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Changes are listed in reverse chronological + * order. + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------------- + * 2018-03-20 pg Add Header file + ============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_busywait + Pauses the execution of a thread for a specified time.\n + Use for small microsecond delays. + + @note1hang The function does not return to the caller until + the time duration has expired. + + @param[in] pause_time_us Time to pause in microseconds. + + @return + None. + + @dependencies + None. + */ +void qurt_busywait (unsigned int pause_time_us); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BUSYWAIT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_callback.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_callback.h new file mode 100755 index 0000000000000..dc9b896c63454 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_callback.h @@ -0,0 +1,235 @@ +#ifndef QURT_CALLBACK_H +#define QURT_CALLBACK_H + +/** + @file qurt_callback.h + Definitions, macros, and prototypes for QuRT callback framework. + + QDI framework allows the development of root process drivers and services that + a user process client can interact with in a secure manner. QDI framework does + this by elevating the priviledge of user process thread, temporarily allowing + the thread execute in root context and letting it fall back to user context once + the QDI invocation is finished. + + The QuRT callback framework provides a safe mechanism for root process drivers + to execute callback functions in a user process. The framework hosts + dedicated worker threads in corresponding processes that handle the execution + of the callback function. This ensures that the callbacks occur in context of + the appropriate process thread, in result maintaining privilege boundaries. + + Prerequisites for use of this framework are: + 1. Driver is a QDI driver and client communicates with drivers using QDI + invocations. + 2. Appropriate callback configuration is specified in cust_config.xml for + the user process that intends to use this framework. + + qurt_cb_data_t is the public data structure that allows client to store all + the required information about the callback, including the callback function + and the arguments to pass to this function when it executes. + The client uses QDI interface to register this structure with root driver. + + Callback framework provides following APIs that a root driver can use to invoke callback. + These functions are described in qurt_qdi_driver.h header file. + + qurt_qdi_cb_invoke_async() triggers an asynchronous callback wherein the + invoking thread does not wait for the callback to finish executing. + + qurt_qdi_cb_invoke_sync() triggers a synchronous callback. Upon invocation + the invoking thread gets suspended till the callback function finishes execution. + + qurt_qdi_cb_invoke_sync_with_data() invokes a synchronous callback similar to + qurt_qdi_cb_invoke_sync(). It allows user to pass large data along with + the callback invocation to be utlized during the callback execution. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int qurt_cb_result_t; + +/* Callback framework error codes. + Callback framework returns a nonzero value if callback invocation is unsuccessful. + Following macros highlight cause of failure in more detail. +*/ +#define QURT_CB_ERROR -1 /* Callback registration failed.\n*/ +#define QURT_CB_OK 0 /* Success.\n*/ +#define QURT_CB_MALLOC_FAILED -2 /* QuRTOS malloc failure.\n*/ +#define QURT_CB_WAIT_CANCEL -3 /* Process exit cancelled wait operation.\n*/ +#define QURT_CB_CONFIG_NOT_FOUND -4 /* Callback configuration for process was not found.\n*/ +#define QURT_CB_QUEUE_FULL -5 /* Callback queue is serving at maximum capacity.*/ +/** @addtogroup cb_types +@{ */ +/** Callback registration data structure. + This data structure is used by a client attempting to register a callback with a QDI driver. + It holds the address of callback function and the argument supplied to the callback + function when it executes. +*/ +typedef struct { + /** @cond */ + void* cb_func; /*< Pointer to the callback function. */ + unsigned cb_arg; /*< Not interpreted by the framework.*/ + /** @endcond */ +} qurt_cb_data_t; + +/** @cond */ +/* Defines used as default if cust_config does not specify them. */ +#define CALLBACK_WORKER_STACK_SIZE 0x2000 +/** @endcond */ +/** @} */ /* end_addtogroup cb_typess */ +/**@ingroup func_qurt_cb_data_init + Initializes the callback data structure. + Entity registering a callback with the root process driver must call this function + to initialize callback registration data structure to the default value. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_init (qurt_cb_data_t* cb_data){ + cb_data->cb_func = NULL; + cb_data->cb_arg = 0; +} + +/**@ingroup func_qurt_cb_data_set_cbfunc + Sets up the callback function in the callback registration data structure. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_func Pointer to the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbfunc (qurt_cb_data_t* cb_data, void* cb_func){ + cb_data->cb_func = cb_func; +} + +/**@ingroup func_qurt_cb_data_set_cbarg + Sets up the callback argument. + This function sets up the argument passed to the callback function when it executes. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_arg Argument for the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbarg (qurt_cb_data_t* cb_data, unsigned cb_arg){ + cb_data->cb_arg = cb_arg; +} + +/** @cond */ +/**@ingroup driver_support_functions + Invokes an asynchronous callback for a specified process. + A driver that resides in the root process calls this API to launch a callback in + a process described by the client_handle. + After the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is not suspended during the callback execution period. + The API returns immediately with a success/failure error code. + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_async(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process. + A driver that resides in a root process calls this API to launch a sync callback in + a process described by the client_handle. + AFter the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is suspended during the callback execution period. + If the process in which to execute the callback exits or terminates, the caller is + woken up with error code #QURT_CB_WAIT_CANCEL (refer to qurt_callback.h). + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process, passing driver data to the user PD. + This function is similar to qurt_qdi_cb_invoke_sync() and allows the driver to pass arbitrary data to + the user process as part of the callback invocation. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @param data Driver arbitrary data to pass to the user process. Memory pointed to by data + must be accessible to the user PD. The root driver can allocate such memory by + using qurt_mem_mmap(). + @param data_len Driver arbitrary data length. + + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync_with_data( int client_handle, + qurt_cb_data_t* cb_data, + int prio, + void *data, + unsigned data_len + ); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_clade.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_clade.h new file mode 100755 index 0000000000000..d7442cf98dd94 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_clade.h @@ -0,0 +1,62 @@ +#ifndef QURT_CLADE_H +#define QURT_CLADE_H +/** + @file qurt_clade.h + @brief Prototypes of Cache Line Accelerated Decompression Engine (CLADE) API. + CLADE is a cache line level memory compression system that is used to + decrease DRAM usage. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_clade2_get + Reads the value of the clade2 register. + + @param[in] offset Offset from the clade2 cfg base. + @param[out] *value Pointer to the register value read from the offset. + + @return + #QURT_EOK - Successfully read the value from the register at offset \n + #QURT_EINVALID - Offset passed is incorrect + + @dependencies + None. + */ +int qurt_clade2_get(unsigned short offset, unsigned int *value); + +/**@ingroup func_qurt_clade2_set + Sets the PMU register; only PMU_SEL register can be set. + + @param[in] offset Offset from the QURTK_clade2_cfg_base. + @param[in] value Value to set at offset. + + @return + #QURT_EOK -- Successfully set the value at offset. \n + #QURT_ENOTALLOWED -- Set operation performed at an offset other than CLADE2_PMU_SELECTION_REG. + + @dependencies + None. + */ +int qurt_clade2_set(unsigned short offset, unsigned int value); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CLADE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cond.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cond.h new file mode 100755 index 0000000000000..6e65ed82a8393 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cond.h @@ -0,0 +1,219 @@ +#ifndef QURT_COND_H +#define QURT_COND_H +/** + @file qurt_cond.h + @brief Prototypes of kernel condition variable object API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup condition_variables_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** QuRT condition variable type. */ +typedef union { + /** @cond */ + unsigned long long raw; + struct { + unsigned int count; + unsigned int n_waiting; + unsigned int queue; + unsigned int reserved; + }X; + /** @endcond */ +} qurt_cond_t; + +/** @} */ /* end_addtogroup condition_variables_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_cond_init + Initializes a conditional variable object. + + @datatypes + #qurt_cond_t + + @param[out] cond Pointer to the initialized condition variable object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_init(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_destroy + Destroys the specified condition variable. + + @note1hang Conditions must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Conditions must not be destroyed while they are still in use. If this occurs, + the behavior of QuRT is undefined. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to destroy. + + @return + None. + + */ +/* ======================================================================*/ +void qurt_cond_destroy(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_signal + Signals a waiting thread that the specified condition is true. \n + + When a thread wishes to signal that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the signal condition operation. \n + -# Unlock the mutex. + + @note1hang Failure to properly lock and unlock a mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_signal(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_broadcast + Signals multiple waiting threads that the specified condition is true.\n + When a thread wishes to broadcast that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the broadcast condition operation. \n + -# Unlock the mutex.\n + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_broadcast(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable (suspends the thread and unlocks the mutex). + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t \n + #qurt_mutex_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait(qurt_cond_t *cond, qurt_mutex_t *mutex); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait2 + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable, which suspends the thread and unlocks the mutex. + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @note1cont This is the same API as qurt_cond_wait(), use this version + when using mutexes of type #qurt_rmutex2_t. + + @datatypes + #qurt_cond_t \n + #qurt_rmutex2_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with the condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait2(qurt_cond_t *cond, qurt_rmutex2_t *mutex); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_COND_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_consts.h new file mode 100755 index 0000000000000..b1e35998e73b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_consts.h @@ -0,0 +1,315 @@ +#ifndef QURT_CONSTS_H +#define QURT_CONSTS_H + +/** + @file qurt_consts.h + @brief QuRT constants and definitions + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* Definitions of system events. System events suspend + a thread and put it into suspending_list. + The system event number is saved in CONTEXT::error::cause field + of the suspended thread. An event handler thread such as + page fault handler or system error handler can wake up the suspended + thread. + */ +#define QURT_EVENT_PAGEFAULT 0x1 /* Page fault event. */ +#define QURT_EVENT_SYSTEM_ERR 0x2 /* System error event. */ +#define QURT_EVENT_SUSPEND 0x3 +#define QURT_EVENT_PROCESS_EXIT 0x4 /* Process termination event.*/ + +#define QURT_SYSENV_MAX_THREADS_TYPE 1 /* Maximum threads object. */ +#define QURT_SYSENV_PROCNAME_TYPE 2 /* Process name object. */ +#define QURT_SYSENV_MAX_PI_PRIO_TYPE 3 /* Maximum pi priority object. */ +#define QURT_SYSENV_ARCH_REV_TYPE 4 /* Architecture version object. */ +#define QURT_SYSENV_APP_HEAP_TYPE 5 /* Application heap object. */ +#define QURT_SYSENV_REGION_ATTR_DEFAULT 7 /* Default region attributes. */ +#define QURT_SYSENV_STACK_PROFILE_COUNT_TYPE 8 /* Stack profile count type. */ +#define QURT_SYSENV_ISLAND_CONFIG_TYPE 9 /*island configuration check*/ +#define QURT_SYSENV_HTHREADS_TYPE 10 /* Active threads objec */ +#define QURT_SYSENV_CONFIG_IMAGE_START_LO 11 /* Config image start address for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_START_HI 12 /* Config Image start address for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_LO 13 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_HI 14 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_PLATPARAMS 15 /* Platformparams for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_SIZE 16 /* Config image Size for DTB parsing */ +#define QURT_SYSENV_L2_CACHE_LINE_SIZE 17 /*L2 cache line size*/ + +/* Get q6 regs */ +#define QURT_GET_SSR 1 +#define QURT_GET_CCR 2 +#define QURT_GET_CFGBASE 3 +#define QURT_GET_SYSCFG 4 +#define QURT_GET_REV 5 + + +/** @cond rest_reg_dist */ +/** @addtogroup performance_monitor_macros +@{ */ + +/* PMU */ +#define QURT_PMUCNT0 0 /**< */ +#define QURT_PMUCNT1 1 /**< */ +#define QURT_PMUCNT2 2 /**< */ +#define QURT_PMUCNT3 3 /**< */ +#define QURT_PMUCFG 4 /**< */ +#define QURT_PMUEVTCFG 5 /**< */ + +/* new since V55 */ +#define QURT_PMUCNT4 6 /**< */ +#define QURT_PMUCNT5 7 /**< */ +#define QURT_PMUCNT6 8 /**< */ +#define QURT_PMUCNT7 9 /**< */ +#define QURT_PMUEVTCFG1 10 /**< */ + +/* new since V61 */ +#define QURT_PMUSTID0 11 /**< */ +#define QURT_PMUSTID1 12 /**< */ + +#define QURT_PMUCNTSTID0 13 /**< */ +#define QURT_PMUCNTSTID1 14 /**< */ +#define QURT_PMUCNTSTID2 15 /**< */ +#define QURT_PMUCNTSTID3 16 /**< */ +#define QURT_PMUCNTSTID4 17 /**< */ +#define QURT_PMUCNTSTID5 18 /**< */ +#define QURT_PMUCNTSTID6 19 /**< */ +#define QURT_PMUCNTSTID7 20 /**< */ + +/** @} */ /* end_addtogroup performance_monitor_macros */ +/** @endcond */ + +/* + Power collapse operation +*/ +#define QURT_POWER_SHUTDOWN 0 /**< */ +#define QURT_TCXO_SHUTDOWN 1 /**< */ +#define QURT_POWER_CMD_PREPARE 0 /**< */ +#define QURT_POWER_CMD_PERFORM 1 /**< */ +#define QURT_POWER_CMD_EXIT 2 /**< */ +#define QURT_POWER_CMD_FAIL_EXIT 3 /**< */ +#define QURT_POWER_CMD_PERFORM_L2_RETENTION 4 /**< */ +#define QURT_POWER_CMD_PERFORM_SAVE_TCM 5 /**< */ +#define QURT_POWER_CMD_DEEP_SLEEP 6 /**< */ + + +/** @addtogroup thread_macros +@{ */ +#define QURT_MAX_HTHREAD_LIMIT 8U /**< Limit on the maximum number of hardware threads supported by QuRT for any + Hexagon version. Use this definition to define arrays, and so on, in + target independent code. */ +/** @} */ /* end_addtogroup thread_macros */ + +/** @cond internal_only */ +/** @addtogroup power_management_macros +@{ */ +/** + L2 cache retention mode +*/ +#define QURT_POWER_SHUTDOWN_TYPE_L2NORET QURT_POWER_CMD_PERFORM /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_L2RET QURT_POWER_CMD_PERFORM_L2_RETENTION /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_SAVETCM QURT_POWER_CMD_PERFORM_SAVE_TCM /**< */ +/** @} */ /* end_addtogroup power_management_macros */ +/** @endcond */ + +/* + QURT_system_state + Use for debugging the shutdown/startup process. + + State transition for cold boot: + QURT_BOOT_SETUP_ISDB --> QURT_CBOOT_BSP_INIT --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT --> + QURT_CBOOT_KERNEL_INIT_DONE --> QURT_CBOOT_PLAT_CONFIG_DONE --> + QURT_CBOOT_ROOT_TASK_STARTED + + State transition for power collapse: + QURT_PREPARE_SINGLE_MODE --> QURT_PERFORM_IPEND --> + QURT_PERFORM_SAVE_TLB --> QURT_PERFORM_SWITCH_PC --> + cache flush states (dependent on L2 retention config) + + State transition for warm boot: + QURT_BOOT_SETUP_ISDB --> QURT_WBOOT_INIT_TLB --> + QURT_WBOOT_SET_1TO1_MAP --> QURT_WBOOT_REMOVE_1TO1_MAP --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT +*/ +#define QURT_PREPARE_SINGLE_MODE 1 /**< */ +#define QURT_PREPARE_END 2 /**< */ +#define QURT_PERFORM_IPEND 3 /**< */ +#define QURT_PERFORM_SAVE_ISDP 4 /**< */ +#define QURT_PERFORM_SAVE_PMU 5 /**< */ +#define QURT_PERFORM_SAVE_TLB 6 /**< */ +#define QURT_PERFORM_SWITCH_PC 7 /**< */ +#define QURT_PERFORM_EXIT 8 /**< */ +#define QURT_FLUSH_L1CACHE 9 /**< */ +#define QURT_FLUSH_L2CACHE 0xA /**< */ +#define QURT_FLUSH_CACHE_DONE 0xB /**< */ +#define QURT_SWITCH_PC_DONE 0xC /**< */ +#define QURT_BOOT_SETUP_ISDB 0xD /**< */ +#define QURT_WBOOT_INIT_TLB 0xE /**< */ +#define QURT_WBOOT_SET_1TO1_MAP 0xF /**< */ +#define QURT_WBOOT_CFG_ADV_SYSCFG 0x10 /**< */ +#define QURT_WBOOT_REMOVE_1TO1_MAP 0x11 /**< */ +#define QURT_CBOOT_BSP_INIT 0x12 /**< */ +#define QURT_CBOOT_END_CLEAN_L1CACHE 0x13 /**< */ +#define QURT_CBOOT_END_CLEAN_INIT 0x14 /**< */ +#define QURT_CBOOT_END_OS_INIT 0x15 /**< */ +#define QURT_CBOOT_TLB_DUMP_LOAD 0x16 /**< */ +#define QURT_CBOOT_TLB_STATIC_LOAD 0x17 /**< */ +#define QURT_CBOOT_KERNEL_INIT_DONE 0x18 /**< */ +#define QURT_CBOOT_PLAT_CONFIG_DONE 0x19 /**< */ +#define QURT_CBOOT_ROOT_TASK_STARTED 0x1A /**< */ +#define QURT_IMPRECISE_EXCEPTION 0x1B /**< */ +#define QURT_WBOOT_DEBUG_L2_START 0x1C /**< */ +#define QURT_WBOOT_DEBUG_L2_END 0x1D /**< */ +#define QURT_NMI_SAVE_L2VIC_COMPLETE 0x1E /**< */ +#define QURT_NMI_HANDLER_COMPLETE 0x1F /**< */ +#define QURT_NMI_AFTER_SAVE_GLOBAL 0x20 /**< */ +#define QURT_WBOOT_START 0x21 /**< */ +#define QURT_ENTER_ISLAND 0x22 /**< */ +#define QURT_EXIT_ISLAND 0x23 /**< */ +#define QURT_LOAD_NOTIFIER_TCB 0x24 /**< */ +#define QURT_ABNORMAL_RESET 0x25 /**< */ +/* + Thread attributes +*/ + +#define QURT_THREAD_ATTR_GP 0x00000002 /*< */ +#define QURT_THREAD_ATTR_UGP 0x00000003 /*< User general pointer (UGP)*/ +#define QURT_THREAD_ATTR_PREFETCH 0x00000004 /*< */ +#define QURT_THREAD_ATTR_TID 0x00000005 /*< */ +#define QURT_THREAD_ATTR_CACHE_PART 0x00000007 /*< */ +#define QURT_THREAD_ATTR_COPROCESSOR 0x00000008 /*< */ +#define QURT_THREAD_ATTR_GET_L2CACHE_PART 0x00000009 /*< */ +#define QURT_THREAD_ATTR_SET_FRML 0x0000000A /*< */ +#define QURT_THREAD_ATTR_STID_GET 0x0000000B /*< */ +#define QURT_THREAD_ATTR_STID_SET 0x0000000C /*< */ +#define QURT_THREAD_ATTR_AUTOSTACK 0x0000000D /*< */ +#define QURT_THREAD_ATTR_SYSTEM_THREAD 0x0000000E /*< */ +#define QURT_THREAD_ATTR_STID_SET2 0x0000000F /*< */ +#define QURT_THREAD_ATTR_STID_SET2_ACKNOWLEDGE 0x00000010 /*< */ +#define QURT_THREAD_ATTR_STID_GET2 0x00000011 /*< */ + +/** Cache operations*/ +#define QURT_DCCLEAN 0U /* Clean Dcache. */ +#define QURT_DCINV 1U /* Invalidate Dcache. */ +#define QURT_DCCLEANINV 2U /* Clean and invalidate Dcache. */ +#define QURT_ICINV 3U /* Invalidate Icache. */ +#define QURT_DUMP_DCTAGS 4U /* For testing purpose. */ +#define QURT_FLUSH_ALL 5U /* Flush entire L1 and L2 cache. */ +#define QURT_TABLE_FLUSH 6U /* Flush based on table of physical pages */ +#define QURT_CLEAN_INVALIDATE_ALL 7U /* Flush and invalidate entire L1 and L2 cache. */ +#define QURT_L2CACHE_LOCK_LINES 8U /* l2 cache lock lines */ +#define QURT_L2CACHE_UNLOCK_LINES 9U /* l2 cache unlock lines */ +#define QURT_CLEAN 10U /* Flush L1 and L2 cache */ +#define QURT_CLEAN_INVALIDATE 11U /* Flush and invalidate L1 and L2 cache. */ +#define QURT_CLEAN_INVALIDATE_L2 12U /* Flush and invalidate entire L2 cache. */ + +/**@ingroup chapter_prefined_symbols */ +/**@xreflabel{hdr:QURT_API_VERSION}*/ + + +/* Process state. */ +#define QURT_UPDATE_PROCESS_STATE 0 /**< */ +#define QURT_MP_INIT 1 /*< */ +#define QURT_MP_RUNNING 2 /*< */ +#define QURT_MP_STOPPED 3 /*< */ + +/* QuRT reset reason. */ +#define QURT_NORMAL_BOOT 0 /* Normal boot. */ +#define QURT_WARM_BOOT 1 /* Power collapse warm boot. */ +#define QURT_WARM_BOOT_L2_RETENTION 2 /* Power collapse with L2 retention warm boot. */ +#define QURT_WARM_BOOT_SAVE_TCM 3 /* Power collapse with saving TCM. */ +#define QURT_QUICK_BOOT 4 /* Deep sleep. */ + +/* QuRT Wait for Idle command */ +#define QURT_WAIT_FOR_IDLE_DISABLE 0 /*< */ +#define QURT_WAIT_FOR_IDLE_ENABLE 1 /*< */ +#define QURT_WAIT_FOR_IDLE 2 /*< */ +#define QURT_WAIT_FOR_IDLE_CANCEL 3 /*< */ + +/*QuRT island exit stages */ +#define QURT_ISLAND_EXIT_STAGE1 1 /*< */ +#define QURT_ISLAND_EXIT_STAGE2 2 /*< */ + +#define QURT_MAX_NAME_LEN 64 /*< */ + +#define MAX_POOL_RANGES 16 /*< */ + +/* key definitions for debug thread info */ +//#define MAX_TCB_KEY 40 //whatever is a good number or makes debug thread structure be 1K +#define KEY_SCHDULER_STATE 1 /*< */ +#define KEY_PRIORITY 2 /*< */ +#define KEY_PRIORITY_ORIG 3 /*< */ +#define KEY_STACK_BOTTOM 4 // Currently not populated +#define KEY_STACK_TOP 5 // Currently not populated +#define KEY_HVX_STATE 6 /*< */ +#define KEY_FUTEX_OBJECT 7 /*< */ +#define KEY_THREAD_ID 8 /*< */ +#define KEY_PROFILE_CYCLE_LO 9 // Currently not populated +#define KEY_PROFILE_CYCLE_HI 10 // Currently not populated +#define KEY_ERROR_ADDRESS 11 // This holds the BADVA +#define KEY_ERROR_CAUSE 12 // This is the same as QURT_error_info.cause +#define KEY_ERROR_CAUSE2 13 // This is the same as QURT_error_info.cause2 +#define KEY_ERROR_SSR 14 /*< Holds the SSR value */ +#define QURT_RESERVED -1 + +/* VTLB method IDs. */ +#define QURT_VTLB_ENTRY_CREATE 0U +#define QURT_VTLB_ENTRY_DELETE 1U +#define QURT_VTLB_ENTRY_READ 2U +#define QURT_VTLB_ENTRY_WRITE 3U +#define QURT_VTLB_ENTRY_PROBE 4U +#define QURT_VTLB_ENTRY_SPLIT 5U +#define QURT_VTLB_ENTRY_MERGE 6U +#define QURT_VTLB_ENTRY_STATISTICS 7U +#define QURT_VTLB_ENTRY_SET_SPECIAL 8U +#define QURT_VTLB_QUEUE_PPAGE 9U +#define QURT_VTLB_RECLAIM_STACK_PAGES 10U +#define QURT_VTLB_ASID_SET_STATE_FAST 11U +#define QURT_VTLB_ASID_SET_STATE 12U +#define QURT_VTLB_ENTRY_SET_EXTENSION 13U +#define QURT_VTLB_ENTRY_CLEAR_EXTENSION 14U + +/* VTCM window access control HWIO programming. */ +#define QURT_VTCM_WINDOW_ENABLE 1U +#define QURT_VTCM_WINDOW_DISABLE 0U +#define QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT 0xFFFU +#define QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT 0U + +/** @cond */ +/* ETM source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< Memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< Memory source of SAC* is data. */ + +/* ETM PID status flags */ +#define QURT_ETM_NO_PID 0xFFFFFFFF /**< No PID is selected. */ +/** @endcond */ + +/* execution context */ +#define QURT_CTX_USER 1 +#define QURT_CTX_GUEST 2 + +/* Profiling STID */ +#define QURT_STID_DEFAULT 0U + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cycles.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cycles.h new file mode 100755 index 0000000000000..b599493f5d563 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_cycles.h @@ -0,0 +1,301 @@ + +#ifndef QURT_CYCLES_H +#define QURT_CYCLES_H 1 +/** + @file qurt_cycles.h + Prototypes of kernel pcycle API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ + +/**@ingroup func_qurt_profile_reset_idle_pcycles + @xreflabel{hdr:qurt_profile_reset_idle_pcycles} + Sets the per-hardware-thread idle cycle counts to zero. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_idle_pcycles (void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_thread_pcycles + @xreflabel{hdr:qurt_profile_get_thread_pcycles} + Gets the count of the running processor cycles for the current thread.\n + Returns the current running processor cycle count for the current QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @return + Integer -- Running processor cycle count for current thread. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_profile_get_thread_pcycles(void); + + +/*======================================================================*/ +/**@ingroup func_qurt_get_core_pcycles + @xreflabel{hdr:qurt_get_core_pcycles} + Gets the count of core processor cycles executed.\n + Returns the current number of running processor cycles executed since the Hexagon + processor was last reset. + + This value is based on the hardware core clock, which varies in speed according to the + processor clock frequency. + + @note1hang Because the hardware core clock stops running when the processor shuts + down (due to all of the hardware threads being idle), treat the cycle values returned + by this operation as relative rather than absolute. + + @note1cont Thread cycle counts are valid only in the V4 Hexagon processor version. + + @return + Integer -- Current count of core processor cycles. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_get_core_pcycles(void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles + + @deprecated use #qurt_profile_get_idle_pcycles2 instead + + Gets the current idle processor cycle counts for a maximum of 6 hardware threads. Use + #qurt_profile_get_idle_pcycles2 for reading pcycles without limitation on maximum hardware threads. + + This operation accepts a pointer to a user-defined array, and writes to the array the current + idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling is enabled or not, + and resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be a minimum of the number of hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_idle_pcycles (unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles2 + Gets the current idle processor cycle counts for maximum available hardware threads. + + This operation accepts a pointer to a user-defined array with length in bytes, and writes + to the array the current idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling enable status, and + resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be equivalent to the number of hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, + it returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_idle_pcycles2 (unsigned long long *pcycles, unsigned int length_in_bytes); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles + + @deprecated use #qurt_profile_get_threadid_pcycles2 instead + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for a maximum of 6 hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Valid thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be a minimum of the number of + hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_threadid_pcycles (int thread_id, unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles2 + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for maximum available hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be equivalent to the number of + hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, it + returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + #QURT_ENOTHREAD -- Operation failed due to invalid #thread_id + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_threadid_pcycles2 (int thread_id, unsigned long long *pcycles, unsigned int length_in_bytes); + + +/*======================================================================*/ +/**@ingroup func_qurt_profile_reset_threadid_pcycles + @xreflabel{hdr:qurt_profile_reset_threadid_pcycles} + Sets the per-hardware-thread running cycle counts to zero for the specified QuRT thread. + + @param[in] thread_id Thread identifier. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_threadid_pcycles (int thread_id); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_enable + @xreflabel{hdr:qurt_profile_enable} + Enables profiling.\n + Enables or disables cycle counting of the running and idle processor cycles. + Profiling is disabled by default. \n + + @note1hang Enabling profiling does not automatically reset the cycle counts -- this must be + done explicitly by calling the reset operations before starting cycle counting. + Cycle counting starts from the instant of it was enabled using this API, and + halts on profiling disable. + + @param[in] enable Profiling. Values: \n + - 0 -- Disable profiling \n + - 1 -- Enable profiling @tablebulletend + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_enable (int enable); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_pcycles + @xreflabel{hdr:qurt_get_hthread_pcycles} + Reads the GCYCLE_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values are 1 through . + + + @return + Value read from GCYCLE_nT register. This value indicates the total number of pcycles that got executed + from reset to current point of execution when n threads are in run mode + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_pcycles(int n); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_commits + @xreflabel{hdr:qurt_get_hthread_commits} + Reads the GCOMMIT_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values: 1 through . + + @return + Value read from the GCOMMIT_nT register. This value indicates the total number of packets + committed from reset to current point of execution when n threads are in run mode. + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_commits(int n); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_devtree.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_devtree.h new file mode 100755 index 0000000000000..4adee45bb44a2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_devtree.h @@ -0,0 +1,161 @@ +#ifndef QURT_DEVTREE_H +#define QURT_DEVTREE_H +/** + @file qurt_devtree.h + @brief Prototypes and structures for device tree aware QuRT library function. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +*/ +/*qurt_callback is included by qurt_qdi_driver.h and depends on NULL being def. + callback is not used here, so define NULL here to avoid including the world*/ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "libfdt.h" +#include "DTBExtnLib.h" +#include "qurt_qdi_ext.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_BLOB_ID (-1) +#define DEFAULT_BLOB_ID 0 + +/** QURT Device Tree Mapping Macros */ +#define QURT_DT_MAPPING_FAILED (-1) +#define QURT_DT_FLAG_ISLAND 0x1 +#define QURT_DT_FLAG_PHYSADDR 0x2 + +/** Device Tree type for Root PD Device tree. +    Root PD Device Tree will typically describe the hardware in the subsystem. +    This is the /soc portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_ROOT 0 + +/** Device Tree type for Local Device tree. +    Local Device Tree will typically contain the software settings. +    This is the /sw portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_LOCAL 1 + +int qurt_devtree_init(void); + +/**@ingroup func_qurt_dt_mapping_create + Creates a memory mapping from the specified property of the specified device + tree node. Returns virtual addresses and sizes. + + @param[in] offset Device tree node offset. + @param[in] flags Flags to configure memory. Overloaded as property + index if reg_name is NULL. + @param[in] reg_name Identifies property to use for mapping, should + resemble a region. + @param[out] vaddr Return pointer for the virtual region address. + @param[out] size Return pointer for the virtual region size. + + @return + Result code indicating success or failure \n +*/ +int qurt_dt_mapping_create(fdt_node_handle *devtreeNode, int flags, char *regionName, int regionIdx, + unsigned long long *vaddr, unsigned long long *size); + +/**@ingroup func_qurt_dt_mapping_create2 + + Creates a memory mapping from the specified property of the specified device + tree node. + + Returns virtual addresses and sizes according to architecture (i.e either 32 bit or 64 bit). + + @param[in] devtreeNode Device Tree node + + @param[in] dt_map_flags Flags to configure memory mapping and are reserved for future purpose. + (0) - Default value assumes details from DT node are phys address, size. + QURT_DT_FLAG_ISLAND + + NOTE: The PA needs to be added to corresponding island spec to create an island mapping + + @param[in] regionName NULL or name of index in range to return, should + resemble a region. Ex.reg-names = "base", "rx", "tx"; + + @param[in] regionIdx Index of range to return. Ex reg = <0x1000 0x20>, <0x10000 0x100>, <0x18000 0x100 >; + + NOTE: If client specifies both re_name & regionIdx. The precedence of + region name is taken over and region index is ignored. + + @param[in] dt_map_perm Mapping access permissions(R/W), + QURT_PERM_READ + QURT_PERM_WRITE + + @param[in] cache_attr QuRT cache mode type's : + QURT_MEM_CACHE_DEVICE + QURT_MEM_CACHE_WRITEBACK + Other required cache type enums in qurt_types.h can also be passed. + + NOTE: No default value for cache & perm is present. + Client always needs to pass any of defined the flags. + + @param[out] vaddr Return pointer to the variable that holds the virtual address + @param[out] size Return pointer for the virtual region size. + + @return + #QURT_EOK Success indicating mapping created properly. + #QURT_DT_MAPPING_FAILED Failed to create mapping. + #QURT_EINVALID Mismatch in the architecture. + + else FdtLib or thirdparty error code. + +*/ +int qurt_dt_mapping_create2(fdt_node_handle *devtreeNode, unsigned int dt_map_flags, + char *regionName, int regionIdx, unsigned int dt_map_perm, int cache_attr, void **vaddr, size_t *size); + +/**@ingroup func_qurt_dt_isr_register + Device tree aware registration of an interrupt service routine (ISR) to an ISR thread. + The interrupt defined in the specified device tree node is enabled when this function returns success. + + @datatypes + #qurt_thread_t \n + #fdt_node_handle + + @param[in] dt_node Device tree node that specifies the interrupt property. + @param[in] dt_int_index Index of the specific interrupt to use within the device tree node structure. + Specify either this or int_name, use -1 if string is used. + @param[in] dt_int_name Name of the specific interrupt to use within the device tree node structure. + Either this or int_index should be specified, use NULL if index is used + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create(), defined by qurt_isr_register2(). + @param[in] prio Priority of the ISR, defined by qurt_isr_register2(). + @param[in] flags Defines ACK type. Values : \n + #QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the kernel. + #QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + Defined by qurt_isr_register2(). + @param[in] isr ISR with proto type void isr (void *arg, int int_num), defined by qurt_isr_register2(). + @param[in] arg First argument of the ISR when it is called to service the interrupt, defined by qurt_isr_register2(). + + @return + #QURT_EOK -- Successfully registered the ISR for the interrupt \n + #QURT_EINT -- Interrupt not configured \n + #QURT_EINVALID -- Invalid thread ID \n + #QURT_EDISABLED -- The feature is disabled \n + #QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Create the thread ID qurt_isr_create(). + ISR registration completed with qurt_isr_register2(). + */ +int qurt_dt_isr_register(fdt_node_handle *dt_node, int dt_int_index, char * dt_int_name, qurt_thread_t isr_thread_id, + unsigned short prio, unsigned short flags, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_dt_blob_id_get + Returns the Blob ID for the Blob type passed. + The value returned from this API can be passed as Blob ID parameter to DTBExtnLib APIs. + + @param[in] blob_type  Blob type to look up. + @return Blob ID for the passed Blob Type. +*/ +int qurt_dt_blob_id_get(unsigned int blob_type); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ecc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ecc.h new file mode 100755 index 0000000000000..09312684e99af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ecc.h @@ -0,0 +1,168 @@ +#ifndef QURT_ECC_H +#define QURT_ECC_H + + +/*===================================================================== + + @file qurt_ecc.h + @brief Prototypes of QuRT memory ECC API functions + + Copyright (c) 2018, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup exception_handling_types +@{ */ +// ECC memory definition +typedef enum { + QURT_ECC_MEM_L1_ICACHE = 0, /**< ECC memory L1 ICache. */ + QURT_ECC_MEM_L1_DCACHE = 1, /**< ECC memory L1 DCache.*/ + QURT_ECC_MEM_L2_CACHE = 2, /**< ECC memory L2 Cache.*/ + QURT_ECC_MEM_VTCM = 3 /**< ECC memory VTCM.*/ +} qurt_ecc_memory_t; +/** @} */ /* end_addtogroup exception_handling_types */ + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup exception_handling_macros +@{ */ + +#define QURT_ECC_ERR_DETECTED_STATUS 0 /**< ECC error detected. */ +#define QURT_ECC_ERR_TYPE 1 /**< ECC error type.*/ +// ECC status type + +#define QURT_ECC_CORRECTABLE_COUNT (1<<0) /**< ECC correctable count.*/ +#define QURT_ECC_UNCORRECTABLE_COUNT (1<<1) /**< ECC uncorrectable count.*/ +#define QURT_ECC_REGION_LOGGING (1<<2) /**< ECC region logging.*/ +// ECC enable/disable definition + +#define QURT_ECC_PROTECTION_DISABLE (0<<0) /**< Bit 0. */ +#define QURT_ECC_PROTECTION_ENABLE (1<<0) /**< Bit 0. */ +/** @} */ /* end_addtogroup exception_handling_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_ecc_enable + Enables or disables ECC protection on a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] enable Set to one of the following values: + - #QURT_ECC_PROTECTION_ENABLE + - #QURT_ECC_PROTECTION_DISABLE @tablebulletend + + @return + - #QURT_EOK -- ECC enabling or disabling setup is performed successfully + - Others -- Failure + + @dependencies + None. + */ +int qurt_ecc_enable( qurt_ecc_memory_t memory, unsigned int enable ); + + +/**@ingroup func_qurt_ecc_get_error_status + Gets ECC error status for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following: + - #QURT_ECC_ERR_DETECTED_STATUS + - #QURT_ECC_ERR_TYPE @tablebulletend + + @return + Returns the following when the type is #QURT_ECC_ERR_DETECTED_STATUS: + - 0 -- No error detected \n + - 1 -- At least one error detected \n + Returns the following when the type is #QURT_ECC_ERR_TYPE: \n + - 0 through 1 -- Correctable error \n + - 2 -- Uncorrectable error + + @dependencies + None. + */ +int qurt_ecc_get_error_status( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_get_error_count + Gets the ECC error count for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values:\n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT @tablebulletend + + @return + Error count for the specified error type. + + @dependencies + None. + */ +int qurt_ecc_get_error_count( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_clear_error_count + Clears ECC error count or region logging for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: \n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one or multiple OR'ed of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT \n + - #QURT_ECC_REGION_LOGGING @tablebulletend + + @return + #QURT_EOK -- Error count successfully cleared \n + Others -- Failure at clearing the error count + + @dependencies + None. + */ +int qurt_ecc_clear_error_count( qurt_ecc_memory_t memory, unsigned int type ); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ECC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_error.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_error.h new file mode 100755 index 0000000000000..f4666b396c378 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_error.h @@ -0,0 +1,149 @@ +#ifndef QURT_ERROR_H +#define QURT_ERROR_H + +/** + @file qurt_error.h + Error results- QURT defines a set of standard symbols for the error result values. This file lists the + symbols and their corresponding values. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021-2022 , 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ +#include "qurt_except.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup chapter_error +@{ */ + +/*===================================================================== +Constants and macros +======================================================================*/ +#define QURT_EOK 0 /**< Operation successfully performed. */ +#define QURT_EVAL 1 /**< Wrong values for the parameters. The specified page does not exist. */ +#define QURT_EMEM 2 /**< Not enough memory to perform the operation.*/ + +#define QURT_EINVALID 4 /**< Invalid argument value; invalid key. */ +/** @cond */ +#define QURT_EUNKNOWN 6 /**< Defined but never used in QuRT. */ +#define QURT_ENOMSGS 7 /**< Message queue is empty. */ +#define QURT_EBADF 9 /**< Bad message queue descriptor. */ +/** @endcond */ +#define QURT_EFAILED 12 /**< Operation failed. */ + +#define QURT_ENOTALLOWED 13 /**< Operation not allowed. */ + +/** @cond */ +#define QURT_EDUPCLSID 14 /*< Duplicate class ID. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOREGISTERED 20 /**< No registered interrupts.*/ +/** @endcond */ + + +/** @cond */ +#define QURT_EISDB 21 /*< Power collapse failed due to ISDB being enabled. */ +#define QURT_ESTM 22 /*< Power collapse failed in a Single-threaded mode check. */ +/** @endcond */ + + +/** @cond rest_reg_dist */ +#define QURT_ETLSAVAIL 23 /**< No free TLS key is available. */ +#define QURT_ETLSENTRY 24 /**< TLS key is not already free. */ +/** @endcond */ + +#define QURT_EINT 26 /**< Invalid interrupt number (not registered). */ +/** @cond rest_reg_dist */ +#define QURT_ESIG 27 /**< Invalid signal bitmask (cannot set more than one signal at a time). */ +/** @endcond */ + +/** @cond */ +#define QURT_EHEAP 28 /**< No heap space is available. */ +#define QURT_ENOSPC 28 /**< No space to create another queue in the system. */ +#define QURT_EMEMMAP 29 /**< Physical address layout is not supported by the kernel. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOTHREAD 30 /**< Thread no longer exists. */ +/** @endcond */ +/** @cond */ +#define QURT_EL2CACHE 31 /**< L2cachable is not supported in kernel invalidate/cleaninv. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_EALIGN 32 /**< Not aligned. */ +#define QURT_EDEREGISTERED 33 /**< Interrupt is already deregistered.*/ +/** @endcond */ + +/** @cond internal_only */ + +#define QURT_ETLBCREATESIZE 34 /**< TLB create error -- Incorrect size.*/ +#define QURT_ETLBCREATEUNALIGNED 35 /**< TLB create error -- Unaligned address.*/ +/** @endcond */ +/** @cond rest_reg_dist*/ +#define QURT_EEXISTS 35 /**< File or message queue already exists. */ +#define QURT_ENAMETOOLONG 36 /**< Name too long for message queue creation. */ +#define QURT_EPRIVILEGE 36 /**< Caller does not have privilege for this operation.*/ + +#define QURT_ECANCEL 37 /**< A cancellable request was canceled because the associated process was asked to exit.*/ +/** @endcond */ + +/** @cond */ +#define QURT_EISLANDTRAP 38 /*< Unsupported TRAP is called in Island mode.*/ + +#define QURT_ERMUTEXUNLOCKNONHOLDER 39 /*< Rmutex unlock by a non-holder.*/ +#define QURT_ERMUTEXUNLOCKFATAL 40 /*< Rmutex unlock error, all except the non-holder error.*/ +#define QURT_EMUTEXUNLOCKNONHOLDER 41 /*< Mutex unlock by a non-holder.*/ +#define QURT_EMUTEXUNLOCKFATAL 42 /*< Mutex unlock error, all except the non-holder error.*/ +#define QURT_EINVALIDPOWERCOLLAPSE 43 /*< Invalid power collapse mode requested. */ +/** @endcond */ +#define QURT_EISLANDUSEREXIT 44 /**< User call has resulted in island exit.*/ +#define QURT_ENOISLANDENTRY 45 /**< Island mode had not yet been entered.*/ +#define QURT_EISLANDINVALIDINT 46 /**< Exited Island mode due to an invalid island interrupt.*/ +/** @cond rest_reg_dist */ +#define QURT_ETIMEDOUT 47 /**< Operation timed-out. */ +#define QURT_EALREADY 48 /**< Operation already in progress. */ +/** @endcond */ + +#define QURT_ERETRY 49 /*< Retry the operation. */ +#define QURT_EDISABLED 50 /*< Resource disabled. */ +#define QURT_EDUPLICATE 51 /*< Duplicate resource. */ +#define QURT_EBADR 53 /*< Invalid request descriptor. */ +#define QURT_ETLB 54 /*< Exceeded maximum allowed TLBs. */ +#define QURT_ENOTSUPPORTED 55 /*< Operation not supported. */ +/** @cond rest_reg_dist */ +#define QURT_ENORESOURCE 56 /**< No resource. */ +/** @endcond */ + +#define QURT_EDTINIT 57 /**< Problem with device tree intialization. */ +#define QURT_EBUFLOCK 58 /*< Buffer lock failed because it was already locked many times. */ +#define QURT_ELOCKED 59 /**< Current operation failed as the buffer is locked. */ +#define QURT_EMSGSIZE 90 /*< Message queue msg_len is greater than mq_msgsize attribute of the message queue. */ + + +#define QURT_ENOTCONFIGURED 91 /*< Interrupt is NOT configured. */ + +#define QURT_EBANDWIDTHLIMIT 92 /*< Message queue send exceed the bandwidth limit. */ + +#define QURT_ECFIVIOLATION 93 /*< CFI violation detected. */ + +#define QURT_EDESTROY 94 /**< A destroy request was made to waiting threads.*/ + +#define QURT_EHMXNOTAVAIL 95 /**< HMX is not available to target thread.*/ +#define QURT_EHMXNOTDETACHABLE 96 /**< HMX is not detachable from target thread.*/ + +#define QURT_EFATAL -1 /**< Fatal error. */ + +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ERROR_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_event.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_event.h new file mode 100755 index 0000000000000..987f0fe79f227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_event.h @@ -0,0 +1,452 @@ +#ifndef QURT_EVENT_H +#define QURT_EVENT_H +/** + @file qurt_event.h + @brief Prototypes of kernel event API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "qurt_consts.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System environment object type. + */ +/**@addtogroup sys_env_types +@{ */ +/** QuRT swap pool information type. */ +typedef struct qurt_sysenv_swap_pools { + /** @cond */ + unsigned int spoolsize; /* Swap pool size.*/ + unsigned int spooladdr; /* Swap pool start address.*/ + /** @endcond */ +}qurt_sysenv_swap_pools_t; + +/**QuRT application heap information type. */ +typedef struct qurt_sysenv_app_heap { + /** @cond */ + unsigned int heap_base; /* Heap base address.*/ + unsigned int heap_limit; /* Heap end address.*/ + /** @endcond */ +} qurt_sysenv_app_heap_t ; + +/** QuRT architecture version information type. */ +typedef struct qurt_sysenv_arch_version { + /** @cond */ + unsigned int arch_version; /*Architecture version.*/ + /** @endcond */ +}qurt_arch_version_t; + +/** QuRT maximum hardware threads information type. */ +typedef struct qurt_sysenv_max_hthreads { + /** @cond */ + unsigned int max_hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_max_hthreads_t; + +/** QuRT active hardware threads information type. */ +typedef struct qurt_sysenv_hthreads { + /** @cond */ + unsigned int hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_hthreads_t; + +/** QuRT maximum pi priority information type. */ +typedef struct qurt_sysenv_max_pi_prio { + /** @cond */ + unsigned int max_pi_prio; /*Maximum pi priority.*/ + /** @endcond */ +}qurt_sysenv_max_pi_prio_t; + +/** QuRT process name information type. */ +typedef struct qurt_sysenv_procname { + /** @cond */ + union { + unsigned int asid; /*Address space ID.*/ + unsigned int pid; /*Process ID.*/ + }; + char name[QURT_MAX_NAME_LEN]; /* Process name.*/ + /** @endcond */ +}qurt_sysenv_procname_t; + +/** QuRT stack profile count information type. */ +typedef struct qurt_sysenv_stack_profile_count { + /** @cond */ + unsigned int count; /*Stack profile count for usage.*/ + unsigned int count_watermark; /*Stack profile count for watermark.*/ + /** @endcond */ +}qurt_sysenv_stack_profile_count_t; + +/** + QuRT system error event type. + */ +typedef struct _qurt_sysevent_error_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + } qurt_sysevent_error_t ; + +typedef struct _qurt_sysevent_error_1_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + unsigned int fkey; /**< Framekey.*/ + unsigned int reserved1; /**< Reserved.*/ + unsigned int reserved2; /**< Reserved.*/ + unsigned int reserved3; /**< Reserved.*/ + } qurt_sysevent_error_1_t ; + +/** QuRT page fault error event information type. */ +typedef struct qurt_sysevent_pagefault { + qurt_thread_t thread_id; /**< Thread ID of the page fault thread. */ + unsigned int fault_addr; /**< Accessed address that caused the page fault. */ + unsigned int ssr_cause; /**< SSR cause code for the page fault. */ +} qurt_sysevent_pagefault_t ; +/** @} */ /* @endaddtogroup sys_env_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/*======================================================================*/ +/** + Gets the environment swap pool 0 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool0 (qurt_sysenv_swap_pools_t *pools ); + +/* + Gets the environment swap pool 1 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool1(qurt_sysenv_swap_pools_t *pools ); + +/**@ingroup func_qurt_sysenv_get_app_heap + Gets information on the program heap from the kernel. + + @datatypes + #qurt_sysenv_app_heap_t + + @param[out] aheap Pointer to information on the program heap. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_app_heap(qurt_sysenv_app_heap_t *aheap ); + +/**@ingroup func_qurt_sysenv_get_arch_version + Gets the Hexagon processor architecture version from the kernel. + + @datatypes + #qurt_arch_version_t + + @param[out] vers Pointer to the Hexagon processor architecture version. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter + + @dependencies + None. +*/ +int qurt_sysenv_get_arch_version(qurt_arch_version_t *vers); + +/**@ingroup func_qurt_sysenv_get_max_hw_threads + Gets the maximum number of hardware threads supported in the Hexagon processor. + The API includes the disabled hardware threads to reflect the maximum + hardware thread count. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, only HW0 and HW2 are initialized by QuRT. + HW1 and HW3 are not used at all. Under such a scenario, + qurt_sysenv_get_max_hw_threads() still returns four. + + @datatypes + #qurt_sysenv_max_hthreads_t + + @param[out] mhwt Pointer to the maximum number of hardware threads supported in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_hw_threads(qurt_sysenv_max_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_hw_threads + Gets the number of hardware threads initialized by QuRT in Hexagon processor. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, QuRT only initializes HW0 and HW2. + HW1 and HW3 are not used. In this scenario, qurt_sysenv_get_hw_threads() returns 2. + + @datatypes + #qurt_sysenv_hthreads_t + + @param[out] mhwt Pointer to the number of hardware threads active in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_hw_threads(qurt_sysenv_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_max_pi_prio + Gets the maximum priority inheritance mutex priority from the kernel. + + @datatypes + #qurt_sysenv_max_pi_prio_t + + @param[out] mpip Pointer to the maximum priority inheritance mutex priority. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_pi_prio(qurt_sysenv_max_pi_prio_t *mpip ); + +/**@ingroup func_qurt_sysenv_get_process_name2 + Gets information on the system environment process names based on the client_handle argument. + + @datatypes + #qurt_sysenv_procname_t + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name2(int client_handle, qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_process_name + Gets information on the system environment process names from the kernel. + + @datatypes + #qurt_sysenv_procname_t + + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name(qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_stack_profile_count + Gets information on the stack profile count from the kernel. + + @datatypes + #qurt_sysenv_stack_profile_count_t + + @param[out] count Pointer to information on the stack profile count. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_stack_profile_count(qurt_sysenv_stack_profile_count_t *count ); + +/**@ingroup func_qurt_exception_wait + Registers the program exception handler. + This function assigns the current thread as the QuRT program exception handler and suspends the + thread until a program exception occurs. + + When a program exception occurs, the thread is awakened with error information + assigned to the parameters of this operation. + + @note1hang If no program exception handler is registered, or if the registered handler + calls exit, QuRT raises a kernel exception. + If a thread runs in Supervisor mode, any errors are treated as kernel + exceptions. + + @param[out] ip Pointer to the instruction memory address where the exception occurred. + @param[out] sp Stack pointer. + @param[out] badva Pointer to the virtual data address where the exception occurred. + @param[out] cause Pointer to the QuRT error result code. + + @return + Registry status: \n + Thread identifier -- Handler successfully registered. \n + #QURT_EFATAL -- Registration failed. + + @dependencies + None. +*/ +unsigned int qurt_exception_wait (unsigned int *ip, unsigned int *sp, + unsigned int *badva, unsigned int *cause); + +unsigned int qurt_exception_wait_ext (qurt_sysevent_error_t * sys_err); + +/**@ingroup func_qurt_exception_wait3 + Registers the current thread as the QuRT program exception handler, and suspends the thread until a + program exception occurs. + When a program exception occurs, the thread is awakened with error information assigned to the specified + error event record. + If a program exception is raised when no handler is registered (or when a handler is registered, but it calls + exit), the exception is treated as fatal.\n + @note1hang If a thread runs in Monitor mode, all exceptions are treated as kernel exceptions.\n + @note1cont This function differs from qurt_exception_wait() by returning the error information in a data + structure rather than as individual variables. It also returns additional information (for example, SSR, FP, and LR). + + @param[out] sys_err Pointer to the qurt_sysevent_error_1_t type structure. + @param[in] sys_err_size Size of the qurt_sysevent_error_1_t structure. + + @return + Registry status: \n + - #QURT_EFATAL -- Failure. \n + - Thread ID -- Success. + + @dependencies + None. +*/ + +unsigned int qurt_exception_wait3(void * sys_err, unsigned int sys_err_size); + +/**@ingroup func_qurt_exception_raise_nonfatal + Raises a nonfatal program exception in the QuRT program system. + + For more information on program exceptions, see Section @xref{dox:exception_handling}. + + This operation never returns -- the program exception handler is assumed to perform all + exception handling before terminating or reloading the QuRT program system. + + @note1hang The C library function abort() calls this operation to indicate software + errors. + + @param[in] error QuRT error result code (Section @xref{dox:error_results}). + + @return + Integer -- Unused. + + @dependencies + None. +*/ +int qurt_exception_raise_nonfatal (int error) __attribute__((noreturn)); + + +/**@ingroup func_qurt_exception_raise_fatal + Raises a fatal program exception in the QuRT system. + + Fatal program exceptions terminate the execution of the QuRT system without invoking + the program exception handler. + + For more information on fatal program exceptions, see Section @xref{dox:exception_handling}. + + This operation always returns, so the calling program can perform the necessary shutdown + operations (data logging, on so on). + + @note1hang Context switches do not work after this operation has been called. + + @return + None. + + @dependencies + None. +*/ +void qurt_exception_raise_fatal (void); + +unsigned int qurt_enable_floating_point_exception(unsigned int mask); + +/**@ingroup func_qurt_exception_enable_fp_exceptions + Enables the specified floating point exceptions as QuRT program exceptions. + + The exceptions are enabled by setting the corresponding bits in the Hexagon + control user status register (USR). + + The mask argument specifies a mask value identifying the individual floating + point exceptions to set. The exceptions are represented as defined symbols + that map into bits 0 through 31 of the 32-bit flag value. + Multiple floating point exceptions are specified by OR'ing together the individual + exception symbols.\n + @note1hang This function must be called before performing any floating point operations. + + @param[in] mask Floating point exception types. Values: \n + - #QURT_FP_EXCEPTION_ALL \n + - #QURT_FP_EXCEPTION_INEXACT \n + - #QURT_FP_EXCEPTION_UNDERFLOW \n + - #QURT_FP_EXCEPTION_OVERFLOW \n + - #QURT_FP_EXCEPTION_DIVIDE0 \n + - #QURT_FP_EXCEPTION_INVALID @tablebulletend + + @return + Updated contents of the USR. + + @dependencies + None. +*/ + +static inline unsigned int qurt_exception_enable_fp_exceptions(unsigned int mask) +{ + return qurt_enable_floating_point_exception(mask); +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EVENT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_except.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_except.h new file mode 100755 index 0000000000000..e1684c80e3d50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_except.h @@ -0,0 +1,185 @@ +#ifndef QURT_EXCEPT_H +#define QURT_EXCEPT_H + +/** + @file qurt_except.h + @brief Defines Cause and Cause2 codes for error-handling. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. + + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + QuRT supports error handling to handle CPU detected exceptions and software errors. + QuRT treats all errors as either fatal errors or nonfatal errors. + + @section sec1 Fatal errors + All supervisor mode exceptions are treated as fatal errors. + If a registered exception handler calls qurt_exit(), it is treated as a fatal error. + Fatal errors result in saving the context of primary hardware thread to QURT_error_info and the rest of the thread contexts to the corresponding TCBs. + All hardware threads are eventually stopped and the cache is flushed. + NMI exception is treated little differently from other fatal errors. QuRT saves the contexts of all the hardware threads into QURT_error_info.\n + + @subsection subsection1 Debugging fatal errors + - QURT_error_info.status.status -- Indicates that an error occured. + - QURT_error_info.status.cause -- Cause code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.cause2 -- Cause2 code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.fatal -- Indicates whether a fatal error occurred. A user error can result in a fatal error if the exceptional handler is not registered. + - QURT_error_info.status.hw_tnum -- Indicates the index of QURT_error_info.locregs[], where the context is saved when the error is fatal error. + - QURT_error_info.global_regs -- Contains the values of the global registers of Q6 + - QURT_error_info.local_regs[QURT_error_info.status.hw_tnum] -- Provides the CPU context when the error is a supervisor error. + + + + @subsection subsection2 Debugging nonfatal errors + - QURT_error_info.user_errors -- All user errors are logged here. + - QURT_error_info.user_errors.counter -- Index to last logged error. + - QURT_error_info.user_errors.entry[0...counter] -- Structure for logged error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb -- TCB for the user error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb.error -- Information about the error; Cause, Cause2, Badva and hardware thread ID. + - QURT_error_info.user_errors.entry[0...counter].error_code -- ((cause2 << 8) 'Logical Or' (cause) ); Cause and Cause 2 details are listed below. + - QURT_error_info.user_errors.entry[0...counter].hw_thread -- Hardware thread ID for error. + - QURT_error_info.user_errors.entry[0...counter].pcycle -- Pcycle for error. + +@note + Important usage note: + Cause and Cause2 are error codes to distinguish multiple errors. + SSR and BADAVA are inconclusive without the vector number. + All cause and cause2 can range from 1 to 255 and every cause can have 1 to 255 error code. + Hence the system can have up to 255 * 255 unique error codes. + The cominations is representated as ((cause2 << 8) 'Logical OR' (cause) ) + Some Cause2 codes are statically defined, whereas some are obtaned from SSR[7:0] cause codes. It depends on cause codes. + SSR cause codes are defined in Hexagon reference manual. + All possible combinations are listed below. +*/ +/** @addtogroup chapter_error +@{ */ +/* cause - error type - 8-bits*/ +#define QURT_EXCEPT_PRECISE 0x01U /**< Precise exception occurred. For this cause code, Cause2 is SSR[7:0].*/ +#define QURT_EXCEPT_NMI 0x02U /**< NMI occurred; Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS 0x03U /**< TLBMISS RW occurred; for this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_RSVD_VECTOR 0x04U /**< Interrupt raised on a reserved vector, which must never occur. Cause2 is not defined. */ +#define QURT_EXCEPT_ASSERT 0x05U /**< Kernel assert. Cause2 QURT_ABORT_* are listed below. */ +#define QURT_EXCEPT_BADTRAP 0x06U /**< trap0(num) called with unsupported num. Cause2 is 0. */ +#define QURT_EXCEPT_UNDEF_TRAP1 0x07U /**< Trap1 is not supported. Using Trap1 causes this error. Cause2 is not defined. */ +#define QURT_EXCEPT_EXIT 0x08U /**< Application called qurt_exit() or qurt_exception_raise_nonfatal(). Can be called from C library. Cause2 is "[Argument passed to qurt_exception_raise_nonfatal() & 0xFF]". */ +#define QURT_EXCEPT_TLBMISS_X 0x0AU /**< TLBMISS X (execution) occurred. Cause2 is not defined. */ +#define QURT_EXCEPT_STOPPED 0x0BU /**< Running thread stopped due to fatal error on other hardware thread. Cause2 is not defined. */ +#define QURT_EXCEPT_FATAL_EXIT 0x0CU /**< Application called qurt_fatal_exit(). Cause2 is not defined. */ +#define QURT_EXCEPT_INVALID_INT 0x0DU /**< Kernel received an invalid L1 interrupt. Cause2 is not defined. */ +#define QURT_EXCEPT_FLOATING_POINT 0x0EU /**< Kernel received an floating point error. Cause2 is not defined. */ +#define QURT_EXCEPT_DBG_SINGLE_STEP 0x0FU /**< Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS_RW_ISLAND 0x10U /**< Read write miss in Island mode. Cause2 QURT_TLB_MISS_RW_MEM* are listed below. */ +#define QURT_EXCEPT_TLBMISS_X_ISLAND 0x11U /**< Execute miss in Island mode. For this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_SYNTHETIC_FAULT 0x12U /**< Synthetic fault with user request that kernel detected. Cause2 QURT_SYNTH_* are listed below. */ +#define QURT_EXCEPT_INVALID_ISLAND_TRAP 0x13U /**< Invalid trap in Island mode. Cause2 is trap number. */ +#define QURT_EXCEPT_UNDEF_TRAP0 0x14U /**< trap0(num) was called with unsupported num. Cause2 is trap number. */ +#define QURT_EXCEPT_PRECISE_DMA_ERROR 0x28U /**< Precise DMA error. Cause2 is DM4[15:8]. Badva is DM5 register. */ + +#define QURT_ECODE_UPPER_LIBC (0U << 16) /**< Upper 16 bits is 0 for libc. */ +#define QURT_ECODE_UPPER_QURT (0U << 16) /**< Upper 16 bits is 0 for QuRT. */ +#define QURT_ECODE_UPPER_ERR_SERVICES (2U << 16) /**< Upper 16 bits is 2 for error service. */ +/** @cond */ +#define QURT_ECODE_ISLAND_INVALID_QDI 3U /**< Passing invalid QDI method in island. */ +/** @endcond */ + +/* Cause2 for QURT_EXCEPT_SYNTHETIC_FAULT cause- 8bits */ +#define QURT_SYNTH_ERR 0x01U /**< */ +#define QURT_SYNTH_INVALID_OP 0x02U /**< */ +#define QURT_SYNTH_DATA_ALIGNMENT_FAULT 0x03U /**< */ +#define QURT_SYNTH_FUTEX_INUSE 0x04U /**< */ +#define QURT_SYNTH_FUTEX_BOGUS 0x05U /**< */ +#define QURT_SYNTH_FUTEX_ISLAND 0x06U /**< */ +#define QURT_SYNTH_FUTEX_DESTROYED 0x07U /**< */ +#define QURT_SYNTH_PRIVILEGE_ERR 0x08U /**< */ + +/* Cause2 - Abort cause reason - 8 bits */ +/* ERR_ASSERT cause */ +#define QURT_ABORT_FUTEX_WAKE_MULTIPLE 0x01U /**< Abort cause - futex wake multiple. */ +#define QURT_ABORT_WAIT_WAKEUP_SINGLE_MODE 0x02U /**< Abort cause - thread waiting to wake up in Single Threaded mode. */ +#define QURT_ABORT_TCXO_SHUTDOWN_NOEXIT 0x03U /**< Abort cause - call TCXO shutdown without exit. */ +#define QURT_ABORT_FUTEX_ALLOC_QUEUE_FAIL 0x04U /**< Abort cause - futex allocation queue failure - QURTK_futexhash_lifo empty. */ +#define QURT_ABORT_INVALID_CALL_QURTK_WARM_INIT 0x05U /**< Abort cause - invalid call QURTK_warm_init() in NONE CONFIG_POWER_MGMT mode. */ +#define QURT_ABORT_THREAD_SCHEDULE_SANITY 0x06U /**< Abort cause - sanity schedule thread is not supposed to run on the current hardware thread. */ +#define QURT_ABORT_REMAP 0x07U /**< Remap in the page table; the correct behavior must remove mapping if necessary. */ +#define QURT_ABORT_NOMAP 0x08U /**< No mapping in page table when removing a user mapping. */ +#define QURT_ABORT_OUT_OF_SPACES 0x09U +#define QURT_ABORT_INVALID_MEM_MAPPING_TYPE 0x0AU /**< Invalid memory mapping type when creating qmemory. */ +#define QURT_ABORT_NOPOOL 0x0BU /**< No pool available to attach. */ +#define QURT_ABORT_LIFO_REMOVE_NON_EXIST_ITEM 0x0CU /**< Cannot allocate more futex waiting queue. */ +#define QURT_ABORT_ARG_ERROR 0x0DU +#define QURT_ABORT_ASSERT 0x0EU /**< Assert abort. */ +#define QURT_ABORT_FATAL 0x0FU /**< Fatal error; must never occur. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_QUEUE 0x10U /**< Abort cause - invalid queue ID in futex resume. */ +#define QURT_ABORT_FUTEX_WAIT_INVALID_QUEUE 0x11U /**< Abort cause - invalid queue ID in futex wait. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_FUTEX 0x12U /**< Abort cause - invalid futex object in hashtable. */ +#define QURT_ABORT_NO_ERHNDLR 0x13U /**< No registered error handler. */ +#define QURT_ABORT_ERR_REAPER 0x14U /**< Exception in the reaper thread. */ +#define QURT_ABORT_FREEZE_UNKNOWN_CAUSE 0x15U /**< Abort in thread freeze operation. */ +#define QURT_ABORT_FUTEX_WAIT_WRITE_FAILURE 0x16U /**< During futex wait processing, could not perform a necessary write operation to userland data; most likely due to a DLPager eviction. */ +#define QURT_ABORT_ERR_ISLAND_EXP_HANDLER 0x17U /**< Exception in Island exception handler task. */ +#define QURT_ABORT_L2_TAG_DATA_CHECK_FAIL 0x18U /**< Detected error in L2 tag/data during warm boot. The L2 tag/data check is done when CONFIG_DEBUG_L2_POWER_COLLAPSE is enabled. */ +#define QURT_ABORT_ERR_SECURE_PROCESS 0x19U /**< Abort error in secure process. */ +#define QURT_ABORT_ERR_EXP_HANDLER 0x20U /**< No exception handler, or the handler caused an exception. */ +#define QURT_ABORT_ERR_NO_PCB 0x21U /**< PCB of the thread context failed initialization, PCB was NULL. */ +#define QURT_ABORT_NO_PHYS_ADDR 0x22U /**< Unable to find the physical address for the virtual address. */ +#define QURT_ABORT_OUT_OF_FASTINT_CONTEXTS 0x23U /**< Fast interrupt contexts exhausted. */ +#define QURT_ABORT_CLADE_ERR 0x24U /**< Fatal error seen with CLADE interrupt. */ +#define QURT_ABORT_ETM_ERR 0x25U /**< Fatal error seen with ETM interrupt. */ +#define QURT_ABORT_ECC_DED_ASSERT 0x26U /**< ECC two-bit DED error. */ +#define QURT_ABORT_VTLB_ERR 0x27U /**< Fatal error in the VTLB layer. */ +#define QURT_ABORT_TLB_ENCODE_DECODE_FAILURE 0x28U /**< Failure during the TLB encode or decode operation. */ +#define QURT_ABORT_VTLB_WALKOBJS_BOUND_FAILURE 0x29U /**< Failure to lookup entry in the page table. */ +#define QURT_ABORT_PHY_MEMORY_OWNERSHIP_FAILURE 0x30U /**< Failure to claim phy memory ownership. */ +#define QURT_ABORT_JTLB_SIZE_CHECK_FAIL 0x31U /**< JTLB size configured is more than actual size in hardware */ +#define QURT_ABORT_AUTOSTACK_ASSERT 0x32U /**< Error while handling stack flimit exception. */ + +/* Cause2 - TLB-miss_X - 8bits */ +#define QURT_TLB_MISS_X_FETCH_PC_PAGE 0x60U /**< */ +#define QURT_TLB_MISS_X_2ND_PAGE 0x61U /**< */ +#define QURT_TLB_MISS_X_ICINVA 0x62U /**< */ + +/* Cause2 - TLB-miss_RW - 8bits */ +#define QURT_TLB_MISS_RW_MEM_READ 0x70U /**< */ +#define QURT_TLB_MISS_RW_MEM_WRITE 0x71U /**< */ + +/** @cond rest_reg_dist */ +/* Cause2 - Floating point exception - 8 bits */ +#define QURT_FLOATING_POINT_EXEC_ERR 0xBFU /**< Execute floating-point. */ +/** @endcond */ + +/** Cause2 - autostackv2 - 8 bits */ +#define QURT_AUTOSTACKV2_CANARY_NOT_MATCH 0xC1U +#define QURT_AUTOSTACKV2_POOL_IDX_OFF_RANGE 0xC2U + +/** Cause2 - CFI violation - 8 bits */ +#define QURT_CFI_VIOLATION 0xC3U + +/** @cond rest_reg_dist*/ +/* Enable floating point exceptions */ +#define QURT_FP_EXCEPTION_ALL 0x1FU << 25 /**< */ +#define QURT_FP_EXCEPTION_INEXACT 0x1U << 29 /**< */ +#define QURT_FP_EXCEPTION_UNDERFLOW 0x1U << 28 /**< */ +#define QURT_FP_EXCEPTION_OVERFLOW 0x1U << 27 /**< */ +#define QURT_FP_EXCEPTION_DIVIDE0 0x1U << 26 /**< */ +#define QURT_FP_EXCEPTION_INVALID 0x1U << 25 /**< */ + +/** @endcond */ +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EXCEPT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fastint.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fastint.h new file mode 100755 index 0000000000000..ea65dc0917fc0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fastint.h @@ -0,0 +1,71 @@ +#ifndef QURT_FASTINT_H +#define QURT_FASTINT_H + +/** + @file qurt_fastint.h + @brief QuRT fast interrupt functions + + Copyright (c) 2013-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_fastint_register + Register fast interrupt callback function + + Fast interrupt callback should be designed to perform the minimal necessary + actions for the interrupt, and/or perform some operations, such as signaling + another regular software thread to start any additional processing. + The callback should be a fast and short function. When a fast interrupt callback + is running, the corresponding interrupt cannot be re-enabled until the callback + returns. + + The fast interrupt callback must not use any system blocking calls, such as + mutex lock or signal wait. Otherwise, it results in errors. + + The fast interrupt callback function has a single integer argument and the + function ends with no return. The argument value passed in is the interrupt + number, and therefore a single callback function can handle + multiple fast interrupts. + + @param[in] intno Interrupt number to register. + @param[in] fn Interrupt callback function. + + @return + #QURT_EOK -- Fast interrupt registration is successful. \n + #QURT_EINVALID -- Interrupt is already registered. \n + #QURT_EINT -- Invalid interrupt number. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_register(int intno, void (*fn)(int)); + + +/*======================================================================*/ +/**@ingroup func_qurt_fastint_deregister + Deregisters the fast interrupt callback function. + + @param[in] intno Level-one interrupt number to deregister. Valid range is 1 and 10 through 31 + (simulator only). + + @return + #QURT_EOK -- Interrupt deregistration is successful. \n + #QURT_EINT -- Invalid interrupt number (not registered). \n + #QURT_EINVALID -- Invalid interrupt number (already deregistered). + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_deregister(int intno); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FASTINT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fs_hub.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fs_hub.h new file mode 100755 index 0000000000000..aaa050a6c838b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_fs_hub.h @@ -0,0 +1,58 @@ +#ifndef QURT_FS_HUB_H +#define QURT_FS_HUB_H + +/** + @file qurt_fs_hub.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver that provides file-system functionality. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + This structure tracks a file-designator for a FS-hub QDI driver. + File system's QDI interface should use this object to encapsulate + true file-descriptor and return back a QDI handle. This QDI handle + will be used as file-descriptor by File-systm-hub. + */ + +typedef struct qurt_qdi_fs_obj +{ + qurt_qdi_obj_t qdi_obj; + int client_handle; + int fd; +}qurt_qdi_fs_obj_t; + + +/**@ingroup fs_hub_support_functions + This function allows a file-system to register it's QDI interface with file-system-hub. + Once registered, all file open operations for any filenames containing the mountpoint will + be forwarded to the QDI inteface. + + Mountpoint string must be encased in two forward slashes e.g. "/mountpoint/" + + @param mtpoint mount point for the file-system being registered. + @param opener opener structure for the QDI driver interface + + @return + QURT_EOK -- Successfully registered QDI driver with file-system-hub. + Negative error code -- Failed to register with file-system-hub + */ +int qurt_fs_hub_mtpoint_register(const char *mtpoint, qurt_qdi_obj_t *opener); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_futex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_futex.h new file mode 100755 index 0000000000000..1fdcc79a43f01 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_futex.h @@ -0,0 +1,82 @@ +#ifndef QURT_FUTEX_H +#define QURT_FUTEX_H +/** + @file qurt_futex.h + + @brief Prototypes of QuRT futex API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Functions +======================================================================*/ + + +/**@ingroup func_qurt_futex_wait + Moves the caller thread into waiting state when a memory object address + contains a value that is the same as a specified value. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait(void *lock, int val); + + +/**@ingroup func_qurt_futex_wait_cancellable + If a memory object address contains a value that is same as a specified + value, move the caller thread into waiting state. + The kernal can cancel the waiting state when there is a special need. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait_cancellable(void *lock, int val); + + +/**@ingroup func_qurt_futex_wake + Wakes up a specified number of threads that have been waiting + for the object change with qurt_futex_wait(). + + @param[in] lock Pointer to the object memory. + @param[in] n_to_wake Maximum number of threads to wake up. + + @return + number of threads to be woken up by this function + + @dependencies + None. + */ +int qurt_futex_wake(void *lock, int n_to_wake); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hmx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hmx.h new file mode 100755 index 0000000000000..e4037dbeae514 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hmx.h @@ -0,0 +1,226 @@ +#ifndef QURT_HMX_H +#define QURT_HMX_H +/** + @file qurt_hmx.h + @brief Prototypes of Qurt HMX API. + +Copyright (c) 2019-2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + + +/** @addtogroup hmx_types +@{ */ +/* HMX locking type */ +#define QURT_HMX_NON_SHARED_LOCK 0U /**< HMX locking type.*/ +#define QURT_HMX_SHARED_LOCK 1U /**< HMX locking type.*/ + +/* HMX unlocking type */ +#define QURT_HMX_NON_SHARED_UNLOCK 0U /**< HMX unlocking type.*/ +#define QURT_HMX_SHARED_UNLOCK 1U /**< HMX unlocking type.*/ + +/* HMX hardware context */ +#define QURT_HMX_UNIT_0 0U /**< HMX hardware context #0 */ +#define QURT_HMX_UNIT_1 1U /**< HMX hardware context #1 */ + /** @} */ /* end_addtogroup hmx_types */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_hmx_lock2 + Locks a HMX unit with the specified locking type. + + #QURT_HMX_NON_SHARED_LOCK: + - If a HMX unit is available, lock the unit and return success of #QURT_EOK. + - If the HMX unit is already locked by another thread, the caller thread is suspended + until the HMX is available and gets locked by this function. + - If there is no HMX hardware supported, returns #QURT_EVAL; + + #QURT_HMX_SHARED_LOCK: + - If a HMX unit is available, enables HMX access for the caller thread, and returns + success of #QURT_EOK. + - If the HMX is enabled on the caller thread, return #QURT_EFAILED. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_SHARED_LOCK, enable HMX access for the caller + thread, and return success of #QURT_EOK. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_NON_SHARED_LOCK, return #QURT_EFAILED. + - If the HMX is locked by a thread from another user process different from the + user process of the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX lock successful.\n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_lock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_unlock2 + Unlocks a HMX unit with the unlocking type. + + #QURT_HMX_NON_SHARED_UNLOCK: + - If there is a HMX unit locked by the caller thread, unlock the HMX unit and clear the + HMX accumulators (assuming a fixed point type). + - If there is no HMX unit locked by the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + #QURT_HMX_SHARED_UNLOCK: + - If the caller thread has locked HMX with type #QURT_HMX_SHARED_LOCK, disable the + HMX access on the caller thread, and return success of #QURT_EOK. + Note: If the caller thread is the last thread that unlocks for #QURT_HMX_SHARED_LOCK + in its user process, the unlock function clears the HMX accumulators. + - If the caller thread has locked HMX with type #QURT_HMX_NON_SHARED_LOCK, return + failure of #QURT_EFAILED. + - If the caller thread has not locked HMX, return failure of #QURT_EFAILED. + - If there is no HMX hardware supported, returns #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX is unlocked successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_unlock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_lock + Locks a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away. + If there is no HMX unit available, the caller is blocked until a HMX is available + and is locked by the function. + + @return + #QURT_EOK -- HMX lock successful. \n + #QURT_EFAILED -- Failure due to wrong locking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_lock(void); + + +/**@ingroup func_qurt_hmx_unlock + Unlocks a HMX unit. + If a HMX unit is locked by the caller thread, unlock the HMX unit and clear its + accumulators(assuming fixed point type). + If there is no HMX unit locked by the caller thread, return failure. + + @return + #QURT_EOK -- HMX unlock successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_unlock(void); + + +/**@ingroup func_qurt_hmx_try_lock + Tries to lock a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away; + if there is no HMX unit available, the function returns failure without blocking the caller. + + @return + #QURT_EOK -- HMX lock successful \n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_try_lock(void); + + +/**@ingroup func_qurt_hmx_assign + Assign a HMX unit to a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + If the requested hmx_unit is already assigned to another thread with QURT_HMX_NON_SHARED_LOCK, + kernel will detach it from the thread, and re-assign it to the target thread. + If the target thread has HVX enabled, it cannot have HMX enabled. + + Locking type + #QURT_HMX_NON_SHARED_LOCK: + - If the HMX unit is available, lock the HMX unit and return success of #QURT_EOK. + - If the HMX unit is already enabled on the target thread, return #QURT_EOK. + - If the HMX unit is already locked by another thread, detach the HMX from the thread. + Re-assign the HMX unit to the target thread, and return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] type Locking type + #QURT_HMX_NON_SHARED_LOCK -- non-shared lock + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is assigned successfully. This includes the case that \n + the target thread already has HMX assigned. \n + #QURT_EFAILED -- Failure due to wrong assigning conditions. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_assign ( unsigned int thread_id, unsigned int type, unsigned int hmx_unit ); + + +/**@ingroup func_qurt_hmx_release + Release a HMX unit from a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + + Qurt detaches the specified HMX unit from the target thread, and return success of + #QURT_EOK. If the HMX unit is already released from the target thread, return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is released successfully. This includes the case that \n + the target thread already has the HMX released. \n + #QURT_EFAILED -- Failure due to wrong assigning condition. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_release ( unsigned int thread_id, unsigned int hmx_unit ); + + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HMX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hvx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hvx.h new file mode 100755 index 0000000000000..13c213d49ac84 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_hvx.h @@ -0,0 +1,421 @@ +#ifndef QURT_HVX_H +#define QURT_HVX_H +/** + @file qurt_hvx.h + @brief Prototypes of QuRT HVX API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @cond */ + +typedef enum { + QURT_HVX_MODE_64B = 0, /**< HVX mode of 64 bytes */ + QURT_HVX_MODE_128B = 1 /**< HVX mode of 128 bytes */ +} qurt_hvx_mode_t; +/** @endcond */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @cond internal_only*/ +/** @addtogroup hvx_macros +@{ */ +#define QURT_HVX_HW_UNITS_2X128B_4X64B 0x00000204 /**< Bits 15 through 8 are for the number of 128B units. */ + /**< Bits 7 through 0 are for the number of 64B units. */ +#define QURT_HVX_HW_UNITS_4X128B_0X64B 0x00000400 +#define QURT_HVX_HW_UNITS_6X128B_0X64B 0x00000600 + +/* HVX locking status */ + +#define QURT_HVX_UNLOCKED (0) /* Has not locked HVX unit */ +#define QURT_HVX_LOCKED (1) /* Has locked HVX unit */ +#define QURT_HVX_ERROR (-1) /* Error, no HVX support */ + +/* Input value for HVX reservation */ + +#define QURT_HVX_RESERVE_ALL (4) /* All the HVX units in terms of 64B_MODE are requested to be reserved */ +#define QURT_HVX_RESERVE_ALL_AVAILABLE (0xff) /* All remaining unlocked HVX units in terms of 64B_MODE are requested to be reserved */ + +/* Return values for HVX reservation */ + +#define QURT_HVX_RESERVE_NOT_SUPPORTED (-1) /* There is no HVX hardware, or less units in the hardware than requested */ +#define QURT_HVX_RESERVE_NOT_SUCCESSFUL (-2) /* Some HVX units are already locked/reserved by other PD, thus not enough units left for the reservation. */ +#define QURT_HVX_RESERVE_ALREADY_MADE (-3) /* There is already a HVX reservation made. */ +#define QURT_HVX_RESERVE_CANCEL_ERR (-4) /* The action of cancling the reservation fails because this protection domain has no reservation made before. */ + +// HVX set requests + +#define QURT_HVX_64B 0 /**< */ +#define QURT_HVX_128B 1 /**< */ +#define QURT_HVX_NO_USE 2 /**< */ +#define QURT_HVX_RELEASE_CONTEXT 3 /**< */ +#define QURT_HVX_IMMEDIATE_USE 4 /**< */ + +// HVX set masks + +#define QURT_HVX_64B_PREFERRED (1<<(QURT_HVX_64B + 8))/**< */ +#define QURT_HVX_128B_PREFERRED (1<<(QURT_HVX_128B + 8))/**< */ +#define QURT_HVX_64B_ACCEPTABLE (1<<(QURT_HVX_64B + 12))/**< */ +#define QURT_HVX_128B_ACCEPTABLE (1<<(QURT_HVX_128B + 12))/**< */ + +// HVX set return "result" + +#define QURT_EOK 0 /**< */ +#define QURT_HVX_SET_ERROR 0xFF /**< */ + +// hvx_mode_assigned for QURT_HVX_IMMEDIATE_USE +#define QURT_HVX_64B_ASSIGNED (1<<(QURT_HVX_64B + 8)) /**< */ +#define QURT_HVX_128B_ASSIGNED (1<<(QURT_HVX_128B + 8)) /**< */ + +// Sizes of HVX dump buffer + +#define QURT_HVX_V65_64B_VSIZE 2084U /**< 64 x 32 + 8 x 4 + 4 (version). */ +#define QURT_HVX_V65_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V66_128B_VSIZE 4420U /**< 128 x (32 +2) + 16 x 4 + 4 (version). */ +#define QURT_HVX_V68_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V79_128B_VSIZE 4740U /**< 128 x (32+4+1) + 4 (version). */ +#define QURT_HVX_VREG_BUF_SIZE QURT_HVX_V79_128B_VSIZE /**< */ + +// HVX dump versions + +#define QURT_HVX_DUMP_V65_64B 1U /**< */ +#define QURT_HVX_DUMP_V65_128B 2U /**< */ +#define QURT_HVX_DUMP_V66_128B 3U /**< */ +#define QURT_HVX_DUMP_V68_128B 4U /**< */ +#define QURT_HVX_DUMP_V79_128B 5U /**< */ +/** @} */ /* end_addtogroup hvx_macros */ +/** @endcond */ +/** @cond */ +// Qurt data struct for hvx_set input +typedef struct qurt_hvx_set_struct_ { + unsigned char set_req; // LSB + struct { + unsigned char preferred_mask:4; + unsigned char acceptable_mask:4; + }; + unsigned short resvd; // MSB +} qurt_hvx_set_struct_t; // 4 bytes + + +// Qurt data struct for hvx_set return +typedef struct qurt_hvx_set_return_str_ { + unsigned char result; // LSB + unsigned char hvx_mode_assigned; + unsigned short resvd; // MSB +} qurt_hvx_set_return_struct_t; // 4 bytes +/** @endcond */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_hvx_lock + Locks one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns right away. + If the current HVX mode is different from the requested mode, the current + thread is blocked. When all HVX units become idle, QuRT changes + the mode, locks the HVX unit, and returns. + + Starting from Q6v65 with HVX context switch support, qurt_hvx_lock() is + mapped as qurt_hvx_set(64_BYTE or 128_BYTE). + + @datatypes + #qurt_mode_t + + @param[in] lock_mode #QURT_HVX_MODE_64B or #QURT_HVX_MODE_128B. + + @return + #QURT_EOK -- Success \n + Other value -- Failure + + @dependencies + None. + + */ +int qurt_hvx_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_unlock + Unlocks the HVX unit held by this software thread. + + @note1hang Starting from Q6v65 with HVX context switch support, qurt_hvx_unlock() + maps as qurt_hvx_set(QURT_HVX_RELEASE_CONTEXT). + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_unlock(void); + +/**@ingroup func_qurt_hvx_try_lock + Tries to lock one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns #QURT_EOK; Otherwise, + the function returns a failure, but does not block the current software + thread to wait for the HVX unit. + Starting from Q6v65 with HVX context switch support, qurt_hvx_try_lock() + maps to qurt_hvx_set(FOR_IMMEDIATE_USE| preferred_mask | acceptable_mask); + + @datatypes + #qurt_mode_t + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_try_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_get_mode + Gets the current HVX mode configured by QuRT. + + @note1hang Returns #QURT_HVX_MODE_128B or #QURT_HVX_MODE_64B, based on + the current HVX configuration. + + @param[out] + None. + + @return + #QURT_HVX_MODE_128B \n + #QURT_HVX_MODE_64B \n + -1 -- Not available. + + @dependencies + None. + */ +int qurt_hvx_get_mode(void); + + +/**@ingroup func_qurt_hvx_get_units + Gets the HVX hardware configuration that the chipset supports. + + @note1hang The function returns the HVX hardware configuration supported by the chipset. + + @return + Bitmask of the units: 1X64, 2X64, 4X64, 1X128, 2X128, and so on.\n + - QURT_HVX_HW_UNITS_2X126B_4X64B -- V60, V62, or V65 HVX \n + - QURT_HVX_HW_UNITS_4X128B_0X64B -- V66 CDSP or newer \n + - 0 -- not available + + @dependencies + None. + + */ +int qurt_hvx_get_units(void); + + +/**@ingroup func_qurt_hvx_reserve + Reserves HVX units in terms of 64-byte mode for the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + If one HVX unit is already locked by the application in the same PD, the unit is + added to the returned count as one reserved unit for the PD. + Starting from Q6v65 with HVX context switch support, qurt_hvx_reserve() + only does basic sanity checks on HVX units. + + @datatypes + None. + + @param[in] num_units Number of HVX units in terms of 64B_MODE to reserve for the PD. + QURT_HVX_RESERVE_ALL to reserve all the HVX units. + QURT_HVX_RESERVE_ALL_AVAILABLE to reserve the remaining unlocked units. + + @return + Number of units successfully reserved, including the units already locked in the same PD. \n + #QURT_HVX_RESERVE_NOT_SUPPORTED \n + #QURT_HVX_RESERVE_NOT_SUCCESSFUL \n + #QURT_HVX_RESERVE_ALREADY_MADE + + + @dependencies + None. + + */ +int qurt_hvx_reserve(int num_units); + + +/**@ingroup func_qurt_hvx_cancel_reserve + Cancels the HVX reservation in the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + + @return + 0 -- Success \n + #QURT_HVX_RESERVE_CANCEL_ERR -- Failure + + @dependencies + None. + + */ +int qurt_hvx_cancel_reserve(void); + + +/**@ingroup func_qurt_hvx_get_lock_val + Gets the HVX locking status value of the thread of the caller. + + @note1hang Returns the status of whether the thread of the caller already locks a HVX unit or not. + + @datatypes + None. + + @return + #QURT_HVX_UNLOCKED \n + #QURT_HVX_LOCKED \n + #QURT_HVX_ERROR + + @dependencies + None. + */ +int qurt_hvx_get_lock_val(void); + +/** @cond internal_only*/ +/**@ingroup func_qurt_hvx_set + Sets the HVX configuration for the software thread of the caller. + + @datatypes + None. + + @param[in] input_arg Composed of set_request | hvx_preferred_mode_mask + | hvx_acceptable_mode_mask where set_request can be set to: \n + - #QURT_HVX_64B \n + - #QURT_HVX_128B \n + - #QURT_HVX_NO_USE \n + - #QURT_HVX_RELEASE_CONTEXT \n + - #QURT_HVX_IMMEDIATE_USE \n + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_preferred_mode_mask can be set to: \n + - #QURT_HVX_64B_PREFERRED \n + - #QURT_HVX_128B_PREFERRED + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_acceptable_mode_mask can be set to: \n + - #QURT_HVX_64B_ACCEPTABLE \n + - #QURT_HVX_128B_ACCEPTABLE @tablebulletend + + @return + Result of the HVX setting in the least significant 8 bits of the returned data. \n + #QURT_EOK -- 0 \n + #QURT_HVX_SET_ERROR -- 0xFF \n + When #QURT_HVX_IMMEDIATE_USE has a result of #QURT_EOK, + bit 8 to bit 15 of the returned data contain hvx_mode_assigned:\n + - #QURT_HVX_64B_ASSIGNED \n + - #QURT_HVX_128B_ASSIGNED + + @dependencies + None. + */ +unsigned int qurt_hvx_set(unsigned int input_arg); + + +/**@ingroup func_qurt_system_hvx_regs_get_maxsize + Returns the maximum buffer size for saving HVX registers. + + @datatypes + None. + + @return + 0 -- No HVX supported in the target. \n + #QURT_HVX_VREG_BUF_SIZE -- Maximum buffer size for saving HVX registers. + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get_maxsize(void); + + +/**@ingroup func_qurt_system_hvx_regs_get_size + Returns the buffer size for saving HVX registers for a specified thread. + + @param[in] thread_id Thread ID of the target thread. + + @return + 0 -- No HVX assgined to the thread. \n + size -- Size of the buffer in bytes for saving HVX registers for the specified thread: \n + - #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + - #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + - #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + + @dependencies + None. + + */ +unsigned int qurt_system_hvx_regs_get_size(unsigned int thread_id); + + + +/**@ingroup func_qurt_system_hvx_regs_get + Saves the HVX registers into the specified buffer. + Returns the size of the data saved into the buffer. + After calling this function for the first time on a specified thread_id, the QuRT kernel removes the internal HVX saving buffer + from the specified thread. When calling the function on the same thread_id for the second time, this function returns 0. + + @param[in] thread_id Thread ID of the target thread. + @param[in] pBuf Pointer to the buffer for HVX register saving. + The first four bytes of the buffer are for saving the HVX version. HVX registers are saved from + the fifth byte of the buffer. The address of the fifth byte should be 256 bytes aligned. + For example, a buffer can be declared at first as: \n + unsigned char vbuf[QURT_HVX_VREG_BUF_SIZE+256];\n + unsigned char *pBuf; \n + then align the buffer pointer to: \n + pBuf = vbuf; \n + pBuf += (256 - 4 - (unsigned)pBuf%256); + @param[in] size Size of the buffer provided, which is pointed by *pBuf. The buffer size should not be smaller than that + returned from qurt_system_hvx_regs_get_size(), and pBuf should be aligned as described above. + @param[out] pBuf Buffer returned with the saved HVx registers (unsigned char hvx_regs[];), which are saved from the fith + byte of the buffer, and the HVX version (unsigned int hvx_version;), which in the first four bytes + contain one of the HVX dump versions:\n + - #QURT_HVX_DUMP_V65_64B \n + - #QURT_HVX_DUMP_V65_128B \n + - #QURT_HVX_DUMP_V66_128B \n + - #QURT_HVX_DUMP_V68_128B \n + - #QURT_HVX_DUMP_V79_128B \n + @tablebulletend + + @return + Total bytes of the data saved in the provided buffer. \n + 0 -- No HVX assigned to the thread \n + #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get(unsigned int thread_id, void *pBuf, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HVX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_int.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_int.h new file mode 100755 index 0000000000000..386aeda1051eb --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_int.h @@ -0,0 +1,509 @@ +#ifndef QURT_INT_H +#define QURT_INT_H +/** + @file qurt_int.h + @brief QuRT interrupt functions. + + + + Copyright (c) 2013-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/** @cond rest_reg_dist */ +/** @addtogroup interrupts_constants +@{ */ +#define SIG_INT_ABORT 0x80000000 /**< */ +#define QURT_INT_NON_DELAYED_ACK 0 +#define QURT_INT_DELAYED_ACK 1 +#define QURT_INT_ACK_DEFAULT QURT_INT_NON_DELAYED_ACK +#define QURT_INT_DRV_DEFAULT 0 +#define QURT_INT_PRIORITY_DEFAULT 0xFF + +/** QuRT interrupt property. */ +#define QURT_INT_CONFIGID_POLARITY 0x1U /**< */ +#define QURT_INT_CONFIGID_LOCK 0x2U /**< */ + +/** QuRT interrupt lock.*/ +#define QURT_INT_LOCK_DEFAULT 0x0 /**< Default. */ +#define QURT_INT_LOCK_DISABLE 0x0 /**< Interrupt can be enabled or disabled or deregistered. */ +#define QURT_INT_LOCK_ENABLE 0x1 /**< Interrupt is locked and cannot be enabled, disabled, or deregistered.*/ +/** @} */ /* end_addtogroup interrupts_constants */ + +/** @addtogroup Qurt_interrupt_type +@{ */ +/** Trigger type bit fields for a PDC interrupt:\n + @verbatim + Polarity Edge Output\n + 0 00 Level sensitive active low + 0 01 Rising edge sensitive + 0 10 Falling edge sensitive + 0 11 Dual edge sensitive + 1 00 Level sensitive active high + 1 01 Falling edge sensitive + 1 10 Rising edge sensitive + 1 11 Dual edge sensitive + @endverbatim +*/ +#define QURT_INT_TRIGGER_TYPE_SET(pol, edge) ((((pol) & 0x01U) << 2) | ((edge) & 0x03U)) /**< */ + +#define QURT_INT_TRIGGER_LEVEL_LOW QURT_INT_TRIGGER_TYPE_SET(0U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_LEVEL_HIGH QURT_INT_TRIGGER_TYPE_SET(1U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_RISING_EDGE QURT_INT_TRIGGER_TYPE_SET(1U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_FALLING_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_DUAL_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x03U) /**< */ +#define QURT_INT_TRIGGER_USE_DEFAULT 0xffU /**< */ +/** @} */ /* end_addtogroup Qurt_interrupt_type */ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_interrupt_register + @xreflabel{sec:interrupt_register} + Registers the interrupt.\n + Enables the specified interrupt and associates it with the specified QuRT signal object and + signal mask. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register(int int_num, qurt_anysignal_t *int_signal, int signal_mask); + +/**@ingroup func_qurt_interrupt_register2 + @xreflabel{sec:interrupt_register2} + Registers the interrupt.\n + Enables the specified interrupt, associates it with the specified QuRT signal object and + signal mask, and sets interrupt flags. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals that the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value #QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value #QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + #QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + @param[in] flags Defines interrupt property, supported property is interrupt lock enable/disable. + Possible values for flags: \n + - #QURT_INT_LOCK_ENABLE + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register2(int int_num, qurt_anysignal_t *int_signal, int signal_mask, unsigned int flags); +/* + * Waits for registered interrupt signal + + * Suspend the current thread until one of its registered interrupts occurs. The second input mask, + * contains the interrupt signals the IST expects to receive. The interrupt signals are registered + * with interrupts via qurt_register_interrupt API. + * + * The signals returned in the signal variable indicate which interrupts occurred. Use function + * qurt_anysignal_get to read the signals. IST must locally maintain a table that maps a signal to + * a specific interrupt. IST also checks if signal #SIG_INT_ABORT is received. If so, the IST + * must quit from interrupt receiving loop. + * + * For detail information on this API, see QuRT User Manual Section 4.2.5 + * + * Prototype + * + * unsigned int qurt_anysignal_wait(qurt_anysignal_t *int_signal, unsigned int mask) + */ + +/**@ingroup func_qurt_interrupt_acknowledge + Acknowledges an interrupt after it has been processed.\n + Re-enables an interrupt and clears its pending status. This is done after an interrupt is + processed by an IST. + + Interrupts are automatically disabled after they occur. To re-enable an interrupt, an IST + performs the acknowledge operation after it has finished processing the interrupt and + just before suspending itself (such as by waiting on the interrupt signal). + + @note1hang To prevent losing or reprocessing subsequent occurrences of the interrupt, + an IST must clear the interrupt signal (Section @xref{sec:anysignal_clear}) before + acknowledging the interrupt. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Interrupt acknowledge was successful. \n + #QURT_EDEREGISTERED -- Interrupt is already de-registered. + + @dependencies + None. +*/ +int qurt_interrupt_acknowledge(int int_num); + +/**@ingroup func_qurt_interrupt_deregister + Disables the specified interrupt and disassociates it from a QuRT signal object. + If the specified interrupt was never registered (Section @xref{sec:interrupt_register}), the deregister operation + returns the status value #QURT_EINT. + + @note1hang If an interrupt is deregistered while an IST waits + to receive it, the IST might wait indefinitely for the interrupt to occur. To avoid + this problem, the QuRT kernel sends the signal #SIG_INT_ABORT to awaken an + IST after determining that it has no interrupts registered. + + @param[in] int_num L2VIC to deregister; valid range is 0 to 1023. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number (not registered). + + @dependencies + None. + +*/ +unsigned int qurt_interrupt_deregister(int int_num); +/** @endcond */ + +/**@ingroup func_qurt_interrupt_disable + Disables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + After qurt_interrupt_disable() returns, the Hexagon subsystem + can no longer send the corresponding interrupt to the Hexagon + core, until qurt_interrupt_enable() is called + for the same interrupt. + + Avoid calling qurt_interrupt_disable() and qurt_interrupt_enable() frequently within + a short period of time.\n + - A pending interrupt can already be in the Hexagon core when qurt_interrupt_disable() + is called. Therefore, some time later, the pending interrupt is received on a Hexagon + hardware thread.\n + - After the Hexagon subsystem sends an interrupt to the Hexagon core, the Hexagon + hardware automatically disables the interrupt until kernel software re-enables the interrupt + at the interrupt acknowledgement stage. If qurt_interrupt_enable() is called from a certain + thread at an ealier time, the interrupt is re-enabled earlier and can trigger + sending a new interrupt to the Hexagon core while kernel software is still processing + the previous interrupt. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully disabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_disable(int int_num); + + +/**@ingroup func_qurt_interrupt_enable + Enables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully enabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. + +*/ + unsigned int qurt_interrupt_enable(int int_num); + + +/**@ingroup func_qurt_interrupt_status + Returns a value that indicates the pending status of the specified interrupt. + + @param[in] int_num Interrupt number that is being checked. + @param[out] status Interrupt status; 1 indicates that an interrupt is + pending, 0 indicates that an interrupt is not pending. + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_status(int int_num, int *status); + + +/**@ingroup func_qurt_interrupt_get_status + Gets the status of the specified interrupt in L2VIC. + + @param[in] int_num Interrupt number that is being checked. + @param[in] status_type 0 -- interrupt pending status \n + 1 -- interrupt enabling status + @param[out] status 0 -- OFF \n + 1 -- ON + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_status(int int_num, int status_type, int *status); + +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_interrupt_clear + Clears the pending status of the specified interrupt. + + @note1hang This operation is intended for system-level use, and must be used with care. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_clear(int int_num); + + +/**@ingroup func_qurt_interrupt_get_config + Gets the L2VIC interrupt configuration. \n + This function returns the type and polarity of the specified L2VIC interrupt. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[out] int_type Pointer to an interrupt type. \n + 0 -- Level-triggered interrupt \n + 1 -- Eedge-triggered interrupt + @param[out] int_polarity Pointer to interrupt polarity.\n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt. + + @return + #QURT_EOK -- Configuration successfully returned.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_config(unsigned int int_num, unsigned int *int_type, unsigned int *int_polarity); + +/**@ingroup func_qurt_interrupt_set_config + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang Deregister L2VIC interrupts before reconfiguring them. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Interrupt type. \n + 0 -- Level-triggered interrupt\n + 1 -- Edge-triggered interrupt + @param[in] int_polarity Interrupt polarity. \n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config(unsigned int int_num, unsigned int int_type, unsigned int int_polarity); + +/**@ingroup func_qurt_interrupt_set_config2 + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Notified to the hardware configuration callback function and used to + modify the L2VIC type. Possible values: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config2(unsigned int int_num, unsigned int int_type); + +/**@ingroup func_ qurt_interrupt_set_config3 + Sets the specified configuration value for the specified property of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured for polarity. + + @param[in] int_num L2VIC interrupt to re-enable. + @param[in] config_id Property to configure: \n + - #QURT_INT_CONFIGID_POLARITY \n + - #QURT_INT_CONFIGID_LOCK @tablebulletend + @param[in] config_val Dependent on the second argument config_id, specifies the value to set. \n + Values for #QURT_INT_CONFIGID_POLARITY: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE \n + + Values for #QURT_INT_CONFIGID_LOCK: \n + - #QURT_INT_LOCK_ENABLE\n + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered or is locked for enable/disable.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. +*/ +unsigned int qurt_interrupt_set_config3(unsigned int int_num, unsigned int config_id, unsigned int config_val); + + +/**@ingroup func_qurt_interrupt_raise + Raises the interrupt. \n + This function triggers a level-triggered L2VIC + interrupt, and accepts interrupt numbers in the range of 0 to 1023. + + @param[in] interrupt_num Interrupt number. + + @return + #QURT_EOK -- Success \n + -1 -- Failure; the interrupt is not supported. + + @dependencies + None. + */ +int qurt_interrupt_raise(unsigned int interrupt_num); + +/**@ingroup func_qurt_interrupt_raise2 + Raises the interrupt and returns the current pcycle value. + + @param[in] interrupt_num Interrupt number. + + @return + 0xFFFFFFFFFFFFFFFF -- Failure; the interrupt is not supported.\n + Other value -- pcycle count at the time the interrupt is raised. + + @dependencies + None. + */ +unsigned long long qurt_interrupt_raise2(unsigned int interrupt_num); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_isr_subcall + Indicates whether the current function is called from a callback procedure (either short or long). + + @return + #QURT_EOK -- TRUE \n + #QURT_EVAL -- FALSE. + + @dependencies + None. + */ +int qurt_isr_subcall(void); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_INT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_island.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_island.h new file mode 100755 index 0000000000000..f0c8ee27cf8b0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_island.h @@ -0,0 +1,122 @@ +#ifndef QURT_ISLAND_H +#define QURT_ISLAND_H + +/** + @file qurt_island.h + @brief Prototypes of power API + The APIs allow entering and exiting island mode where the memory + accesses are limited to local memory. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_island_get_status + Gets Island mode status. + + Returns a value that indicates whether the QuRT system executes in Island mode. + + @return + 0 - Normal mode. \n + 1 - Island mode. + + @dependencies + None. +*/ +unsigned int qurt_island_get_status (void); + +/**@ingroup func_qurt_island_get_status2 + Gets Island mode status especially that differentiates between island partial exit and complete exit. + + Returns a value that indicates the current state. + + @note1hang Transition from NORMAL mode to ISLAND mode happens in single + threaded mode. Whereas transition from ISLAND mode to other modes + happen in multi-threaded mode. So, a thread that gets island mode + status as NORMAL can assume the same status till it continues to + run. A thread that gets island mode status as ISLAND should + assume that the status may change to EXITING or NORMAL while it + runs. A thread that gets island mode status as EXITING should + assume that the status may change to NORMAL while it runs. If + the thread goes to wait state in after reading the status, it should get + the island mode state again and not assume the previous state. + @note2hang This api returns more intrinsic states than qurt_island_get_status, + when qurt_island_get_status returns 0, this api could return + QURT_ISLAND_MODE_EXITING or QURT_ISLAND_MODE_ISLAND + + @param[in/out] data field is reserved for future use. If NULL pointer is passed, + the field will be ignored. If a valid pointer is passed, + QuRT will return back a bitmask which can be interpreted as follows: + data[31] - Valid bit. Set to 1 to indicate data[30:0] are valid. + Otherwise set to 0. + data[30:0] – Reserved for future definition. + + @return + QURT_ISLAND_MODE_NORMAL - Main mode \n + QURT_ISLAND_MODE_ISLAND - Island mode \n + QURT_ISLAND_MODE_EXITING - Exiting Island mode \n + + @dependencies + None. +*/ +unsigned int qurt_island_get_status2 (unsigned int *data); + + + +/**@ingroup func_qurt_island_get_exit_status + Gets the reason for the last Island mode exit status. + + @param[out] cause_code Pointer that returns the cause code of the last + island exit reason. \n + - #QURT_EISLANDUSEREXIT -- Island exit due to user call for island exit.\n + - #QURT_ENOISLANDENTRY -- API called before exiting island. \n + - #QURT_EISLANDINVALIDINT -- Island exit due to an invalid interrupt in Island mode. @tablebulletend + + @param[out] int_num Pointer that holds the invalid interrupt number that caused + island exit when the cause code is #QURT_EISLANDINVALIDINT. + For other cases, it is -1. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_exit_status(unsigned int *cause_code, int *int_num); + +/**@ingroup func_qurt_island_get_enter_timestamp + Gets the recent timestamp when the system exits STM during island enter. + + @param[out] island_enter_timestamp Returns a pointer to the recent timestamp + recorded after the system exits STM during island enter. If the system never + attempts to enter island, the island_enter_timestamp return pointer holds a value + of zero. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_enter_timestamp(unsigned long long *island_enter_timestamp); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISLAND_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_isr.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_isr.h new file mode 100755 index 0000000000000..db29ea2f265d7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_isr.h @@ -0,0 +1,177 @@ +#ifndef QURT_ISR_H +#define QURT_ISR_H + +/*===================================================================== + + @file qurt_isr.h + + @brief Prototypes of Qurt ISR API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2017, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + Functions +=============================================================================*/ + + +/**@ingroup func_qurt_isr_set_hw_config_callback + Set callback function for the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_config_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_enable_callback + Set callback function for enabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_enable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_disable_callback + Set callback function for disabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_disable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_create + Creates an ISR thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + + @return + #QURT_EVAL -- Invalid arguments + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_isr_create (qurt_thread_t *thread_id, qurt_thread_attr_t *pAttr); + +/**@ingroup func_qurt_isr_register2 + Registers an Interrupt Service Routine to an ISR thread. ISR callback with the specified attributes. + The interrupt is enabled when this function returns success. + + @datatypes + qurt_thread_t + + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create() + @param[in] int_num The interrupt number + @param[in] prio Priority of the ISR + @param[in] flags Defines ACK type. Values : \n + QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the Kernel. + QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + @param[in] int_type. Notifies it to registered function. Values: \n + - QURT_INT_TRIGGER_USE_DEFAULT + - QURT_INT_TRIGGER_LEVEL_HIGH + - QURT_INT_TRIGGER_LEVEL_LOW + - QURT_INT_TRIGGER_RISING_EDGE + - QURT_INT_TRIGGER_FALLING_EDGE + - QURT_INT_TRIGGER_DUAL_EDGE + @param[in] isr Interrupt Service Routine with proto type void isr (void *arg, int int_num) + @param[in] arg 1st argument of the ISR when it is called to service the interrupt + + @return + QURT_EOK -- Successfully registered the ISR for the interrupt + QURT_EINT -- Interrupt not configured + QURT_EINVALID -- Invalid Thread ID + QURT_EDISABLED -- The feature is disabled + QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_register2 (qurt_thread_t isr_thread_id, int int_num, unsigned short prio, unsigned short flags, unsigned int int_type, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_isr_deregister2 + De-registers the ISR for the specified interrupt. + The interrupt is disabled when this function returns success. + + @param[in] int_num The interrupt number + + @return + QURT_EOK -- ISR deregistered successfully + QURT_ENOREGISTERED -- Interrupt with int_num is not registered + + @dependencies + None. + */ +int qurt_isr_deregister2 (int int_num); + +/**@ingroup func_qurt_isr_delete + ISR thread will exit and releases Kernel resources + + @note1hang The ISR thread shouldn't be actively processing interrupts, + otherwise the call will fail and return an error. + + @param[in] thread-id of the ISR thread that needs to be deleted. + + @return + QURT_ENOTALLOWED -- ISR thread is processing an interrupt + QURT_EINVALID -- Invalid ISR thread ID + QURT_EOK -- Success + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_delete (qurt_thread_t isr_tid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISR_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_l2cfg.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_l2cfg.h new file mode 100755 index 0000000000000..7e26b30a580d9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_l2cfg.h @@ -0,0 +1,98 @@ +#ifndef QURT_L2CFG_H +#define QURT_L2CFG_H +/** + @file qurt_l2cfg.h + @brief QuRT APIs for L2 configuration and system configuration + +EXTERNAL FUNCTIONS + qurt_l2cfg_set + qurt_l2cfg_get + qurt_system_config_get + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +/* Definition for system configuration */ +/** @addtogroup l2cfg_macros +@{ */ +#define QURT_CORE_CFG_HMX_INT8_SPATIAL 0x78 /**< HMX fixed-point spatial size */ +#define QURT_CORE_CFG_HMX_INT8_DEPTH 0x7C /**< HMX fixed-point output depth */ +/** @} */ /* end_addtogroup l2cfg_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_l2cfg_set + Sets the value of a L2 configuration register. A register can be set *IFF* its + initial value is configured. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[in] value Value to set the register to. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; likely + a configuration problem. \n + #QURT_EINVALID -- Argument error. \n + #QURT_ENOTALLOWED -- Setting this register is prohibited. + + @dependencies + None. + */ +int qurt_l2cfg_set (unsigned short offset, unsigned int value); + +/**@ingroup func_qurt_l2cfg_get + Gets the value of a L2 configuration register. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[out] value Pointer to value of the register. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; + likely a configuration problem. \n + #QURT_EINVALID -- Argument error. + + @dependencies + None. + + */ +int qurt_l2cfg_get (unsigned short offset, unsigned int * value); + + +/**@ingroup func_qurt_system_config_get + Gets the system configuration information. + + @param[in] index Index to system configuration. Values:\n + - #QURT_CORE_CFG_HMX_INT8_SPATIAL \n + - #QURT_CORE_CFG_HMX_INT8_DEPTH @tablebulletend + + @param[out] data Pointer to a word for returned data. + + @return + #QURT_EOK -- Get the configuration data successful. \n + Other values -- Failure (no such configuration available). + + @dependencies + None. + + */ +int qurt_system_config_get(int index, unsigned int *data); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_L2CFG_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_lifo.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_lifo.h new file mode 100755 index 0000000000000..dc399fccc5f0f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_lifo.h @@ -0,0 +1,71 @@ +#ifndef QURT_LIFO_H +#define QURT_LIFO_H +/** + @file qurt_lifo.h + + @brief + Provide lock free LastInFirstOut algorithm, which can be used in a + variety of situations for allocation/free fixed size buffer + This implementation touches the first word of your FREED buffer. Even + though it does not matter how you use it when it is allocated, you might want + to be a bit careful not to put your MAGIC number as the first field. + Because it will not hold the magic value for "freed" + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ +/** + Pops an element out of the LIFO. + + @param[in] freelist Pointer to the head of your list. + + @return + Top object from the list + + @dependencies + None. +*/ +/* ======================================================================*/ +void * qurt_lifo_pop(void *freelist); + + +/*======================================================================*/ +/** + Pushes an element into the LIFO. + + @param[in] freelist Pointer to the head of your list. + @param[in] buf Pointer to your buffer to push into the list. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_lifo_push(void *freelist, void *buf); + +void qurt_lifo_remove(void *freelist, void *buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_LIFO_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mailbox.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mailbox.h new file mode 100755 index 0000000000000..a6cd91c611782 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mailbox.h @@ -0,0 +1,176 @@ +#ifndef QURT_MAILBOX_H +#define QURT_MAILBOX_H + +/** + @file qurt_mailbox.h + @brief Definitions, macros, and prototypes used for QuRT mailbox + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* Definitions on typedef and return values */ + +#define QURT_MAILBOX_ID_NULL 0 +#define QURT_MAILBOX_ERROR -1 +#define QURT_MAILBOX_ID_ERROR -2 +#define QURT_MAILBOX_NON_VALID_DATA -3 +#define QURT_MAILBOX_FULL -4 +#define QURT_MAILBOX_DELETED -5 +#define QURT_MAILBOX_RECEIVE_HALTED -6 +#define QURT_MAILBOX_BANDWIDTH_LIMIT -7 + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ + +#define QURT_MAILBOX_AT_QURTOS 0U // Receiver is QurtOS +#define QURT_MAILBOX_AT_ROOTPD 1U // Receiver is RootPD (ASID=0) +#define QURT_MAILBOX_AT_USERPD 2U // Receiver is User PD (ASID!=0) +#define QURT_MAILBOX_AT_SECUREPD 3U // Receiver is Secure PD + +typedef unsigned char qurt_mailbox_receiver_cfg_t; + +#define QURT_MAILBOX_SEND_OVERWRITE 0U // When there is already valid content, overwrite it +#define QURT_MAILBOX_SEND_NON_OVERWRITE 1U // When there is already valid content, return failure + +typedef unsigned char qurt_mailbox_send_option_t; + + +#define QURT_MAILBOX_RECV_WAITING 0U // When there is no valid content, wait for it +#define QURT_MAILBOX_RECV_NON_WAITING 1U // When there is no valid content, return failure immediately +#define QURT_MAILBOX_RECV_PEEK_NON_WAITING 2U // Read the content, but doesn't remove it from the mailbox. No waiting. + +typedef unsigned char qurt_mailbox_recv_option_t; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/* Function prototype */ + +/**@ingroup qurt_mailbox_create + Creates a QuRT mailbox. + + @param name Mailbox name up to 8 characters. + @param recv_opt Configuration on the receiver process. + + @return + Mailbox ID -- Mailbox Identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at creating mailbox + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_create(char *name, qurt_mailbox_receiver_cfg_t recv_opt); + + +/**@ingroup qurt_mailbox_get_id + Gets a QuRT mailbox identifier. + + @param name Mailbox name up to 8 characters. + + @return + Mailbox ID -- Mailbox identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at getting mailbox ID + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_get_id(char *name); + + +/**@ingroup qurt_mailbox_send + Sends data to a QuRT mailbox. + + @param mailbox_id Mailbox identifier. + @param send_opt Option for mailbox send. + @param data Data to send. + + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors.\n + #QURT_MAILBOX_FULL Valid data already exists, non-overwriting.\n + #QURT_MAILBOX_BANDWIDTH_LIMIT Reached the bandwidth limitation. + + @dependencies + None. +*/ +int qurt_mailbox_send(unsigned long long mailbox_id, qurt_mailbox_send_option_t send_opt, unsigned long long data); + + +/**@ingroup qurt_mailbox_receive + Receive data from QuRT mailbox + + @param mailbox_id Mailbox Identifier + @param send_opt Option for mailbox receiving + @param data Pointer to data buffer for receiving + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. \n + #QURT_MAILBOX_NON_VALID_DATA No current valid data, put the previous content in the buffer. \n + #QURT_MAILBOX_RECEIVE_HALTED Receive halted, the waiting thread is woken up. \n + #QURT_MAILBOX_DELETED Mailbox is deleted, and the waiting thread is woken up. + + @dependencies + None. +*/ +int qurt_mailbox_receive(unsigned long long mailbox_id, qurt_mailbox_recv_option_t recv_opt, unsigned long long *data); + + +/**@ingroup qurt_mailbox_delete + Deletes a QuRT mailbox. + + A mailbox can only be deleted from the process that created the mailbox. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_delete(unsigned long long mailbox_id); + + +/**@ingroup qurt_mailbox_receive_halt + Halts a QuRT mailbox receiving and wakes up waiting threads. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_receive_halt(unsigned long long mailbox_id); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_MAILBOX_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_memory.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_memory.h new file mode 100755 index 0000000000000..90ce2586fec50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_memory.h @@ -0,0 +1,1487 @@ +#ifndef QURT_MEMORY_H +#define QURT_MEMORY_H +/** + @file qurt_memory.h + @brief Prototypes of kernel memory API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup memory_management_macros +@{ */ +#define QURT_SYSTEM_ALLOC_VIRTUAL 1 /**< Allocates available virtual memory in the address space of all + processes.*/ +/** @} */ /* end_addtogroup memory_management_macros */ +/**@cond rest_reg_dist */ +/** @addtogroup memory_management_types +@{ */ +/** @xreflabel{hdr:qurt_mem_default_pool} */ +extern qurt_mem_pool_t qurt_mem_default_pool __attribute__((section(".data"))); /**< Memory pool object.*/ +/** @} */ /* end_addtogroup memory_management_types */ + +/** @cond rest_reg_dist */ +/** Mapping attribute information*/ +typedef struct{ + qurt_paddr_64_t paddr; + qurt_size_t size ; + qurt_mem_cache_mode_t cache_mode; + qurt_perm_t perms ; +}qurt_mapping_attr_t; +/** @endcond */ +/** @} */ /* end_addtogroup mapping_attribute_types*/ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_mem_cache_clean + Performs a cache clean operation on the data stored in the specified memory area. + Peforms a syncht on all the data cache operations when the Hexagon processor version is V60 or greater. + + @note1hang Perform the flush all operation only on the data cache. + + @note1cont This operation flushes and invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed and invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_ALL\n + @note1 #QURT_MEM_CACHE_FLUSH_ALL is valid only when the type is #QURT_MEM_DCACHE @tablebulletend + @param[in] type Cache type. Values: + - #QURT_MEM_ICACHE + - #QURT_MEM_DCACHE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type.\n + + @dependencies + None. +*/ +int qurt_mem_cache_clean(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_clean2 + Performs a data cache clean operation on the data stored in the specified memory area. + + This API only performs the following data cache operations:\n + - #QURT_MEM_CACHE_FLUSH\n + - #QURT_MEM_CACHE_INVALIDATE\n + - #QURT_MEM_CACHE_FLUSH_INVALIDATE -- flushes/invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed/invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values:\n #QURT_MEM_CACHE_FLUSH\n #QURT_MEM_CACHE_INVALIDATE\n + #QURT_MEM_CACHE_FLUSH_INVALIDATE + @param[in] type Cache type. Values: \n #QURT_MEM_DCACHE + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type. + + @dependencies + None. +*/ +int qurt_mem_cache_clean2(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_phys_clean + Performs a cache clean operation on the data stored in the specified memory area based on address match and mask. + Operate on a cache line when (LINE.PhysicalPageNumber & mask) == addrmatch. + + @note1hang The addrmatch value should be the upper 24-bit physical address to match against. + + @datatypes + #qurt_mem_cache_op_t \n + + @param[in] mask 24-bit address mask. + @param[in] addrmatch Physical page number (24 bits) of memory to use as an address match. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid operation + + @dependencies + None. +*/ + +int qurt_mem_cache_phys_clean(unsigned int mask, unsigned int addrmatch, qurt_mem_cache_op_t opcode); + +/**@ingroup func_qurt_mem_l2cache_line_lock + Performs an L2 cache line locking operation. This function locks selective lines in the L2 cache memory. + + @note1hang Perform the line lock operation only on the 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to lock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of L2 cache memory to line lock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success.\n + #QURT_EALIGN -- Data alignment or address failure. + #QURT_EINVALID -- Improper addr and size passed (e.g. integer overflow due to addr + size) + #QURT_EFAILED -- Failed to lock cache line as all the ways were locked for the corresponding set of an address + in the range of addr and addr+size or the address range is not L2 cacheable + @dependencies + None. +*/ +int qurt_mem_l2cache_line_lock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_l2cache_line_unlock + Performs an L2 cache line unlocking operation. This function unlocks selective lines in the L2 cache memory. + + @note1hang Perform the line unlock operation only on a 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to unlock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of the L2 cache memory line to unlock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success. \n + #QURT_EALIGN -- Aligning data or address failure. \n + #QURT_EFAILED -- Operation failed, cannot find the matching tag. + + @dependencies + None. +*/ +int qurt_mem_l2cache_line_unlock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_region_attr_init + @xreflabel{sec:qurt_mem_region_attr_init} + Initializes the specified memory region attribute structure with default attribute values: \n + - Mapping -- #QURT_MEM_MAPPING_VIRTUAL \n + - Cache mode -- #QURT_MEM_CACHE_WRITEBACK \n + - Physical address -- -1 \n + - Virtual address -- -1 \n + - Memory type -- #QURT_MEM_REGION_LOCAL \n + - Size -- -1 + + @note1hang The memory physical address attribute must be explicitly set by calling the + qurt_mem_region_attr_set_physaddr() function. The size and pool attributes are set directly + as parameters in the memory region create operation. + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the destination structure for the memory region attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attach + Initializes a memory pool object to attach to a pool predefined in the system + configuration file. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. They are specified in memory region create operations + (Section @xref{sec:mem_region_create}). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool attach + operation is necessary only when allocating memory regions in nonstandard + memory units such as TCM. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach(char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_attach2 + Gets the identifier that corresponds to a pool object created specifically for a client, for example, HLOS_PHYSPOOL. + The client_handle is used to look up the client specific pool. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. Memory pool objects are specified during mapping creation operations + (qurt_mem_mmap() and qurt_mem_region_create()). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool_attach2 + operation is necessary only when allocating memory regions in memory units specific to the client. + + @datatypes + #qurt_mem_pool_t + + @param[in] client_handle Client identifier used by the OS to lookup the identifier + for client specific pool + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach2(int client_handle, char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_create + @xreflabel{hdr:qurt_mem_pool_create} + Dynamically creates a memory pool object from a physical address range. + + The pool is assigned a single memory region with the specified base address and size. + + The base address and size values passed to this function must be aligned to 4K byte + boundaries, and must be expressed as the actual base address and size values divided by 4K. + + For example, the function call: + @code + qurt_mem_pool_create ("TCM_PHYSPOOL", 0xd8020, 0x20, &pool) + @endcode + ... is equivalent to the following static pool definition in the QuRT system configuration file: + @code + + + + @endcode + + @cond rest_dist For more information on the system configuration file, see @xhyperref{80VB41979,80-VB419-79}. @endcond + + @note1hang Dynamically created pools are not identical to static pools. In particular, + qurt_mem_pool_attr_get() is not valid with dynamically created pools. + + @note1cont Dynamic pool creation permanently consumes system resources, and cannot be undone. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[in] base Base address of the memory region (divided by 4K). + @param[in] size Size (in bytes) of the memory region (divided by 4K). + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_mem_pool_create(char *name, unsigned base, unsigned size, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_add_pages + Adds a physical address range to the specified memory pool object.\n + + @note1hang Call this operation only with root privileges (guest OS mode). + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_mem_pool_add_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages); + +/**@ingroup func_qurt_mem_pool_remove_pages + Removes a physical address range from the specified memory pool object. + + If any part of the address range is in use, this operation returns an + error without changing the state. + + @note1hang Call this operation only with root privileges (guest-OS mode). + + @note1cont In the future, this operation will support (via the flags parameter) the + removal of a physical address range when part of the range is in use. + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + @param[in] flags Remove options. Values: \n + - 0 -- Skip holes in the range that are not part of the pool (default) \n + - #QURT_POOL_REMOVE_ALL_OR_NONE -- Pages are removed only if the specified + physical address range is entirely contained (with no holes) in the + pool free space. @tablebulletend + @param[in] callback Callback procedure called when pages were successfully removed. + Not called if the operation failed. Passing 0 as the parameter + value causes the callback to not be called. + @param[in] arg Value passed as an argument to the callback procedure. + + @return + #QURT_EOK -- Pages successfully removed. + + @dependencies + None. +*/ +int qurt_mem_pool_remove_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages, + unsigned flags, + void (*callback)(void *), + void *arg); +/**@ingroup memory_management_types*/ +#define QURT_POOL_REMOVE_ALL_OR_NONE 1 /**< */ + +/**@ingroup func_qurt_mem_pool_attr_get + Gets the memory pool attributes. \n + Retrieves pool configurations based on the pool handle, and fills in + the attribute structure with configuration values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_attr_t + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[out] attr Pointer to the memory region attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_attr_get (qurt_mem_pool_t pool, qurt_mem_pool_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attr_get_size + Gets the size of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] size Pointer to the destination variable for the range size. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_size (qurt_mem_pool_attr_t *attr, int range_id, qurt_size_t *size){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*size) = 0; + return QURT_EINVALID; + } + else { + (*size) = attr->ranges[range_id].size; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr + Gets the start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_t *addr){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; + } + else { + (*addr) = (attr->ranges[range_id].start)<<12; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr_64 + Gets the 64 bit start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_64_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr_64 (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_64_t *addr){ +if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; +} +else { + (*addr) = ((qurt_addr_64_t)attr->ranges[range_id].start)<<12; + } + return QURT_EOK; + } + + +/**@ingroup func_qurt_mem_pool_status_get + Gets the memory pool status. \n + Based on the pool handle, retrieves largest contiguous free memory, + total free memory, and total memory declared for the pool in bytes. Fills in + the memory status structure with the values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_status_t + + @param[in] pool Pool handle. + @param[out] status Pointer to the memory pool status structure. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_status_get (qurt_mem_pool_t pool, qurt_mem_pool_status_t *status); + + +/**@ingroup func_qurt_mem_pool_is_available + Checks whether the number of pages that the page_count argument indicates + can be allocated from the specified pool. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_mem_mapping_t \n + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[in] page_count Number of 4K pages. + @param[in] mapping_type Variable of type qurt_mem_mapping_t. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Mapping_type is invalid. \n + #QURT_EMEM -- Specified pages cannot be allocated from the pool. + + @dependencies + None. +*/ +int qurt_mem_pool_is_available(qurt_mem_pool_t pool, int page_count, qurt_mem_mapping_t mapping_type); + + +/**@ingroup func_qurt_mem_region_create + @xreflabel{sec:mem_region_create} + Creates a memory region with the specified attributes. + + The application initializes the memory region attribute structure with + qurt_mem_region_attr_init() and qurt_mem_region_attr_set_bus_attr(). + + If the virtual address attribute is set to its default value + (Section @xref{sec:qurt_mem_region_attr_init}), the virtual address of the memory region is + automatically assigned any available virtual address value. + + If the memory mapping attribute is set to virtual mapping, the physical address of the memory region + is also automatically assigned.\n + + @note1hang The physical address attribute is explicitly set in the attribute structure only + for memory regions with physical-contiguous-mapped mapping. + + Memory regions are always assigned to memory pools. The pool value specifies the memory pool + that the memory region is assigned to. + + @note1hang If attr is specified as NULL, the memory region is created with default + attribute values (Section @xref{sec:qurt_mem_region_attr_init}). + QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}), which allocates memory regions in SMI memory. + + @datatypes + #qurt_mem_region_t \n + #qurt_size_t \n + #qurt_mem_pool_t \n + #qurt_mem_region_attr_t + + @param[out] region Pointer to the memory region object. + @param[in] size Memory region size (in bytes). If size is not an integral multiple of 4K, + it is rounded up to a 4K boundary. + @param[in] pool Memory pool of the region. + @param[in] attr Pointer to the memory region attribute structure. + + @return + #QURT_EOK -- Memory region successfully created.\n + #QURT_EMEM -- Not enough memory to create region. + #QURT_EINVALID -- Invalid cache attributes / permissions provided in attribute. + + @dependencies + None. +*/ +int qurt_mem_region_create(qurt_mem_region_t *region, qurt_size_t size, qurt_mem_pool_t pool, qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_region_delete + Deletes the specified memory region. + + If the caller application creates the memory region, it is removed and the system reclaims its + assigned memory. + + If a different application creates the memory region (and is shared with the caller + application), only the local memory mapping to the region is removed; the system does + not reclaim the memory. + + @datatypes + #qurt_mem_region_t + + @param[in] region Memory region object. + + @returns + #QURT_EOK -- Region successfully deleted. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. +*/ +int qurt_mem_region_delete(qurt_mem_region_t region); + + +/**@ingroup func_qurt_mem_region_attr_get + @xreflabel{sec:mem_region_attr_get} + Gets the memory attributes of the specified message region. + After a memory region is created, its attributes cannot be changed. + + @datatypes + #qurt_mem_region_t \n + #qurt_mem_region_attr_t + + @param[in] region Memory region object. + @param[out] attr Pointer to the destination structure for memory region attributes. + + @return + #QURT_EOK -- Operation successfully performed. \n + Error code -- Failure. + + @dependencies + None. +*/ +int qurt_mem_region_attr_get(qurt_mem_region_t region, qurt_mem_region_attr_t *attr); + + +/**@ingroup func_qurt_mem_region_attr_set_type + Sets the memory type in the specified memory region attribute structure. + + The type indicates whether the memory region is local to an application or shared between + applications. + @cond rest_dist For more information, see @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in,out] attr Pointer to memory region attribute structure. + @param[in] type Memory type. Values: \n + - #QURT_MEM_REGION_LOCAL \n + - #QURT_MEM_REGION_SHARED @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t type){ + attr->type = type; +} + +/**@ingroup func_qurt_mem_region_attr_get_size + Gets the memory region size from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] size Pointer to the destination variable for memory region size. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_size(qurt_mem_region_attr_t *attr, qurt_size_t *size){ + (*size) = attr->size; +} + +/**@ingroup func_qurt_mem_region_attr_get_type + Gets the memory type from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] type Pointer to the destination variable for the memory type. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t *type){ + (*type) = attr->type; +} + +/**@ingroup func_qurt_mem_region_attr_set_physaddr + Sets the memory region 32-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise QuRT automatically sets it + when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr(qurt_mem_region_attr_t *attr, qurt_paddr_t addr){ + attr->ppn = (unsigned)(((unsigned)(addr))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr + Gets the memory region physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for memory region physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned)(((unsigned) (attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_region_attr_set_virtaddr + Sets the memory region virtual address in the specified memory attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_addr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_virtaddr(qurt_mem_region_attr_t *attr, qurt_addr_t addr){ + attr->virtaddr = addr; +} + +/**@ingroup func_qurt_mem_region_attr_get_virtaddr + Gets the memory region virtual address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for the memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_virtaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned int)(attr->virtaddr); +} + +/**@ingroup func_qurt_mem_region_attr_set_mapping + Sets the memory mapping in the specified memory region attribute structure. + + The mapping value indicates how the memory region is mapped in virtual memory. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mapping Mapping. Values: + - #QURT_MEM_MAPPING_VIRTUAL + - #QURT_MEM_MAPPING_PHYS_CONTIGUOUS + - #QURT_MEM_MAPPING_IDEMPOTENT + - #QURT_MEM_MAPPING_VIRTUAL_FIXED + - #QURT_MEM_MAPPING_NONE + - #QURT_MEM_MAPPING_VIRTUAL_RANDOM + - #QURT_MEM_MAPPING_INVALID @tablebulletend + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t mapping){ + attr->mapping_type = mapping; +} + +/**@ingroup func_qurt_mem_region_attr_get_mapping + Gets the memory mapping from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mapping Pointer to the destination variable for memory mapping. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t *mapping){ + (*mapping) = attr->mapping_type; +} + +/**@ingroup func_qurt_mem_region_attr_set_cache_mode + Sets the cache operation mode in the specified memory region attribute structure. + + @cond rest_dist For more information on the cache, see @xhyperref{80VB41992,80-VB419-92}.@endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mode Cache mode. Values: \n + - #QURT_MEM_CACHE_WRITEBACK \n + - #QURT_MEM_CACHE_WRITETHROUGH\n + - #QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE\n + - #QURT_MEM_CACHE_NONE @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t mode){ + QURT_PGATTR_C_SET(attr->pga, (unsigned)mode); +} + +/**@ingroup func_qurt_mem_region_attr_get_cache_mode + Gets the cache operation mode from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t *mode){ + unsigned int mode_temp = QURT_PGATTR_C_GET(attr->pga); + (*mode) = (qurt_mem_cache_mode_t)mode_temp; +} + +/**@ingroup func_qurt_mem_region_attr_set_bus_attr + Sets the (A1, A0) bus attribute bits in the specified memory region attribute structure. + + @cond rest_dist For more information on the bus attribute bits, see the @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] abits The (A1, A0) bits to use with the memory region, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_bus_attr(qurt_mem_region_attr_t *attr, unsigned abits){ + QURT_PGATTR_A_SET(attr->pga, abits); +} + +/**@ingroup func_qurt_mem_region_attr_get_bus_attr + Gets the (A1, A0) bus attribute bits from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] pbits Pointer to an unsigned integer that is filled in with + the (A1, A0) bits from the memory region attribute structure, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_bus_attr(qurt_mem_region_attr_t *attr, unsigned *pbits){ + (*pbits) = QURT_PGATTR_A_GET(attr->pga); +} + +void qurt_mem_region_attr_set_owner(qurt_mem_region_attr_t *attr, int handle); +void qurt_mem_region_attr_get_owner(qurt_mem_region_attr_t *attr, int *p_handle); +void qurt_mem_region_attr_set_perms(qurt_mem_region_attr_t *attr, unsigned perms); +void qurt_mem_region_attr_get_perms(qurt_mem_region_attr_t *attr, unsigned *p_perms); + +/**@ingroup func_qurt_mem_map_static_query + Determines whether a memory page is statically mapped. + Pages are specified by the following attributes: physical address, page size, cache mode, + and memory permissions. \n + - If the specified page is statically mapped, vaddr returns the virtual + address of the page. \n + - If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + The system configuration file defines QuRT memory maps. + + @datatypes + #qurt_addr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr Physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped, vaddr returns the virtual address. \n + #QURT_EMEM -- Specified page is not statically mapped, vaddr returns -1. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query(qurt_addr_t *vaddr, qurt_addr_t paddr, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + + +/**@ingroup func_qurt_mem_region_query + Queries a memory region. \n + This function determines whether a dynamically-created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. + When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns #QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_paddr_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr Physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Query successfully performed. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_t paddr); + + +/**@ingroup func_qurt_mapping_create + @xreflabel{hdr:qurt_mapping_create} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Mapping created. \n + #QURT_EMEM -- Failed to create mapping. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove + @xreflabel{hdr:qurt_mapping_remove} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Mapping created. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr + Translates a virtual memory address to the physical memory address to which it maps. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the + physical address of another process. + + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- Physical address to which the virtual address is mapped.\n + 0 -- Virtual address not mapped. + + @dependencies + None. +*/ +qurt_paddr_t qurt_lookup_physaddr (qurt_addr_t vaddr); + +/**@ingroup func_qurt_mem_region_attr_set_physaddr_64 + Sets the memory region 64-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise it is automatically set by + QuRT when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr_64 Memory region 64-bit physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t addr_64){ + attr->ppn = (unsigned)(((unsigned long long)(addr_64))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr_64 + Gets the memory region 64-bit physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr_64 Pointer to the destination variable for the memory region 64-bit physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t *addr_64){ + (*addr_64) = (unsigned long long)(((unsigned long long)(attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_map_static_query_64 + Determines if a memory page is statically mapped. + The following attributes specify pages: 64-bit physical address, page size, cache mode, + and memory permissions. \n + If the specified page is statically mapped, vaddr returns the virtual + address of the page. + If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + QuRT memory maps are defined in the system configuration file. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr_64 64-bit physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped; a virtual address is returned in vaddr. \n + #QURT_EMEM -- Specified page is not statically mapped; -1 is returned in vaddr. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query_64(qurt_addr_t *vaddr, qurt_paddr_64_t paddr_64, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mem_region_query_64 + Determines whether a dynamically created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr_64 64-bit physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query_64(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64); + +/**@ingroup func_qurt_mapping_create_64 + @xreflabel{hdr:qurt_mapping_create_64} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Failure. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove_64 + @xreflabel{hdr:qurt_mapping_remove_64} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Success. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr_64 + Translates a virtual memory address to the 64-bit physical memory address it is mapped to. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the physical + address of another process. + + @datatypes + #qurt_paddr_64_t \n + #qurt_addr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address has not been mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr_64 (qurt_addr_t vaddr); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_mapping_reclaim + Deallocates all QuRT resources associated with the specified virtual + memory area, making it available for user memory management:\n + - The associated physical memory areas are freed and added to the + specified physical pool.\n + - The associated TLB entries are deleted and made available for TLB + management.\n + - The virtual memory area is not freed -- it is left in + place as allocated, but unmapped virtual memory. Access to this + memory area generates an exception.\n + + The virtual memory area must be statically allocated. + If no pool is specified, the freed physical memory is not added to any pool. + + @note1hang The virtual memory area is restricted to being filled with locked + TLB entries that are contiguous within the memory area, and contained by it. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_pool_t + + @param[in] vaddr Virtual address of the memory area to free. + @param[in] vsize Size (in bytes) of the memory area to free. + @param[in] pool Handle to the physical pool where freed physical memory is added. + If set to 0, freed physical memory is not added to any pool. + + @return + 0 -- Success. \n + Nonzero -- Failure that indicates a partial success, or that the request was malformed. \n @note1hang The expected behavior is that + QuRT logs messages related to the failure, and callers are free to ignore the return value. + + @dependencies + None. +*/ +int qurt_mapping_reclaim(qurt_addr_t vaddr, qurt_size_t vsize, qurt_mem_pool_t pool); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_mem_configure_cache_partition + Configures the Hexagon cache partition at the system level. + + A partition size value of #SEVEN_EIGHTHS_SIZE is applicable only to the L2 cache. + + The L1 cache partition is not supported in Hexagon processor version V60 or greater. + + @note1hang Call this operation only with QuRT OS privilege. + + @datatypes + #qurt_cache_type_t \n + #qurt_cache_partition_size_t + + @param[in] cache_type Cache type for partition configuration. Values: \n + - #HEXAGON_L1_I_CACHE \n + - #HEXAGON_L1_D_CACHE \n + - #HEXAGON_L2_CACHE @tablebulletend + + @param[in] partition_size Cache partition size. Values: \n + - #FULL_SIZE \n + - #HALF_SIZE \n + - #THREE_QUARTER_SIZE \n + - #SEVEN_EIGHTHS_SIZE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Error. + + @dependencies + None. + */ +int qurt_mem_configure_cache_partition(qurt_cache_type_t cache_type, qurt_cache_partition_size_t partition_size); + + +/**@ingroup func_qurt_mem_syncht + @xreflabel{hdr:qurt_mem_syncht} + Performs heavy-weight synchronization of memory transactions. + + This operation does not return until all previous memory transactions (cached and uncached load/store, + mem_locked, and so on) that originated from the current thread are complete and globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon syncht instruction. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_syncht(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" SYNCHT \n"); + #endif +} + +/**@ingroup func_qurt_mem_barrier + @xreflabel{hdr:qurt_mem_barrier} + Creates a barrier for memory transactions. + + This operation ensures that all previous memory transactions are globally observable before any + future memory transactions are globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon barrier instruction. + @return + None + + @dependencies + None. + */ +static inline void qurt_mem_barrier(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" BARRIER \n"); + #endif +} +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_system_mem_alloc + Requests that the kernel allocates memory from the kernel-owned pool. + + @param[in] size Size in bytes (aligned to 4K) to allocate. + @param[in] align Any alignment that must be considered for the allocation. + @param[in] flags Supports the #QURT_SYSTEM_ALLOC_VIRTUAL flag; allocates + available virtual memory in the address space of all processes. + + @return + #QURT_EFATAL -- Allocation failed \n + Start address of the successful allocation. + + @dependencies + None. +*/ +unsigned qurt_system_mem_alloc(unsigned size, unsigned align, unsigned flags); +/** @endcond */ +/** @cond rest_reg_dist*/ +/**@ingroup func_qurt_lookup_physaddr2 + Translates the virtual memory address of the specified process to the 64-bit + physical memory address to which it is mapped. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[in] vaddr Virtual address. + @param[in] pid PID. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address is not mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr2(qurt_addr_t vaddr, unsigned int pid); +/** @endcond */ + +/**@ingroup func_qurt_mapping_attr_get + Gets the mapping attributes for a given virtual address and PID + + @datatypes + #qurt_addr_t \n + #qurt_mapping_attr_t + + @param[in] vaddr virtual address for which the attributes are required. + @param[in] pid process id for the target process + @param[out] attr Pointer to the mapping attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Incorrect virtual address or pid +*/ +int qurt_mapping_attr_get(qurt_addr_t vaddr, unsigned int pid, qurt_mapping_attr_t *attr); + + +/**@ingroup func_qurt_mapping_attr_get_cache_mode + Gets the cache operation mode in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] cache_mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_cache_mode(qurt_mapping_attr_t *attr, qurt_mem_cache_mode_t *cache_mode) +{ + (*cache_mode) = attr->cache_mode; +} + +/**@ingroup func_qurt_mapping_attr_get_physaddr + Gets the physical memory address in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] physaddr Pointer to the destination variable for physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_physaddr(qurt_mapping_attr_t *attr, qurt_paddr_64_t *physaddr) +{ + (*physaddr) = attr->paddr; +} + +/**@ingroup func_qurt_mapping_attr_get_perms + Gets the permissions in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_perm_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] perms Pointer to the destination variable for permissions. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_perms(qurt_mapping_attr_t *attr, qurt_perm_t *perms) +{ + (*perms) = attr->perms; +} + +/**@ingroup func_qurt_mapping_attr_get_size + Gets the size in the specified memory mapping attribute structure.This represents size of the + TLB entry which covers the virtual address. + + + @datatypes + #qurt_mapping_attr_t \n + #unsigned int + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] size Pointer to the destination variable for size. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_mapping_attr_get_size(qurt_mapping_attr_t *attr, unsigned int *size) +{ + (*size) = attr->size; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MEMORY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mmap.h new file mode 100755 index 0000000000000..c3bd875910af7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mmap.h @@ -0,0 +1,359 @@ +#ifndef QURT_MMAP_H +#define QURT_MMAP_H +/** + @file qurt_mmap.h + @brief Prototypes of memory mapping/unmapping APIs. + The APIs allow the user to map, un-map, and change permissions + on memory regions. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2022, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_mem_mmap + Creates a memory mapping with the specified attributes. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that specifies a pool handle + if the user wants to allocate memory from a specific pool. + The default value for this argument is NULL. + @param[in] pRegion Map region. This argument is unused, and the default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + @param[in] flags Mapping modes.\n + - #QURT_MAP_NAMED_MEMSECTION + - #QURT_MAP_FIXED \n + - #QURT_MAP_NONPROCESS_VPOOL \n + - #QURT_MAP_TRYFIXED \n + - #QURT_MAP_ANON \n + - #QURT_MAP_PHYSADDR \n + - #QURT_MAP_VA_ONLY @tablebulletend + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap2 + Creates a memory mapping with the specified attributes. Returns a more descriptive + error code in case of failure. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that allows the user to specify a pool handle + when the user wants to allocate memory from a specific pool. + Default value for this argument is NULL. + @param[in] pRegion Map region (unused argument); default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode. + @param[in] flags Mapping modes; + Shared, Private, or Anonymous. + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_EMEM -- Physical address is not available. \n + #QURT_EFAILED -- VA is not available or mapping failed.\n + #QURT_EINVALID -- Invalid argument was passed (for example, an unaligned VA/PA). + */ +void *qurt_mem_mmap2(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap_by_name + Creates a memory mapping for a named-memsection using the specified attributes. + The named memsection should be specified in cust_config.xml. + + @note1hang If the specified attributes are not valid or the named memsection is not found, + an error result is returned. + + @param[in] name Name of the memsection in cust_config.xml that specifies + this mapping. Should be less than 25 characters. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode + @param[in] flags Mapping modes, such as + Shared, Private, or Anonymous. + @param[in] offset Offset relative to the physical address range specified in memsection. + If offset + length exceeds size of memsection, failure is + returned. + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap_by_name(const char* name, + void *addr, + size_t length, + int prot, + int flags, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mprotect2 + Changes access permissions and attributes on an existing mapping based on the client_handle argument. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned. + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping.\n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect2(int client_handle, const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_mprotect + Changes access permissions and attributes on an existing mapping. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned.\n + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect(const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_munmap + Removes an existing mapping. + + @note1hang If the specified mapping is not found in the context of the caller process + or invalid attributes are passed, an error code is returned. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap(void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap2 + Removes an existing mapping for a specified process. + + @note1hang This API allows a root process entity, such as a driver, to remove mapping + that was created for a user process. If the specified mapping is not found in the context + of client handle or invalid attributes are passed, an error code is returned. + + @param[out] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap2(int client_handle, + void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap3 + Removes an existing mapping or reservation for a specified process. + + @param[in] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Pointer to a virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] flags Specifies the flag. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap3(int client_handle, + void *addr, + size_t length, + int flags); + +/* +|| The macros here follow the style of the standard mmap() macros, but with +|| QURT_ prepended to avoid name conflicts, and to avoid having a dependency +|| on sys/mman.h. +|| +|| Wherever possible, any values here that are also present in sys/mman.h +|| should have the same value in both places so that we can accept "mmap" +|| calls without having to remap parameters to new values. +|| +|| In the future, it would be desirable to have a regression test that +|| checks, for instance, that these macros match. Example: +|| +|| assert(QURT_MAP_FAILED == MAP_FAILED); +|| ... repeat as needed ... +*/ + +/** @addtogroup memory_mapping_macros +@{ */ +/** @cond */ +#define QURT_PROT_NONE 0x00U /**< */ +#define QURT_PROT_READ 0x01U /**< */ +#define QURT_PROT_WRITE 0x02U /**< */ +#define QURT_PROT_EXEC 0x04U /**< */ +#define QURT_PROT_NODUMP 0x08U /**< Skip dumping the mapping. During PD dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and the DSP process + crashes before the mapping is removed.*/ +#define QURT_PROT_ISLAND 0x10U /**< Island mapping. */ + +#define QURT_MAP_SHARED 0x0001U /**< Shared. */ +#define QURT_MAP_PRIVATE 0x0002U /**< Private. */ +/** @endcond */ +#define QURT_MAP_NAMED_MEMSECTION 0x0004U /**< Named memsection. */ +#define QURT_MAP_FIXED 0x0010U /**< Fixed virtual address. */ +#define QURT_MAP_RENAME 0x0020U /**< Rename. */ +#define QURT_MAP_NORESERVE 0x0040U /**< No reserve. */ +#define QURT_MAP_INHERIT 0x0080U /**< Inherit. */ +#define QURT_MAP_NONPROCESS_VPOOL 0x0100U /**< Use a virtual address outside of the default range of the + processes. This option is only supported in the root process + and only when virtual memory split is enabled in the XML. + The root process can use this flag to create mapping for a + user process, for example, if the virtual address is configured + for a 3G/1G split, the root process can use this flag to create + mapping in the top 1 GB area for the user process or the + lower 3 GB area for the root process. This is useful for + shared buffer use cases. */ +#define QURT_MAP_HASSEMAPHORE 0x0200U /**< Has semaphore. */ +#define QURT_MAP_TRYFIXED 0x0400U /**< Try to create a mapping for a virtual address that was passed. + If the passed virtual address fails, use a random virtual address. */ +#define QURT_MAP_WIRED 0x0800U /**< Wired. */ +#define QURT_MAP_FILE 0x0000U /**< File. */ +#define QURT_MAP_ANON 0x1000U /**< Allocate physical memory from the pool that was passed. + By default, memory is allocated from the default physpool. */ +#define QURT_MAP_VA_ONLY 0X2000U /**< Reserve a virtual address without + mapping it. */ + +/** @cond */ +#define QURT_MAP_ALIGNED(n) ((n) << QURT_MAP_ALIGNMENT_SHIFT) +#define QURT_MAP_ALIGNMENT_SHIFT 24 + + +#define QURT_MAP_ALIGNMENT_MASK QURT_MAP_ALIGNED(0xff) /**< */ +#define QURT_MAP_ALIGNMENT_64KB QURT_MAP_ALIGNED(16) /**< */ +#define QURT_MAP_ALIGNMENT_16MB QURT_MAP_ALIGNED(24) /**< */ +#define QURT_MAP_ALIGNMENT_4GB QURT_MAP_ALIGNED(32) /**< */ +#define QURT_MAP_ALIGNMENT_1TB QURT_MAP_ALIGNED(40) /**< */ +#define QURT_MAP_ALIGNMENT_256TB QURT_MAP_ALIGNED(48) /**< */ +#define QURT_MAP_ALIGNMENT_64PB QURT_MAP_ALIGNED(56) /**< */ +/** @endcond */ +#define QURT_MAP_FAILED ((void *) -1) /**< Mapping creation failed. */ + +/* +|| The macros below are extensions beyond the standard mmap flags, but follow +|| the style of the mmap flags. +*/ +/** @cond */ +// Describe bitfields in (prot) +#define QURT_PROT_CACHE_BOUNDS 16U,19U,7U /**< Bits 16 through 19 are cache attribute, default is 0. */ +#define QURT_PROT_BUS_BOUNDS 20U,21U,0U /**< Bits 20 through 21 are bus attributes, default is 0. */ +#define QURT_PROT_USER_BOUNDS 22U,23U,3U /**< Bits 22 through 23 are user mode, default is 3; + default of 3 means to derive user mode setting from the + default mode of the client. */ + +// Describe bitfields in (flags) +#define QURT_MAP_PHYSADDR_BOUNDS 15U,15U,0U /**< Bits 15 through 15 are physaddr, default is 0. */ +#define QURT_MAP_TYPE_BOUNDS 16U,19U,0U /**< Bits 16 through 19 are mapping type, default is 0. */ +#define QURT_MAP_REGION_BOUNDS 20U,23U,0U /**< Bits 20 through 23 are region type, default is 0. */ +/** @endcond */ + +// These macros get OR'ed into (prot) +#define QURT_PROT_CACHE_MODE(n) QURT_MMAP_BUILD(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_BUS_ATTR(n) QURT_MMAP_BUILD(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_USER_MODE(n) QURT_MMAP_BUILD(QURT_PROT_USER_BOUNDS,(n)) /**< */ +// These macros get OR'ed into (flags) + +#define QURT_MAP_PHYSADDR QURT_MMAP_BUILD(QURT_MAP_PHYSADDR_BOUNDS,1U) /**< Use the physical address that was passed in offset field. + This is allowed only for root process. */ +#define QURT_MAP_TYPE(n) QURT_MMAP_BUILD(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_REGION(n) QURT_MMAP_BUILD(QURT_MAP_REGION_BOUNDS,(n)) /**< */ +/** @} */ /* end_addtogroup memory_mapping_macros */ +/** @cond */ +// These macros extract fields from (prot) +#define QURT_PROT_GET_CACHE_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_BUS_ATTR(n) QURT_MMAP_EXTRACT(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_USER_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_USER_BOUNDS,(n)) /**< */ + +// These macros extract fields from (flags) +#define QURT_MAP_GET_TYPE(n) QURT_MMAP_EXTRACT(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_GET_REGION(n) QURT_MMAP_EXTRACT(QURT_MAP_REGION_BOUNDS,(n)) /**< */ + +// Macros for bitfield insertion and extraction +#define QURT_MMAP_MASK(lo,hi) (~((~0u) << ((hi)-(lo)+1U))) /**< Mask of same size as [lo..hi]. */ +#define QURT_MMAP_BUILD_(lo,hi,def,n) ((((n)^(def))&QURT_MMAP_MASK((lo),(hi)))<<(lo)) /**< */ +#define QURT_MMAP_EXTRACT_(lo,hi,def,n) ((((n)>>(lo))&QURT_MMAP_MASK((lo),(hi)))^(def)) /**< */ +#define QURT_MMAP_BUILD(a,b) QURT_MMAP_BUILD_(a,b) /**< */ +#define QURT_MMAP_EXTRACT(a,b) QURT_MMAP_EXTRACT_(a,b) /**< */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mq.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mq.h new file mode 100755 index 0000000000000..580c83d3de41a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mq.h @@ -0,0 +1,458 @@ +#ifndef QURT_MQ_H +#define QURT_MQ_H +/** + @file qurt_mq.h + + @brief Prototypes of secure message queues API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2019-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +======================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_MQ_NAME_MAXLEN 16U /**< Maximum name length. */ + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/* This enum must be generated in accordance to process class class numbers. + For now it is made to match generated version, do not change this unless + there is a corresponding change in the process_class.py, indicies start from 0 + basically: QURT_MQ_SECURITY_SCOPE_ = (1 << QURTK_process_class_index_) +*/ +typedef enum { + QURT_MQ_SECURITY_SCOPE_KERNEL = ( 1U << 0 ), + QURT_MQ_SECURITY_SCOPE_SRM = ( 1U << 1 ), + QURT_MQ_SECURITY_SCOPE_SECURE = ( 1U << 2 ), + QURT_MQ_SECURITY_SCOPE_CPZ = ( 1U << 3 ), + QURT_MQ_SECURITY_SCOPE_ROOT = ( 1U << 4 ), + QURT_MQ_SECURITY_SCOPE_SIGNED = ( 1U << 5 ), + QURT_MQ_SECURITY_SCOPE_UNSIGNED = ( 1U << 6 ), + QURT_MQ_SECURITY_SCOPE_SECURE_ROOT = ( 1U << 7 ) +} qurt_mq_security_scope_t; + +typedef enum { + QURT_MQ_CARDINALITY_PTP = (1U << 0), + QURT_MQ_CARDINALITY_MTO = (1U << 1) +}qurt_mq_cardinality_t; + +typedef unsigned int qurt_mqd_t; + +typedef union{ + struct { + unsigned int perms:2; + unsigned int cardinality:1; + unsigned int blocking:1; + + qurt_mq_security_scope_t creator_scope: 8; + qurt_mq_security_scope_t allowed_scope: 8; //can be a bitmask in case of MTO + unsigned int queue_closed: 1; + unsigned int reserved: 11; + }; //try to do anonymous struct + unsigned int raw; +} qurt_mq_flags_t; + + +/* permissions are from qurt_types.h , block X though */ +#if 0 +/** Memory access permission. */ +typedef enum { + QURT_PERM_READ=0x1U, /**< */ + QURT_PERM_WRITE=0x2U, /**< */ + QURT_PERM_EXECUTE=0x4U, /**< */ + QURT_PERM_FULL=QURT_PERM_READ|QURT_PERM_WRITE|QURT_PERM_EXECUTE, /**< */ +} qurt_perm_t; +#endif + +struct qurt_mq_attr { + unsigned flags; /**< Configured flags. Only meaningful with get_attr(), only used for qurt_mq_flags_t.perms. */ + unsigned mq_maxmsg; /**< Maximum number of messages. Used with create() and get_attr. */ + unsigned short mq_send_msgsize; /**< Maximum size (bytes) of message in receiver facing queue, + from sender to receiver. */ + unsigned short mq_recv_msgsize; /**< Maximum size (bytes) of message in sender facing queue, + from receiver to sender. */ + unsigned client_pid; /**< Process ID of client that is allowed to open the message queue + that was created using qurt_mq_create(). */ + qurt_mq_cardinality_t cardinality; /**< Cardinality of message queue connection, see below. */ + qurt_mq_security_scope_t scope; /**< Security scope of the senders to the queue. */ +}; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mq_attr_init + Initializes attributes to default values used for creating the queue. + + The initialize operation sets the following default attribute values: \n + - flag - QURT_PERM_READ | QURT_PERM_WRITE \n + - maxmsg - 1 \n + - mq_send_msgsize - 8 \n + - mq_recv_msgsize - 8 \n + - sender_pid - -1 \n + - cardinality - QURT_MQ_CARDINALITY_PTP \n + - scope - QURT_MQ_SECURITY_SCOPE_SIGNED \n + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the initialized message queue object. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_init(struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_attr_set_send_msgsize + Sets the message size in bytes the sender can send. + Maximum message length is configurable using the XML configuration, however, limited to a maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_send_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_recv_msgsize + Sets the message size in bytes that the receiver can read. + Maximum message length is configurable using the XML configuration, however, limited to maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_recv_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_maxmsg + Sets the maximum message that can queue in the message queue. + Message depth is configurable using the XML configuration. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] depth Maximum message that can be queued. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_maxmsg (struct qurt_mq_attr *attr, unsigned int depth); + +/**@ingroup qurt_mq_attr_set_scope + Sets the scope of the message queue. A message queue created with a security + scope allows only a process class of that scope to open a message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mq_security_scope_t + + @param[in,out] attr Pointer to the message queue object. + @param[in] scope Scope of the message queue: \n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_scope (struct qurt_mq_attr *attr, qurt_mq_security_scope_t scope); + + +/**@ingroup qurt_mq_attr_set_client_pid + Sets the client_pid that can open this message queue. + If client_pid is set, allowed_scope to open MQ shall not be considered. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] client_pid Valid PID for client process. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_client_pid (struct qurt_mq_attr *attr, unsigned client_pid); + +/**@ingroup qurt_mq_attr_set_flags + Sets the properties of the message queues. + The current implementation is only used to set the permission for the message queue using the flag attribute. + Default is #QURT_PERM_READ | #QURT_PERM_WRITE, explicit permission is not implemented. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] flags Permission for message queue. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_flags (struct qurt_mq_attr *attr, unsigned int flags); + +/**@ingroup qurt_mq_create + Create a message queue with the provided name and attributes. + The calling process becomes the owner of the queue. + Name of the message queue is limited to 16 characters including the NULL terminator. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue identifier if + the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] attr Pointer to the initialized message queue attribute + structure that specifies the attributes of the created message queue. + + @return + #QURT_EOK Message queue created. \n + #QURT_EINVALID Invalid arguments. \n + #QURT_ENOSPC Maximum number of queues in the system is exceeded. + + @dependencies + None. +*/ +int qurt_mq_create(qurt_mqd_t *mqd, const char *name, struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_open + Opens a message queue connection between a process and a created message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue + identifier if the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] flags Flag that contains the properties that define the behavior of message queue connection. + Permissions:\n + #QURT_PERM_READ \n + #QURT_PERM_WRITE \n + #QURT_PERM_READ | QURT_PERM_WRITE @tablebulletend + Default is QURT_PERM_READ | QURT_PERM_WRITE, explicit permission is not implemented \n + Cardinality: \n + #QURT_MQ_CARDINALITY_PTP (default) \n + #QURT_MQ_CARDINALITY_MTO (not implemented) \n + Block suspend thread until the message queue with the apecified name is created. \n + Scope: security boundary to which the message queue and its users are constrained. + Block suspend thread until the message queue with the apecified name is created. \n + It is coupled with process privilege level/scope.\n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED @tablebulletend + + @return + QURT_EOK -- Message queue connection successfully opened \n + QURT_EFAILED -- Message queue connection failed , if non-blocking message queue \n + QURT_ENOTALLOWED -- Open failed due to security scope mismatch + + @dependencies + None. +*/ +int qurt_mq_open (qurt_mqd_t *mqd, const char *name, qurt_mq_flags_t flags); + +/**@ingroup qurt_mq_send + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send shall resume that thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] msg_len Length of the message buffer in bytes. + + @return + #QURT_EOK Message queue send was successful.\n + #QURT_EMSGSIZE Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED Send failed due to security scope mismatch. + + @dependencies + None. +*/ +int qurt_mq_send(qurt_mqd_t mqd, const char *msg_ptr, size_t msg_len); + +/**@ingroup qurt_mq_send_timed + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message or until timeout is reached. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_send_timed shall return #QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] duration Interval (in microseconds) that the duration value must be + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in] msg_len Length of message buffer in bytes. + + @return + #QURT_EOK -- Message queue send was successful. \n + #QURT_EMSGSIZE -- Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED -- Send failed due to security scope mismatch \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. +*/ +int qurt_mq_send_timed(qurt_mqd_t mqd, const char *msg_ptr, unsigned long long int duration, size_t msg_len); + + /**@ingroup qurt_mq_recv + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue. \n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv shall resume the thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in,out] msg_len Pointer to the length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID Message pointer or msg_len ptr are NULL. \n + #QURT_EBADR Message queue descriptior (mqd) is invalid. \n + #QURT_EBADF Sender closed the message queue. + + @dependencies + None. +*/ +int qurt_mq_recv(qurt_mqd_t mqd, unsigned char *msg_ptr, size_t *msg_len); + + /**@ingroup qurt_mq_recv_timed + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue or until timeout is reached.\n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_recv_timed shall return QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in] duration Interval (in microseconds) that the duration value must be; + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in,out] msg_len Pointer to length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID -- Message ptr or msg_len ptr are NULL. \n + #QURT_EBADR -- Message queue descriptior (mqd) is invalid.\n + #QURT_EBADF -- Sender closed the message queue. \n + #QURT_ETIMEDOUT -- Timeout. + + @dependencies + None. +*/ +int qurt_mq_recv_timed(qurt_mqd_t mqd, unsigned char *msg_ptr, unsigned long long int duration, size_t *msg_len); + + /**@ingroup qurt_mq_close + Closes the message queue and disassociates the calling process (client) from the message queue + under this descriptor. Marks the queue as closed for the receiver. + This function is expected to be called from the client side. If called + from the server side, the function reduces to no-op and returns success. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue close was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_close(qurt_mqd_t mqd); + + /**@ingroup qurt_mq_destroy + Destroys the message queue. This function ought to be + called from the process that called qurt_mq_create(). + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue destroy was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_destroy(qurt_mqd_t mqd); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif //QURT_MQ_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mutex.h new file mode 100755 index 0000000000000..4ad6b270cdde6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_mutex.h @@ -0,0 +1,211 @@ +#ifndef QURT_MUTEX_H +#define QURT_MUTEX_H +/** + @file qurt_mutex.h + @brief Prototypes of mutex API. + This is mostly a user space mutex, but calls the + kernel to block if the mutex is taken. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT mutex type. + + Both non-recursive mutex lock and unlock, and recursive + mutex lock and unlock can be applied to this type. + */ +typedef union qurt_mutex_aligned8{ + /** @cond */ + struct { + unsigned int holder; + unsigned int count; + unsigned int queue; + unsigned int wait_count; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_mutex_t; +/** @} */ /* end_addtogroup mutex_types */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* @addtogroup mutex_const_macros +@{ */ +#define MUTEX_MAGIC 0xfe /**< */ +#define QURTK_FUTEX_FREE_MAGIC 0x1F // 11111 /**< */ +#define QURT_MUTEX_INIT {{MUTEX_MAGIC, 0, QURTK_FUTEX_FREE_MAGIC,0}} /**< Suitable as an initializer for a + variable of type qurt_mutex_t. */ +/* @} */ /* end_addtogroup mutex_const_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mutex_init + Initializes a mutex object. + The mutex is initially unlocked. + + @note1hang Each mutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_mutex_destroy() + when this object is not used anymore + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the mutex object. Returns the initialized object. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_destroy + Destroys the specified mutex. + + @note1hang Mutexes must be destroyed when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Mutexes must not be destroyed while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_lock + Locks the specified mutex. + If a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. + + @note1hang A thread is suspended indefinitely if it locks a mutex that it has already + locked. Avoid this by using recursive mutexes (Section @xref{dox:recursive_mutexes}). + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_lock(qurt_mutex_t *lock); /* blocking */ + +/**@ingroup func_qurt_mutex_lock_timed + Locks the specified mutex. + When a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + When a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. If the duration of suspension exceeds the timeout duration, wait is + terminated and no access to mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object; specifies the mutex to lock. + @param[in] duration Interval (in microseconds) that the duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_mutex_lock_timed (qurt_mutex_t * lock, unsigned long long int duration); + +/**@ingroup func_qurt_mutex_unlock + Unlocks the specified mutex. \n + More than one thread can be suspended on a mutex. When the mutex is unlocked, only the + highest-priority thread waiting on the mutex is awakened. If the awakened thread has + higher priority than the current thread, a context switch occurs. + + @note1hang The behavior of QuRT is undefined if a thread unlocks a mutex it did not first + lock. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to unlock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_unlock(qurt_mutex_t *lock); /* unlock */ + +/**@ingroup func_qurt_mutex_try_lock + @xreflabel{hdr:qurt_mutex_try_lock} + Attempts to lock the specified mutex. + If a thread performs a try_lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + @note1hang If a thread performs a try_lock operation on a mutex that it has already locked + or is in use by another thread, qurt_mutex_try_lock immediately returns with a + nonzero result value. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_mutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_os_services.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_os_services.h new file mode 100755 index 0000000000000..cbc4c239e9620 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_os_services.h @@ -0,0 +1,24 @@ +/*============================================================================= + + qurt_os_services.c + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ + +#define QURT_OS_SERVICE_THREAD "/os/thread" /**< Thread service */ +#define QURT_OS_SERVICE_FS_HUB "/os/fs_hub" /**< file-system hub */ +#define QURT_OS_SERVICE_CALLBACK "/os/callback" /**< QDI callback service */ +#define QURT_OS_SERVICE_INTERRUPTS "/os/interrupt" /**< Interrupt service */ +#define QURT_OS_SERVICE_PROXY "/os/proxy" /**< QDI proxy serice */ +#define QURT_OS_SERVICE_MEMORY "/os/memory" /**< Memory management service */ +#define QURT_OS_SERVICE_MEMPOOL "/os/mempool" /**< Pool management service */ +#define QURT_OS_SERVICE_PROCESS "/os/process" /**< Process management service */ +#define QURT_OS_SERVICE_MMAP "/os/mem_mapper" /**< mmapper service */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex.h new file mode 100755 index 0000000000000..61aee5cba7ce8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_PIMUTEX_H +#define QURT_PIMUTEX_H 1 +/** + @file qurt_pimutex.h + @brief Prototypes of qurt_pimutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pimutex_init + Initializes a priority inheritance mutex object. + The priority inheritance mutex is initially unlocked. + + This function works the same as qurt_mutex_init(). + + @note1hang Each pimutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_pimutex_destroy() + when this object is not used anymore + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the priority inheritance mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_destroy + Destroys the specified priority inheritance mutex. + + @note1hang Priority inheritance mutexes must be destroyed when they are no longer in + use. Failure to do this causes resource leaks in the QuRT kernel.\n + @note1cont Priority inheritance mutexes must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_lock + Requests access to a shared resources. If a thread performs a lock operation on a mutex + that is not in use, the thread gains access to the shared resource that the mutex protects, + and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + If a thread is suspended on a priority inheritance mutex, and the priority of the suspended + thread is higher than the priority of the thread that has locked the mutex, the thread + with the mutex acquires the higher priority of the suspended thread. The locker thread blocks + until the lock is available. + + @note1hang A thread is not suspended if it locks a priority inheritance mutex that it has + already locked . However, the mutex does not become available to other + threads until the thread performs a balanced number of unlocks on the mutex.\n + @note1cont When multiple threads compete for a mutex, the lock operation for a priority + inheritance mutex is slower than it is for a recursive mutex. + In particular, it is about 10 times slower when the mutex is available for locking, + and slower (with greatly varying times) when the mutex is already locked. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_lock(qurt_mutex_t *lock); + + +/**@ingroup func_qurt_pimutex_lock_timed + Locks a priority inheritance mutex with timeout. + + A thread can lock a priority inheritance mutex for multiple times. The mutex is not + available to other threads until the thread performs the same number of mutex unlock + operations. + + If a thread performs a lock operation on a mutex that is already locked by another thread, + the thread is moved to waiting state. When the mutex becomes available again (because the + other thread has unlocked the mutex), the thread is awakened and tries to lock the mutex. + + If a thread is waiting on a priority inheritance mutex, and the priority of the waiting thread + is higher than the priority of the thread that has locked the mutex, the priority of the thread + that has locked the mutex is raised to the same priority of the waiting thread. + + If the duration of waiting exceeds the timeout duration, the waiting is terminated, and + the function returns QURT_ETIMEDOUT as a failure of the mutex lock. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to lock. + @param[in] duration Duration (in microseconds) to wait. The duration value must be between + #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + #QURT_EINVALID -- Duration is out of range + + @dependencies + None. + + */ +int qurt_pimutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + + +/**@ingroup func_qurt_pimutex_unlock + Releases access to a shared resource; unlocks the specified priority inheritance mutex. \n + More than one thread can be suspended on a priority inheritance mutex. When the mutex + is unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + When a thread unlocks a priority inheritance mutex, its thread priority is restored to its + original value from any higher priority value that it acquired from another thread + suspended on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_try_lock + Request access to a shared resource (without suspend). Attempts to lock the specified priority inheritance mutex.\n + If a thread performs a try_lock operation on a priority inheritance mutex that is not in + use, the thread gains access to the shared resource that is protected by the mutex, and + continues executing. + If a thread performs a try_lock operation on a priority inheritance mutex that is already + in use by another thread, qurt_pimutex_try_lock immediately returns with a + nonzero result value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_pimutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex2.h new file mode 100755 index 0000000000000..b809f163cbfd2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pimutex2.h @@ -0,0 +1,162 @@ +#ifndef QURT_PIMUTEX2_H +#define QURT_PIMUTEX2_H +/** + @file qurt_pimutex2.h + @brief Prototypes of pimutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_pimutex2_init + Initializes a recursive mutex object. + + @deprecated use #qurt_pimutex_init instead. + + The recursive mutex is initially unlocked. + + Objects of type pimutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_destroy + + @deprecated use #qurt_pimutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1cont Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code should destroy an pimutex2 object prior to + deallocating it; calling qurt_pimutex2_destroy() before deallocating it ensures + that all qurt_pimutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_lock + + @deprecated use #qurt_pimutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not being used, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing. + + If a thread performs a lock operation on a recursive mutex that is already being used by + another thread, the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_unlock + + @deprecated use #qurt_pimutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_pimutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_pimutex2_lock(). If a call to qurt_pimutex2_lock() would + succeed immediately, this function behaves similarly, and returns 0 for success. + If a call to qurt_pimutex2_lock() would not succeed immediately, this function has + no effect and returns non-zero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_pimutex2_try_lock(qurt_rmutex2_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pipe.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pipe.h new file mode 100755 index 0000000000000..6bdaa044f8640 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pipe.h @@ -0,0 +1,479 @@ +#ifndef QURT_PIPE_H +#define QURT_PIPE_H +/** + @file qurt_pipe.h + @brief Prototypes of the pipe interface API + This is a pipe or message queue + It blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup pipe_types +@{ */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_PIPE_MAGIC 0xF1FEF1FE /**< Magic. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_RAM 0 /**< RAM. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_TCM 1 /**< TCM. */ + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** QuRT pipe data values type. */ +typedef unsigned long long int qurt_pipe_data_t; + +/** QuRT pipe type.*/ +typedef struct { + /** @cond */ + qurt_mutex_t pipe_lock; + qurt_sem_t senders; + qurt_sem_t receiver; + unsigned int size; + unsigned int sendidx; + unsigned int recvidx; + void (*lock_func)(qurt_mutex_t *); + void (*unlock_func)(qurt_mutex_t *); + int (*try_lock_func)(qurt_mutex_t *); + void (*destroy_lock_func)(qurt_mutex_t *); + unsigned int magic; + qurt_pipe_data_t *data; + /** @endcond */ +} qurt_pipe_t; + +/** QuRT pipe attributes type. */ +typedef struct { + /** @cond */ + qurt_pipe_data_t *buffer; + unsigned int elements; + unsigned char mem_partition; + /** @endcond */ +} qurt_pipe_attr_t; + +/** @} */ /* end_addtogroup pipe_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pipe_attr_init + @xreflabel{hdr:qurt_pipe_attr_init} + Initializes the structure that sets the pipe attributes when a pipe is created. + + After an attribute structure is initialized, the individual attributes in the structure are + explicitly set using the pipe attribute operations. + + The attribute structure is assigned the following default values: \n + - buffer -- 0 \n + - elements -- 0 \n + - mem_partition -- #QURT_PIPE_ATTR_MEM_PARTITION_RAM + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_init(qurt_pipe_attr_t *attr) +{ + attr->buffer = NULL; + attr->elements = 0; + attr->mem_partition = QURT_PIPE_ATTR_MEM_PARTITION_RAM; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer + @xreflabel{sec:qurt_pipe_attr_set_buffer} + Sets the pipe buffer address attribute.\n + Specifies the base address of the memory area to use for the data buffer of a pipe. + + The base address and size (Section @xref{sec:qurt_pipe_attr_set_elements}) specify the + memory area used as a pipe data buffer. The user is responsible for allocating the + memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t \n + #qurt_pipe_data_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] buffer Pointer to the buffer base address. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer(qurt_pipe_attr_t *attr, qurt_pipe_data_t *buffer) +{ + attr->buffer = buffer; +} + +/**@ingroup func_qurt_pipe_attr_set_elements + @xreflabel{sec:qurt_pipe_attr_set_elements} + Specifies the length of the memory area to use for the data buffer of a pipe. + + The length is expressed in terms of the number of 64-bit data elements that + can be stored in the buffer. + + The base address (Section @xref{sec:qurt_pipe_attr_set_buffer}) and size specify + the memory area used as a pipe data buffer. The user is responsible for + allocating the memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] elements Pipe length (64-bit elements). + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_elements(qurt_pipe_attr_t *attr, unsigned int elements) +{ + attr->elements = elements; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer_partition + @xreflabel{sec:qurt_pipe_attr_set_buffer_partition} + Specifies the memory type where a pipe's buffer is allocated. + Allocate pipes in RAM or TCM/LPM. + + @note1hang If a pipe is specified as allocated in TCM/LPM, it must be created + with the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] mem_partition Pipe memory partition. Values: \n + - #QURT_PIPE_ATTR_MEM_PARTITION_RAM -- Pipe resides in RAM \n + - #QURT_PIPE_ATTR_MEM_PARTITION_TCM -- Pipe resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer_partition(qurt_pipe_attr_t *attr, unsigned char mem_partition) +{ + attr->mem_partition = mem_partition; +} + +/**@ingroup func_qurt_pipe_create + Creates a pipe.\n + Allocates a pipe object and its associated data buffer, and initializes the pipe object. + + @note1hang The buffer address and size stored in the attribute structure specify how the + pipe data buffer is allocated. + + @note1cont If a pipe is specified as allocated in TCM/LPM, it must be created + using the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the created pipe object. + @param[in] attr Pointer to the attribute structure used to create the pipe. + + @return + #QURT_EOK -- Pipe created. \n + #QURT_EFAILED -- Pipe not created. \n + #QURT_ENOTALLOWED -- Pipe cannot be created in TCM/LPM. + + @dependencies + None. + */ +int qurt_pipe_create(qurt_pipe_t **pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_init + Initializes a pipe object using an existing data buffer. + + @note1hang The buffer address and size stored in the attribute structure must + specify a data buffer that the user has already allocated. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the pipe object to initialize. + @param[in] attr Pointer to the pipe attribute structure used to initialize the pipe. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Failure. + + @dependencies + None. + */ +int qurt_pipe_init(qurt_pipe_t *pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_destroy + @xreflabel{sec:qurt_pipe_destroy} + Destroys the specified pipe. + + @note1hang Pipes must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel. + Pipes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_destroy(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_delete + Deletes the pipe.\n + Destroys the specified pipe (Section @xref{sec:qurt_pipe_destroy}) and deallocates the pipe object and its + associated data buffer. + + @note1hang Delete pipes only if they were created using qurt_pipe_create + (and not qurt_pipe_init). Otherwise the behavior of QuRT is undefined. \n + @note1cont Pipes must be deleted when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Pipes must not be deleted while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_delete(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_send + Writes a data item to the specified pipe. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + None. + + @dependencies + None. +*/ +void qurt_pipe_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_receive + Reads a data item from the specified pipe. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + Integer containing the 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_receive(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_try_send + Writes a data item to the specified pipe (without suspending the thread if the pipe is full).\n + + If a thread writes to a full pipe, the operation returns immediately with success set to -1. + Otherwise, success is always set to 0 to indicate a successful write operation. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + 0 -- Success. \n + -1 -- Failure (pipe full). + + @dependencies + None. +*/ +int qurt_pipe_try_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_try_receive + Reads a data item from the specified pipe (without suspending the thread if the pipe is + empty).\n + If a thread reads from an empty pipe, the operation returns immediately with success set + to -1. Otherwise, success is always set to 0 to indicate a successful read operation.\n + + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[out] success Pointer to the operation status result. + + @return + Integer containing a 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_try_receive(qurt_pipe_t *pipe, int *success); + +/**@ingroup func_qurt_pipe_receive_cancellable + Reads a data item from the specified pipe (with suspend), cancellable. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + The operation is cancelled if the user process of the calling thread is killed, + or if the calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] result Pointer to the integer containing the 64-bit data item from pipe. + + @return + #QURT_EOK -- Receive completed. \n + #QURT_ECANCEL -- Receive canceled. \n + #QURT_EDESTROY -- Receive destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_receive_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t *result); + +/**@ingroup func_qurt_pipe_send_cancellable + @xreflabel{hdr:qurt_pipe_send_cancellable} + Writes a data item to the specified pipe (with suspend), cancellable. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + The operation is canceled if the user process of the calling thread is killed, or if the + calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] data Data item to write. + + @return + #QURT_EOK -- Send completed. \n + #QURT_ECANCEL -- Send canceled. \n + #QURT_EDESTROY -- Send destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_send_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_is_empty + Returns a value indicating whether the specified pipe contains any data. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + 1 -- Pipe contains no data. \n + 0 -- Pipe contains data. + + @dependencies + None. +*/ +int qurt_pipe_is_empty(qurt_pipe_t *pipe); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIPE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmem_manager.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmem_manager.h new file mode 100755 index 0000000000000..8c8da985228b9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmem_manager.h @@ -0,0 +1,82 @@ +#ifndef QURT_PMEM_MANAGER_H +#define QURT_PMEM_MANAGER_H +/** + @file qurt_pmem_manager.h + Prototypes of kernel physical memory manager APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* physical memory API return error code */ +#define QURT_PMEM_SUCCESS 0 +#define QURT_PMEM_NO_PRIV 1 +#define QURT_PMEM_RETRY 2 +#define QURT_PMEM_OVERLAP 3 +#define QURT_PMEM_NOT_EXIST 4 +#define QURT_PMEM_INIT_FAILURE 5 +#define QURT_PMEM_OUTSTANDING_MAPPING 6 +#define QURT_PMEM_GENERIC_FAILURE 7 +#define QURT_PMEM_ENTRY_FOUND 8 +#define QURT_PMEM_REACH_END 9 +#define QURT_PMEM_UNCLAIMED 10 +#define QURT_PMEM_ALREADY_CLAIMED 11 + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_pmem_acquire + Acquire the ownership of a specific physical memory region. + + @note1hang The ownership will be the caller + + @param[in] ppage Starting physical page number + @param[in] pnum Number of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_OVERLAP -- The whole or part of the range has been owned \n + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. +*/ +int qurt_pmem_acquire(unsigned int ppage, unsigned int pnum); + +/**@ingroup func_qurt_pmem_release + Release the ownership of a specific physical memory region. + + @param[in] ppage The start of physical page number + @param[in] pnum The numbers of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_NOT_EXIST -- The physical memory range is not usable. \n + #QURT_PMEM_OUTSTANDING_MAPPING -- There is outstanding mapping in this range + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. + */ +int qurt_pmem_release(unsigned int ppage, unsigned int pnum); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMEM_MANAGER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmu.h new file mode 100755 index 0000000000000..73ea8eba04abf --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_pmu.h @@ -0,0 +1,121 @@ +#ifndef QURT_PMU_H +#define QURT_PMU_H +/** + @file qurt_pmu.h + Prototypes of pipe interface API. + A pipe or message queue blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_pmu_set + Sets the value of the specified PMU register. + + @note1hang Setting PMUEVTCFG automatically clears the PMU registers PMUCNT0 + through PMUCNT3. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @param[in] reg_value Register value. + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_set (int reg_id, unsigned int reg_value); + +/**@ingroup func_qurt_pmu_get + Gets the PMU register.\n + Returns the current value of the specified PMU register. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @return + Integer -- Current value of the specified PMU register. + + @dependencies + None. + */ +unsigned int qurt_pmu_get (int reg_id); + +/**@ingroup func_qurt_pmu_enable + Enables or disables the Hexagon processor PMU. + Profiling is disabled by default. + + @note1hang Enabling profiling does not automatically reset the count registers -- this must + be done explicitly before starting event counting. + + @param[in] enable Performance monitor. Values: \n + - 0 -- Disable performance monitor \n + - 1 -- Enable performance monitor @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_enable (int enable); + +/**@ingroup func_qurt_pmu_get_pmucnt + Reads PMU counters in a single trap. + + @param[out] buf Pointer to a buffer to save values read from PMU counters. + buffer size should be at least 32 bytes to read all eight PMU counters. + + @return + #QURT_EOK -- Successful read.\n + #QURT_EFATAL -- Failure. + + @dependencies + None. + */ +int qurt_pmu_get_pmucnt (void * buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMU_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_power.h new file mode 100755 index 0000000000000..2ee4d29a73976 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_power.h @@ -0,0 +1,140 @@ +#ifndef QURT_POWER_H +#define QURT_POWER_H +/** + @file qurt_power.h + @brief Prototypes of power API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/*============================================================================= + + EDIT HISTORY FOR MODULE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + +when who what, where, why +-------- --- ------------------------------------------------------------ +03/03/11 op Add header file +12/12/12 cm (Tech Pubs) Edited/added Doxygen comments and markup. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +/**@ingroup func_qurt_power_shutdown_fail_exit + Returns from Power Collapse mode when power collapse cannot proceed. + + This function unmasks the global interrupt. This operation is used only when the thread is + recovering from a failed power collapse operation (Section @xref{sec:powerShutdownEnter}). + + @return + #QURT_EOK -- Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_fail_exit qurt_power_exit + +/**@ingroup func_qurt_power_shutdown_exit + Undoes state changes made preparing for power collapse.\n + This function unmasks the global interrupts. + + @return + #QURT_EOK --Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_exit qurt_power_exit +/**@endcond */ + +/**@ingroup func_qurt_system_ipend_get + Gets the IPEND register.\n + + @note1hang Returns the current value of the Hexagon processor IPEND register. The return value + is a mask value that identifies the individual interrupts that are pending. \n + + @note1hang The bit order of the mask value is identical to the order defined for the IPEND register. A + mask bit value of 1 indicates that the corresponding interrupt is pending, and 0 indicates that the + corresponding interrupt is not pending. \n + + @return + Return the IPEND register value. + + @dependencies + None. + */ +unsigned int qurt_system_ipend_get (void); + + +/**@ingroup func_qurt_system_vid_get + Gets the VID register. \n + + @note1hang Returns the current value of the Hexagon processor VID register. The return value is + the vector number of a second-level interrupt that has been accepted by the Hexagon + processor core.\n + + @return + Return the VID register value that is the L2 VIC interrupt number accepted by the processor. + Valid range is 0 to 1023. + + @dependencies + None. + */ +unsigned int qurt_system_vid_get(void); + +/**@ingroup func_qurt_power_shutdown_get_pcycles + Gets the number of power collapses and processor cycles for entering and exiting most recent + power collapse. + + @note1hang If no power collapse has occured yet, processor cycle numbers are zero. + + @param[out] enter_pcycles Number of processor cycles for entering most + recent power collapse. + @param[out] exit_pcycles Number of processor cycles for exiting most + recent power collapse. + @return + Zero -- No power collapses have occurred. \n + Nonzero -- Number of power collapses that have occurred since + the processor was reset. + + @dependencies + None. + */ +int qurt_power_shutdown_get_pcycles( unsigned long long *enter_pcycles, unsigned long long *exit_pcycles ); + +/**@ingroup func_qurt_system_tcm_set_size + Set size of TCM to save during full power collapse. + + @note1hang The size aligns to 32 bytes. If size passed is greater than the maximum size defined in + XML, the size is truncated to the size defined in XML. + + @param[in] new_size Size of TCM to save. + + @return + Zero -- Size successfully set \n + -1 -- Size of 0 passed + + @dependencies + None. + */ +int qurt_system_tcm_set_size(unsigned int new_size); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_POWER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_printf.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_printf.h new file mode 100755 index 0000000000000..a775d8a815918 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_printf.h @@ -0,0 +1,44 @@ +#ifndef QURT_PRINTF_H +#define QURT_PRINTF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file qurt_printf.h + Prototypes of printf API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup chapter_function_tracing +@{ */ + +int qurt_printf(const char* format, ...); + +int qurt_vprintf(const char* format, va_list args); + +/** @} */ /* end_addtogroup chapter_function_tracing */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PRINTF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_process.h new file mode 100755 index 0000000000000..0df9ddc2d4a70 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_process.h @@ -0,0 +1,995 @@ +#ifndef QURT_PROCESS_H +#define QURT_PROCESS_H +/** + @file qurt_process.h + @brief Prototypes of QuRT process control APIs. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2009-2013, 2021-2023 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_callback.h" +#include "qurt_consts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup process_types +@{ */ +#define QURT_PROCESS_ATTR_NAME_MAXLEN QURT_MAX_NAME_LEN /**< Maximum length of the process name. */ +#define QURT_PROCESS_ATTR_BIN_PATH_MAXLEN 128 /**< Maximum length of the path of binary/ELF for this process. */ +#define QURT_PROCESS_ATTR_CAP_MAXLEN 128 /**< Maximum length for a resource name. */ + +/** QuRT process capability wildcard strings */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_ALL "ALLOW_ALL" /**< Capability wild-card for full access */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_NONE "ALLOW_NONE" /**< Capability wild-card for no access */ + +/** QuRT process capability states */ +#define QURT_PROCESS_ATTR_CAP_ENABLED 0x1 /**< Capability enabled*/ +#define QURT_PROCESS_ATTR_CAP_DISABLED 0x0 /**< Capability disabled*/ + +/* QuRT process thread attributes. */ +#define QURT_PROCESS_DEFAULT_CEILING_PRIO 0 /**< Default ceiling priority of the threads in the new process. */ +#define QURT_PROCESS_DEFAULT_MAX_THREADS -1 /**< Default number of threads in the new process. + -1 indicates that the limit is set to the maximum supported by the system. */ + +/* QuRT process flags. */ +#define QURT_PROCESS_SUSPEND_ON_STARTUP (1U) /**< Suspend the new processes just before calling main(). */ +#define QURT_PROCESS_NON_SYSTEM_CRITICAL (1u << 1) /**< Starts the new process as non system-critical. */ +#define QURT_PROCESS_ISLAND_RESIDENT (1u << 2) /**< Process is island resident. */ +#define QURT_PROCESS_RESTARTABLE (1u << 3) /**< Indicates that the process is restartable */ +#define QURT_PROCESS_UNTRUSTED (1u << 7) /**< Starts the new process as unsigned process. */ + +/* QuRT process debugging session status.*/ +#define QURT_DEBUG_NOT_START 0 /**< Debug is not started. */ +#define QURT_DEBUG_START 1 /**< Debug has started. */ + +/** Process Suspend Options */ +#define QURT_PROCESS_SUSPEND_DEFAULT 0 + +/** Process Resume Options */ +#define QURT_PROCESS_RESUME_DEFAULT 0 + + +/* QuRT process types. */ +typedef enum { + QURT_PROCESS_TYPE_RESERVED, /**< Process type is reserved. \n */ + QURT_PROCESS_TYPE_KERNEL, /**< Kernel process. \n*/ + QURT_PROCESS_TYPE_SRM, /**< SRM process. \n*/ + QURT_PROCESS_TYPE_SECURE, /**< Secure process. \n*/ + QURT_PROCESS_TYPE_ROOT, /**< Root process. \n*/ + QURT_PROCESS_TYPE_USER, /**< User process. */ +}qurt_process_type_t; + +/** QuRT process callback types. */ +typedef enum { + QURT_PROCESS_DUMP_CB_ROOT, /**< Register the callback that executes in the + root process context. \n */ + QURT_PROCESS_DUMP_CB_ERROR, /**< Register the user process callback that is + called after threads in the process are frozen. \n */ + QURT_PROCESS_DUMP_CB_PRESTM, /**< Register the user process callback that is + called before threads in the process are frozen. \n*/ + QURT_PROCESS_DUMP_CB_MAX /**< Reserved for error checking. */ +}qurt_process_dump_cb_type_t; + +/** QuRT process dump attributes. */ +typedef struct _qurt_pd_dump_attr{ + /** @cond */ + unsigned int enabled; /**< Process dump is enabled. */ + const char *path; /**< Process dump path. */ + unsigned int path_len; /**< Length of process dump path. */ + /** @endcond */ +}qurt_pd_dump_attr_t; + +/** QuRT process capability resource type */ +enum qurt_process_cap_type_t { + QURT_PROCESS_CAP_TYPE_NUM_ENTRIES=0, /**< Number of entries in the capability structure*/ + QURT_PROCESS_CAP_TYPE_DRIVER=1, /**< Driver resource */ + QURT_PROCESS_CAP_TYPE_MAX /**< Maximum identifier */ +}; + +/** QuRT process capability structure */ +typedef struct _qurt_capability { + enum qurt_process_cap_type_t type; /**< Resource type */ + char name[QURT_PROCESS_ATTR_CAP_MAXLEN]; /**< Resource name*/ + unsigned long long cap; /**< Capabilities allowed for this resource */ +}qurt_capability_t; + +/** QuRT process attributes. */ +typedef struct _qurt_process_attr { + /** @cond */ + char name[QURT_PROCESS_ATTR_NAME_MAXLEN]; /**< Name of the new process. */ + char path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the binary for the new process. */ + char dtb_path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the DTB ELF for the new process. */ + int flags; /**< Flags as indicated by QuRT process flags. */ + unsigned int sw_id; /**< Software ID of the process be load. */ + unsigned sid; /**< Stream ID of the process being spawned. */ + unsigned max_threads; /**< Maximum number of threads that the new process can create. */ + unsigned short ceiling_prio; /**< Maximum priority at which threads can be + created by new process. */ + qurt_process_type_t type; /**< Process type as indicated by + #qurt_process_type_t. */ + qurt_pd_dump_attr_t dump_attr; /**< Process dump attributes for the new process + as indicated by #qurt_pd_dump_attr_t. */ + qurt_capability_t *capabilities; /**< Pointer to array of structure of type + qurt_capability_t */ + /** @endcond */ +} qurt_process_attr_t; + +/** @} */ /* end_addtogroup process_types */ + +/*============================================================================= +FUNCTIONS +=============================================================================*/ + /** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_create + Creates a process with the specified attributes, and starts the process. + + The process executes the code in the specified executable ELF file. + + @datatypes + #qurt_process_attr_t + + @param[out] attr Accepts an initialized process attribute structure, which specifies + the attributes of the created process. + + @return + Postive return value Indicates Process ID. + Negative return value Indicates any of follwoing error, + #-QURT_EPRIVILEGE -- Caller does not have privilege for this operation \n + #-QURT_EMEM -- Not enough memory to perform the operation \n + #-QURT_EFAILED -- Operation failed \n + #-QURT_ENOTALLOWED -- Operation not allowed \n + #-QURT_ENOREGISTERED -- Not registered \n + #-QURT_ENORESOURCE -- Resource exhaustion \n + #-QURT_EINVALID -- Invalid argument value + #QURT_EFATAL -- attr is NULL + + @dependencies + None. +*/ +int qurt_process_create (qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_get_id + Returns the process identifier for the current thread. + + @return + None. + + @dependencies + Process identifier for the current thread. +*/ +int qurt_process_get_id (void); +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_get_uid + Returns the user identifier for the current thread. + + @return + None. + + @dependencies + User identifier for the current thread. +*/ +int qurt_process_get_uid (void); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_init + Initializes the structure that sets the process attributes when a thread is created. + + After an attribute structure is initialized, the individual attributes in the structure can + be explicitly set using the process attribute operations. + + Table @xref{tbl:processAttrDefaults} lists the default attribute values set by the initialize + operation. + + @inputov{table_process_attribute_defaults} + + @datatypes + #qurt_process_attr_t + + @param[out] attr Pointer to the structure to initialize. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_process_attr_init (qurt_process_attr_t *attr) +{ + attr->name[0] = '\0'; + attr->path[0] = '\0'; + attr->dtb_path[0] = '\0'; + attr->flags = 0; + attr->sw_id = 0; + attr->sid = 0; + attr->max_threads = (unsigned)QURT_PROCESS_DEFAULT_MAX_THREADS; + attr->ceiling_prio = QURT_PROCESS_DEFAULT_CEILING_PRIO; + attr->type = QURT_PROCESS_TYPE_RESERVED; + attr->dump_attr.enabled = 0; + attr->dump_attr.path = NULL; + attr->dump_attr.path_len = 0; + attr->capabilities = NULL; +} + +/**@ingroup func_qurt_process_attr_set_executable + Sets the process name in the specified process attribute structure. + + Process names identify process objects that are already + loaded in memory as part of the QuRT system. + + @note1hang Process objects are incorporated into the QuRT system at build time. + + @note1hang Maximum length of name string is limited to QURT_PROCESS_ATTR_NAME_MAXLEN - 1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] name Pointer to the process name. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_executable (qurt_process_attr_t *attr, const char *name); + +/**@ingroup func_qurt_process_attr_set_binary_path + Sets the binary path for the process loading in the specified process attribute structure. + + Path specifies the binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_binary_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_dtb_path + Sets the DTB binary path for the process loading in the specified process attribute structure. + + Path specifies the DTB binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_dtb_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_flags +Sets the process properties in the specified process attribute structure. +Process properties are represented as defined symbols that map into bits +0 through 31 of the 32-bit flag value. Multiple properties are specified by OR'ing +together the individual property symbols. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] flags QURT_PROCESS_NON_SYSTEM_CRITICAL Process is considered as non system-critical. + This attribute will be used by error services, + to decide whether to kill user pd or whole subsystem. + QURT_PROCESS_ISLAND_RESIDENT Process will be marked as island resident. + QURT_PROCESS_RESTARTABLE Process will be marked as restartable. + QURT_PROCESS_UNTRUSTED Process will be marked as unsigned process. +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_flags (qurt_process_attr_t *attr, int flags) +{ + attr->flags = flags; +} +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_sid +Sets the process streamID in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sid streamID to set for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sid (qurt_process_attr_t *attr, unsigned sid) +{ + attr->sid = sid; +} +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_set_max_threads +Sets the maximum number of threads allowed in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] max_threads Maximum number of threads allowed for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_max_threads (qurt_process_attr_t *attr, unsigned max_threads) +{ + attr->max_threads = max_threads; +} + +/**@ingroup func_qurt_process_attr_set_sw_id +Sets the software ID of the process to load in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sw_id Software ID of the process, used in authentication. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sw_id(qurt_process_attr_t *attr, unsigned int sw_id) +{ + attr->sw_id = sw_id; +} + +/**@ingroup func_qurt_process_attr_set_ceiling_prio +Sets the highest thread priority allowed in the specified process attribute structure. +Refer qurt_thread.h for priority ranges. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] prio Priority. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_ceiling_prio (qurt_process_attr_t *attr, unsigned short prio) +{ + attr->ceiling_prio = prio; +} +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_dump_status +Sets the process domain dump-enabled field in the process domain dump attributes. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] enabled 1 -- Process domain dump is collected \n + 0 -- Process domain dump is not collected + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_status(qurt_process_attr_t *attr, unsigned int enabled) +{ + attr->dump_attr.enabled = enabled; +} + +/**@ingroup func_qurt_process_attr_set_dump_path +Sets the process domain dump path and type. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] path Path where the process domain dumps must be saved. +@param[in] path_len Length of the path string. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_path(qurt_process_attr_t *attr, const char *path, int path_len) +{ + attr->dump_attr.path = path; + attr->dump_attr.path_len = (unsigned int)path_len; +} + +/**@ingroup func_qurt_process_attr_set_capabilities +Sets list of capabilities available to this process. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] capabilities Pointer to array of structures of type qurt_capability_t defining + resources and capabilites + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_capabilities(qurt_process_attr_t *attr, qurt_capability_t *capabilities) +{ + attr->capabilities = capabilities; +} + +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_cmdline_get +Gets the command line string associated with the current process. +The Hexagon simulator command line arguments are retrieved using +this function as long as the call is made +in the process of the QuRT installation, and with the +requirement that the program runs in a simulation environment. + +If the function modifies the provided buffer, it zero-terminates +the string. It is possible that the function does not modify the +provided buffer, so the caller must set buf[0] to a NULL +byte before making the call. A truncated command line is returned when +the command line is longer than the provided buffer. + +@param[in] buf Pointer to a character buffer that must be filled in. +@param[in] buf_siz Size (in bytes) of the buffer pointed to by the buf argument. + +@return +None. + +@dependencies +None. +*/ +void qurt_process_cmdline_get(char *buf, unsigned buf_siz); + +/**@ingroup func_qurt_process_get_thread_count +Gets the number of threads present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of threads in the process indicated by PID, if positive value is obtained +Negative error code if failed include: + QURT_EFATAL - Invalid PID + -QURT_ENOTALLOWED - Current process doesnt have access to target process indicated by PID + +@dependencies +None. +*/ +int qurt_process_get_thread_count(unsigned int pid); + +/**@ingroup func_qurt_process_get_thread_ids +Gets the thread IDs for a process indicated by PID. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a user passed buffer that must be filled in with thread IDs. +@param[in] thread_num Number of thread IDs requested. + +@return +#QURT_EOK - Success +#QURT_EFATAL - Failed, ptr is NULL + +@dependencies +None. + */ +int qurt_process_get_thread_ids(unsigned int pid, unsigned int *ptr, unsigned thread_num); +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_dump_get_mem_mappings_count +Gets the number of mappings present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of mappings for the process indicated by the PID. + +@dependencies +None. +*/ +int qurt_process_dump_get_mem_mappings_count(unsigned int pid); + +/**@ingroup func_qurt_process_dump_get_mappings +Gets the mappings for a specified PID. + +@note1hang This API skips device type mappings or mappings created by setting the #QURT_PERM_NODUMP attribute. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a buffer that must be filled in with mappings. +@param[in] count Count of mappings requested. + +@return +Number of mappings filled in the buffer passed by the user. + +@dependencies +None. +*/ +int qurt_process_dump_get_mappings(unsigned int pid, unsigned int *ptr, unsigned count); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_get +Gets the attributes of the process with which it was created. + +@datatypes +#qurt_process_attr_t + +@param[in] pid PID of the process for which the information is required. +@param[in,out] attr Pointer to the user allocated attribute structure. + +@return +#QURT_EOK - Success +#QURT_INVALID - Invalid PID +#QURT_EFATAL - attr is NULL + +@dependencies +None. +*/ +int qurt_process_attr_get(unsigned int pid, qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_dump_register_cb +Registers the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information. +@param[in] type Callback type; these callbacks are called in the context of the user process domain: \n + #QURT_PROCESS_DUMP_CB_PRESTM -- Before threads of the exiting process are frozen. \n + #QURT_PROCESS_DUMP_CB_ERROR -- After threads are frozen and captured. \n + #QURT_PROCESS_DUMP_CB_ROOT -- After threads are frozen and captured, and CB_ERROR type of callbacks + are called. +@param[in] priority Priority. + +@return +#QURT_EOK -- Success \n +Other values -- Failure + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_register_cb(qurt_cb_data_t *cb_data, qurt_process_dump_cb_type_t type, unsigned short priority); + +/**@ingroup func_qurt_process_dump_deregister_cb +Deregisters the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information to deregister. +@param[in] type Callback type. + +@return +#QURT_EOK -- Success.\n +Other values -- Failure. + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_deregister_cb(qurt_cb_data_t *cb_data,qurt_process_dump_cb_type_t type); + +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_set_rtld_debug +Sets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in] address rtld_debug address. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_set_rtld_debug(unsigned int pid,unsigned int address); + +/**@ingroup func_qurt_process_get_rtld_debug +Gets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in,out] address Pointer to the user passed address in which the rtld_debug address must be returned. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_get_rtld_debug(unsigned int pid,unsigned int *address); +/** @endcond */ +/**@ingroup func_qurt_process_exit +Exits the current user process with an exit code. + +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exit(int exitcode); + +/**@ingroup func_qurt_process_kill +Kills the process represented by the PID with the exit code. + +@param[in] pid PID of the process to kill. +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_kill(int pid, int exitcode); + + +/**@ingroup func_qurt_debugger_register_process +Registers the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. +@param[in] adr Address. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_register_process(int pid, unsigned int adr); + + +/**@ingroup func_qurt_debugger_deregister_process +Deregister the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_deregister_process(int pid); + +/**@ingroup func_qurt_process_exec_callback +Executes callbacks in the user process as indicated by the client_handle argument. + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] callback_fn Callback function to execute. +@param[in] stack_base Stack address to use. +@param[in] stack_size Stack size. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exec_callback(int client_handle, + unsigned callback_fn, + unsigned stack_base, + unsigned stack_size); + +/**@ingroup func_qurt_process_get_pid +Gets the process ID of the process that the client_handle argument represents. + +@note1hang This API is not supported for unsigned PD, For unsigned PD use qurt_process_get_id() + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] pid Pointer to the address to store the PID. + +@return +#QURT_EOK -- Success +#QURT_EFATAL -- pid pointer passed as NULL + +@dependencies +None. +*/ +int qurt_process_get_pid(int client_handle, int * pid); + +/**@ingroup func_qurt_process_get_dm_status +Gets the debugging session status on the process represented by the pid argument. + +@param[in] pid Process ID +@param[in,out] status Address to store the status: \n + #QURT_DEBUG_NOT_START \n + #QURT_DEBUG_START + +@return +#QURT_EOK - Success \n +#QURT_EINVALID - Error + +@dependencies +None. +*/ +int qurt_process_get_dm_status( unsigned int pid, unsigned int *status); + + +/**@ingroup func_qurt_process_suspend_threads + Suspends user threads in a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in GuestOS/root process. + After the user threads in the target user process are suspended, they cannot be scheduled to run by the kernel + until they resume later. + + This function has one optional argument with one default option. + #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + This function call is a synchronous call, the function returns after the relevant threads are + completely suspended. + + If some user threads in the target user process are set as non-suspendable, this function call does + not suspend these threads. + + If the target user process is already suspended, this function call returns success as the + confirmation on the user process suspending. + + QuRT debugger monitor threads in the target user process are non-suspendable, this function call does + not suspend the threads. + + If the target user process is a secure user process, or a CPZ process, this function call returns error + without suspending the target user process. + + If a user thread in the target user process runs in the guest OS/root process via a QDI call, this function call + does not suspend the thread in the guest OS, but instead marks the thread as pending-suspend. The thread is suspended + when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success while the user thread can be running in GuestOS, and is suspended + when exiting the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Dfault option #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid process_id input \n + #QURT_ENOTALLOWED -- Failure because the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_suspend_threads (unsigned int process_id, unsigned int option); + + +/**@ingroup func_qurt_process_resume_threads + Resumes a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in the guest OS/root process. + After the user threads in the target user process resume, the kernel scheduler + can schedule the user threads to run based on their thread priorities. + + This function has an optional argument, #QURT_PROCESS_RESUME_DEFAULT, which + resumes user threads in the target user process. + + This is an asynchronous function, it returns after the kernel moves the user thread from + suspended state to runnable state. The threads are scheduled to run based on their thread priorities. + + This function call does not resume threads in the target user process that have been set as non-resumable. + + If the target user process have already resumed, this function call confirms that the user process resumes + by returning success. + + If the target user process is a secure user process or a CPZ process, this function call returns an error without + resuming operation. + + If user threads in the target user process run in the guest OS/root process via QDI call, this function + call clears the mark of suspend-pending on these threads, so that the threads are be suspended when it exits + the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Default option #QURT_PROCESS_RESUME_DEFAULT resumes user threads in the target user process. + + @return + #QURT_EOK -- Success + #QURT_EINVALID -- Failure because of invalid process_id input. + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_resume_threads (unsigned int process_id, unsigned int option); + +/**@ingroup func_qurt_process_vtcm_window_set + Set a VTCM access window for a process. + The caller thread needs to be in SRM process. + + This is an synchronous function, it ensures all running threads of the process have the requested + window in effect.The requested view for all non-running thread will take in effect when they get + scheduled. + + @param[in] pid Process identifier. + @param[in] enable QURT_VTCM_WINDOW_ENABLE enforces VTCM access window defined by high and low offset. + QURT_VTCM_WINDOW_DISABLE high and low offset is ignored and VTCM access is fully + disabled for the process. + @param[in] high_offset Specifies the high window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT restore high offset to reset value. + @param[in] low_offset Specifies the low window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT restore low offset to reset value. + + @note1hang + when high_offset is set to QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT and low offset is set as + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT full VTCM range is accessible. Access to VTCM is controlled + via MMU mapping for the process. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_set(int pid, unsigned int enable, unsigned int high_offset, unsigned int low_offset); + +/**@ingroup func_qurt_process_vtcm_window_get + Get the VTCM window for a process. + The caller thread needs to be in SRM process. + + + @param[in] pid Process identifier. + @param[out] enable address to store enable status if set + @param[out] high_offset address to return high window offset, in 4K increments, from the base address of the VTCM + @param[out] low_offset address to return low window offset, in 4K increments, from the base address of the VTCM. + + @note1hang + User must first check the value of enable returned before checking high and low offset. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_get(int pid, unsigned int *enable, unsigned int *high_offset, unsigned int *low_offset); + +/**@ingroup func_qurt_process_set_group_config + Enable thread groups in the process with the ceiling priorities setup + + @param[in] process_id Process identifier. + @param[in] group_bitmask 64-bit mask of active thread groups + @param[in] ceiling_priorities array of ceiling priorities for thread group + + @note1hang + This API can only be called by root PD and can only be called once for each process, otherwise it will be + rejected. Group 0 must be enabled in group_bitmask, otherwise QuRT will return error. After this API, all + exisiting threads will be moved to group 0, and if there is any thread's priority higher than ceiling + priority of group 0, it will be lowered to the ceiling value. + Examples 1: + group_bitmask = 0xD7; //'b11010111 + ceiling_priorities[] = {100, 128, 200, 0, 196, 0, 240, 20}; // 0 - does not care + Exmaples 2: + group_mask = 0x5; //'b101 + ceiling_priorities[] = {240, 0, 20}; // 0 - does not care + + + @return + #QURT_EOK -- Success. + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_ENOTALLOWED -- The group has been configured already. + + @dependencies + None. + */ +int qurt_process_set_group_config(unsigned int process_id, unsigned long long group_bitmask, + unsigned char *ceiling_priorities); + + +/**@ingroup func_qurt_process_stid_set + Set the specified stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[in] stid stid to be set + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) if stid needs to set at a process level. + All threads within a process that has default stid (QURT_STID_DEFAULT) will inherit the stid set for a process. + When a non-default group_id is specified, the stid is set only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_set(unsigned int pid, unsigned int group_id , unsigned int stid); + +/**@ingroup func_qurt_process_stid_get + Get the stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[out] Pointer to a variable to return stid + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) to return process-level stid. + When a non-default group_id is specified, the stid is returned only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_get(unsigned int pid, unsigned int group_id , unsigned int *stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_profile.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_profile.h new file mode 100755 index 0000000000000..2a50c461440f6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_profile.h @@ -0,0 +1,98 @@ +#ifndef QURT_PROFILE_H +#define QURT_PROFILE_H +/** + @file qurt_profile.h + QuRT profiling support. + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup profiling_macros +@{ */ +#define QURT_PROFILE_DISABLE 0 /**< Disable profiling. */ +#define QURT_PROFILE_ENABLE 1 /**< Enable profiling. */ + +typedef unsigned int qurt_profile_param_t; + +#define QURT_PROFILE_PARAM_THREAD_READY_TIME 0U /**< Profile thread ready time. */ + +/** @} */ /* end_addtogroup profiling_macros */ + +/** @addtogroup profiling_types + @{ */ +/** Profiling results. */ +typedef union +{ + /** Result associated with #QURT_PROFILE_PARAM_THREAD_READY_TIME. */ + struct + { + unsigned int ticks; /**< Cumulative ticks the thread was ready. */ + } thread_ready_time; + +} qurt_profile_result_t; +/** @} */ /* end_addtogroup profiling_types */ + +/**@ingroup func_qurt_profile_enable2 + * Starts profiling of a specific parameter on a specific thread (as applicable). + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of the thread (if applicable) for which the specified + * paramter must be profiled. + * @param[in] enable #QURT_PROFILE_DISABLE -- disable \n #QURT_PROFILE_ENABLE -- + * enable + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EALREADY -- Measurement already in progress or already stopped \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_enable2 ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + int enable +); + +/**@ingroup func_qurt_profile_get + * Gets the value of the profiling parameter that was previously enabled. + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of thread (if applicable) for which the specified + * profiling paramter must be retrieved. + * @param [out] result Profiling result associated with the parameter for the specified + * thread (if applicable). + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EFAILED -- Operation failed; profiling was not enabled \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_get ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + qurt_profile_result_t * result +); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ptrace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ptrace.h new file mode 100755 index 0000000000000..622304dd92865 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_ptrace.h @@ -0,0 +1,37 @@ +/*============================================================================= + + qurt_ptrace.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SYS_PTRACE_H__ +#define __SYS_PTRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum __ptrace_request +{ + /** + Indicates that the process making this request is requesting to be traced. + */ + PTRACE_TRACEME = 0, + PTRACE_EXT_IS_DEBUG_PERMITTED = 500 +}; + +long ptrace(enum __ptrace_request request, unsigned int pid, void*addr, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_PTRACE_H__ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi.h new file mode 100755 index 0000000000000..705408e5cfc6f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi.h @@ -0,0 +1,185 @@ +#ifndef QDI_H +#define QDI_H + +/** + @file qurt_qdi.h + @brief Prototypes of QuRT Driver Invocation API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_qdi_open + Opens the specified driver for subsequent operations. + qurt_qdi_open() is the primary mechanism by which a driver user can + obtain a QDI handle. The user provides the name of the driver to the + qurt_qdi_open call, and gets back a handle referencing + the named driver. \n + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_open function prototype is not actually defined as a varargs. + + + @param[in] p Driver name. + @param[in] ... Up to nine additional device-specific arguments can be passed as parameters, + and should follow the POSIX open() convention. \n + - flags -- Optional second parameter (POSIX flags), the handle + access requested (read-only, write-only, or read-write, + for instance) and other flags such as whether the call + should create a new device or only open an existing + device. \n + - mode -- Optional third parameter (POSIX mode); permissions to + configure when a new device is created. @tablebulletend + + @return + Negative value -- Error. \n + Non-negative value -- Success, this result value serves as a handle to the + opened driver. + @dependencies + None. + */ +// int qurt_qdi_open(); +#define qurt_qdi_open(p,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN,(p),##__VA_ARGS__) + +#define qurt_qdi_open_dt(p,q,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN_FROM_DT,(p),(q),##__VA_ARGS__) + +/**@ingroup func_qurt_qdi_handle_invoke + Performs a generic driver operation, which (depending on the specified operation) can be + either be one of the predefined operations listed in @xhyperref{tbl:functionMapping,QDI function mapping} + or a driver-specific operation. + The user provides a QDI handle and an integer + method number, along with 0 to 8 optional 32-bit arguments. + The device driver invocation function is invoked with the + same method number and 0 to 8 optional arguments. The + return value from the invocation function is passed back to + the user as the return value of qurt_qdi_handle_invoke. + + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_handle_invoke() function prototype is not actually defined as a + varargs function (and would break if it were defined this way). + + @param[in] h Driver handle. + @param[in] m Integer number for the operation to perform. + @param[in] ... Up to eight optional arguments can be passed to the device driver as operation-specific parameters: \n + arg1 -- First parameter \n + arg2 -- Second parameter \n + arg3 -- Third parameter \n + arg4 -- Fourth parameter \n + arg5 -- Fifth parameter \n + arg6 -- Sixth parameter \n + arg7 -- Seventh parameter \n + arg8 -- Eighth parameter + + @return + Integer value defined by the device driver. \n + -1 -- Error. + + @dependencies + None. + */ +// int qurt_qdi_handle_invoke(); +#define qurt_qdi_handle_invoke(h,m,...) \ + _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__) +#define _QDMHI3(a,b,c) qurt_qdi_qhi3(0,b,c) +#define _QDMHI4(a,b,c,d) qurt_qdi_qhi4(0,b,c,(int)(d)) +#define _QDMHI5(a,b,c,d,e) qurt_qdi_qhi5(0,b,c,(int)(d),(int)(e)) +#define _QDMHI6(a,b,c,d,e,f) qurt_qdi_qhi6(0,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMHI7(a,b,c,d,e,f,g) qurt_qdi_qhi7(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMHI8(a,b,c,d,e,f,g,h) qurt_qdi_qhi8(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMHI9(a,b,c,d,e,f,g,h,i) qurt_qdi_qhi9(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMHI10(a,b,c,d,e,f,g,h,i,j) qurt_qdi_qhi10(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMHI11(a,b,c,d,e,f,g,h,i,j,k) qurt_qdi_qhi11(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMHI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_qdi_qhi12(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) +int qurt_qdi_qhi3(int,int,int); +int qurt_qdi_qhi4(int,int,int,int); +int qurt_qdi_qhi5(int,int,int,int,int); +int qurt_qdi_qhi6(int,int,int,int,int,int); +int qurt_qdi_qhi7(int,int,int,int,int,int,int); +int qurt_qdi_qhi8(int,int,int,int,int,int,int,int); +int qurt_qdi_qhi9(int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi10(int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi11(int,int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi12(int,int,int,int,int,int,int,int,int,int,int,int); + +/**@ingroup func_qurt_qdi_write + Writes data to the specified driver. + A predefined invocation routine for drivers that + support a POSIX-like write functionality. + qqurt_qdi_write(handle, buf, len) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_WRITE, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data to write is stored. + @param[in] len Number of bytes of data to write. + + @return + Non-negative integer -- Number of bytes written. \n + Negative error code -- Write could not take place. + + @dependencies + None. + */ +int qurt_qdi_write(int handle, const void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_read + User-visible API to read data from a QDI handle. + A predefined invocation routine for drivers that + support a POSIX-like read functionality. + qurt_qdi_read(handle, buf, len) is equivalent to: + qurt_qdi_handle_invoke(handle, QDI_READ, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data read is stored. + @param[in] len Number of bytes of data to read. + + @return + Non-negative integer number -- Bytes read. \n + Negative error code -- Read could not take place. + + @dependencies + None. + */ +int qurt_qdi_read(int handle, void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_close + Closes the specified driver, releasing any resources associated with the open driver. + User-visible API to close a QDI handle. + + This API should be called when the user is done using a + QDI-based handle. When this function is called, the driver can release + any resources held and perform other necessary cleanup + operations. qurt_qdi_close(handle) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_CLOSE, handle) + + @param[in] handle Driver handle. + + @return + 0 -- Success.\n + Negative error code -- Failure. + + @dependencies + None. + */ +int qurt_qdi_close(int handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_constants.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_constants.h new file mode 100755 index 0000000000000..4866fada067f0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_constants.h @@ -0,0 +1,193 @@ +#ifndef QDI_CONSTANTS_H +#define QDI_CONSTANTS_H + +/** + @file qurt_qdi_constants.h + @brief Predefined invocation methods for drivers. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Method numbers used for QDI. +|| +|| Intended grouping of method numbers for QDI +|| including future usage: +|| +|| Method 0 should always be unused and not responded to by +|| any driver. +|| Methods 1 and 2 are reserved for name registration and +|| name lookup. +|| Methods 3 through 31 are reserved for POSIX-type operations +|| on open handles. +|| Methods 32 through 127 are reserved for the QDI infrastructure +|| and may be extended in the future to provide standard +|| driver debug services, management services, and system +|| notifications. +|| Methods 128 through 255 are reserved for the use of automatically +|| generated methods such as might be generated by an IDL (interface +|| definition language). The infrastructure may be extended to +|| perform services on these methods based on information provided +|| by the IDL, such as automatic buffer validation, etc. These +|| method numbers should not be used for any "ad hoc" methods. +|| Methods with number >= 256 are "private" method numbers that are +|| outside the scope of the QDI infrastructure. Drivers that want +|| to generate and consume their own "ad hoc" methods are free to +|| use these method numbers as they wish. The infrastructure does +|| not generate these method numbers or respond to them, but +|| passes them on unmolested. +|| +|| All driver implementations *should* return a value of +|| -1 when called with an unsupported method. The standard error +|| return value for POSIX APIs is -1, so we emulate that behavior +|| here. +*/ +/** @cond */ +#define QDI_UNUSED 0 +#define QDI_DEVNAME_REGISTER 1 +#define QDI_OPEN 2 +#define QDI_CLOSE 3 +#define QDI_READ 4 +#define QDI_WRITE 5 +#define QDI_IOCTL 6 +#define QDI_MMAP 7 +#define QDI_OS_FILEOPEN 8 +#define QDI_FLEN 9 +#define QDI_UNLINK 10 +#define QDI_FTELL 22 +#define QDI_SEEK 23 +#define QDI_FSTAT 24 + +#define QDI_FSNAME_REGISTER 150 +#define QDI_FS_OPEN 151 +#define QDI_MMAP2 153 +#define QDI_MPROTECT2 154 +#define QDI_MUNMAP2 155 + +#define QDI_CLIENT_HANDLE_OBJREF_GET 10 + +#define QDI_OS_PROCESS_LOAD 12 +#define QDI_OS_PROCESS_CHOOSE_ASID 13 + +#define QDI_OS_SET_GP 26 +#define QDI_CLIENT_HANDLE_CALLBACK 27 + +#define QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T 19 //reused +#define QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T 80 +#define QDI_CLIENT_HANDLE_HANDLE_RELEASE 81 +#define QDI_CLIENT_HANDLE_COPY_FROM_USER 82 +#define QDI_CLIENT_HANDLE_COPY_TO_USER 83 +#define QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE 86 +#define QDI_CLIENT_HANDLE_SAFE_CACHE_OPS 87 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK 41 +#define QDI_CLIENT_HLOSPOOL_INFO_GET 90 +#define QDI_CLIENT_HLOSPOOL2_INFO_GET 96 + +#define QDI_CLIENT_PID 44 +#define QDI_CLIENT_ASID QDI_CLIENT_PID + +#define QDI_OS_CLIENT_INFO_GET 48 + +#define QDI_OS_MEM_LOOKUP_PHYSADDR 57 + +#define QDI_OS_THREAD_ITERATOR_CREATE 68 +#define QDI_OS_THREAD_ITERATOR_NEXT 69 + +#define QDI_OS_SYSENV 78 + +#define QDI_REGION_USERMALLOC_INIT 180 // This method is for generic handle + + +#define QDI_CLIENT_HANDLE_USER_MALLOC 84 +#define QDI_CLIENT_HANDLE_USER_FREE 85 + +#define QDI_SIGNAL_GROUP_SIGNAL_CREATE 96 +#define QDI_SIGNAL_GROUP_WAIT 98 +#define QDI_SIGNAL_GROUP_POLL 99 +#define QDI_SIGNAL_SET 96 +#define QDI_SIGNAL_CLEAR 97 +#define QDI_SIGNAL_WAIT 98 +#define QDI_SIGNAL_POLL 99 + +#define QDI_OS_WAIT_FOR_MAIN_REAPER 104 + +#define QDI_CLIENT_HANDLE_REFPROXY_INSTALL 105 +#define QDI_CLIENT_HANDLE_REFPROXY_ADD 106 +#define QDI_CLIENT_HANDLE_REFPROXY_REMOVE 107 + +#define QDI_CLIENT_HANDLE_DETACH 116 + +#define QDI_OS_RESERVED1 139 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK2 142 + +#define QDI_DT_REGISTER 158 +#define QDI_OPEN_DEVICE 159 +#define QDI_OPEN_FROM_DT 160 + +#define QDI_PRIVATE 256 /* Method numbers beginning at 256 + are private method numbers, which + are device-specific and available + for use by device implementors. */ +/* +|| Permission bitmasks for use with qurt_qdi_lock_buffer(). +|| +|| Make sure these match with permission values from qurt_perm_t. +*/ +/** @endcond */ + +/** @addtogroup driver_support_constants +@{ */ +#define QDI_PERM_W 2 /**< Write access. */ +#define QDI_PERM_R 1 /**< Read access. */ +#define QDI_PERM_RW (QDI_PERM_R | QDI_PERM_W) /**< Read/write access. */ + +#define QDI_HANDLE_LOCAL_CLIENT 3 /**< Local client. */ +#define QDI_HANDLE_GENERIC 4 /**< Generic. */ + +#define QDI_REFCNT_BASE 0x510000 /**< */ +#define QDI_REFCNT_MAXED 0x51FFFD /**< */ +#define QDI_REFCNT_INIT 0x51FFFE /**< Driver object is temporary and is eventually deleted.*/ +#define QDI_REFCNT_PERM 0x51FFFF /**< Driver object is permanent and is never deleted. */ +/** @} */ /* end_addtogroup driver_support_constants */ + +/** @cond */ +/* +|| Flags used by process loaders. +*/ + +#define QDI_OS_PROCESS_FLAGS_ISLAND_RESIDENT 0x1 /* Set this flag to request the loaded process + to have island residency. */ +#define QDI_OS_PROCESS_FLAGS_ROOT_RESIDENT 0x2 /* Set this flag to request the loaded process + to have root residency, for example, DL Pager. */ +/* +|| Constants used for qurt_event register API, type field. +*/ + +#define QURT_PROCESS_EXIT 1 + +/* +|| Constants used by QDI extensions. +*/ + +#define QURT_QDI_SINGLETON_TYPE_TRUE 0 +#define QURT_QDI_SINGLETON_TYPE_FALSE 1 +#define QURT_QDI_SINGLETON_TYPE_PER_PROCESS 2 +/** @endcond */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QDI_CONSTANTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_driver.h new file mode 100755 index 0000000000000..e044e25f1bb72 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_driver.h @@ -0,0 +1,868 @@ +#ifndef QURT_QDI_DRIVER_H +#define QURT_QDI_DRIVER_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2018, 2019-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "stddef.h" +#include "qurt_qdi.h" +#include "qurt_types.h" +#include "qurt_callback.h" +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" +#include "qurt_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| This gives the canonical form for the arguments to a QDI +|| driver invocation function. The arguments are as follows: +|| +|| int client_handle (R0) QDI handle that represents the client +|| that made this QDI request. If the +|| client is remote, this is a +|| variable handle; if the client is local +|| (same thread and process), this is +|| set to QDI_HANDLE_LOCAL_CLIENT. +|| +|| qurt_qdi_obj_t *obj (R1) Points at the qdi_object_t structure +|| on which this QDI request is being made. +|| The qdi_object_t structure is usually +|| the first element of a larger structure +|| that contains state associated with the +|| object; because it is usually the first +|| element, the object pointers can be freely +|| interchanged through casts. +|| +|| int method (R2) Integer QDI method that represents +|| the request type. +|| +|| qurt_qdi_arg_t arg1 (R3) First three general purpose arguments +|| qurt_qdi_arg_t arg2 (R4) to the invocation function are passed in +|| qurt_qdi_arg_t arg3 (R5) these slots. +|| +|| qurt_qdi_arg_t arg4 (SP+0) Arguments beyond the first three are +|| qurt_qdi_arg_t arg5 (SP+4) passed on the stack. +|| qurt_qdi_arg_t arg6 (SP+8) +|| qurt_qdi_arg_t arg7 (SP+12) +|| qurt_qdi_arg_t arg8 (SP+16) +|| qurt_qdi_arg_t arg9 (SP+20) +|| +|| The canonical form of the invocation function takes a +|| total of 12 arguments, but not all of them are used. In general, +|| the QDI infrastructure only passes those arguments provided by +|| the caller; if the invocation function accesses additional +|| arguments beyond those provided by the caller, the values are not +|| useful. +*/ +/** @cond */ +#define QDI_INVOKE_ARGS \ + int, struct qdiobj *, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define QDI_EXT_INVOKE_ARGS \ + int, qurt_qdi_man_obj_t*, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define BUFFER_LOCK 1 +#define BUFFER_UNLOCK 0 + +struct qdiobj; +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef union { + void *ptr; /**< Pointer to the driver handle. */ + int num; /**< Method number. */ +} qurt_qdi_arg_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI driver version */ +typedef union { + int num; + struct { + short major; /** Driver major version number. */ + short minor; /** Driver minor version number. */ + }; +} qurt_qdi_version_t; + +typedef int (*qurt_qdi_pfn_invoke_t)(QDI_INVOKE_ARGS); +typedef void (*qurt_qdi_pfn_release_t)(struct qdiobj *); +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef struct qdiobj { + qurt_qdi_pfn_invoke_t invoke; /**< Invocation function that implements the driver methods.*/ + int refcnt; /**< Reference count, an integer value maintained by the QDI infrastructure that tracks the number of + references to a driver instance. */ + qurt_qdi_pfn_release_t release; /**< Release function that performs details associated with deleting an instance + of the driver object.*/ +} qurt_qdi_obj_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI managed object */ +typedef struct qurt_qdi_man_obj +{ + qurt_qdi_obj_t qdi_obj; + union + { + struct qurt_qdi_ext_driver * opener_obj; + struct qurt_qdi_ext_device * device_obj; + }; +}qurt_qdi_man_obj_t; + +typedef int (*qurt_qdi_ext_pfn_create_t)(int client_id, const char *name, qurt_qdi_version_t version, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_create_device_t)(int client_id, const char *name, qurt_qdi_version_t version, struct qurt_qdi_ext_device * device, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_invoke_t)(QDI_EXT_INVOKE_ARGS); +typedef void (*qurt_qdi_ext_pfn_destroy_t)(qurt_qdi_man_obj_t *qdi_obj); +typedef int (*qurt_qdi_ext_pfn_probe_t)(void *handle, struct qurt_qdi_ext_device **device); + +typedef struct qurt_qdi_ext_obj_info{ + qurt_qdi_man_obj_t *obj; + int qdi_client_id; + struct qurt_qdi_ext_obj_info *next; +}qurt_qdi_ext_obj_info_t; +typedef struct qurt_qdi_ext_obj_info *qurt_qdi_ext_obj_info_ptr; + +/** QuRT QDI device */ +//temporarily add this back while there are still drivers who statically define this structure +struct qurt_qdi_device { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; +}; +typedef struct qurt_qdi_device qurt_qdi_man_device; + +struct qurt_qdi_ext_driver { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + qurt_qdi_ext_pfn_create_device_t create_device; + qurt_qdi_version_t version; + qurt_qdi_ext_pfn_probe_t probe; + const char* compatible; + struct qurt_qdi_ext_device * device_list; + //qurt_qdi_ext_device_ptr device_list; +}; +typedef struct qurt_qdi_ext_driver qurt_qdi_ext_driver_t; +//above replaces qurt_qdi_man_device + +extern int qurt_qdi_obj_ref_inc(qurt_qdi_obj_t *); +extern int qurt_qdi_obj_ref_dec(qurt_qdi_obj_t *); + +extern int qurt_qdi_ext_opener (QDI_INVOKE_ARGS); +/** @endcond */ +/**@ingroup func_qurt_qdi_method_default + Processes a method that is unrecognized or unsupported in the driver invocation function. + All arguments passed to the current invocation function (Section @xref{sec:invocationFunction}) must be forwarded + to this function. + + @note1hang Invocation functions must process all unrecognized or unsupported methods + by calling this function. + + @return + None. + + @dependencies + None. +*/ +extern int qurt_qdi_method_default(QDI_INVOKE_ARGS); + +/**@ingroup func_qurt_qdi_handle_create_from_obj_t + Allocates a new device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[out] obj Pointer to the driver object. + + @return + Non-negative integer -- Success; this value is the new handle. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_invoke + Allocates a new island device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). + @param[in] obj Pointer. + + @return + Non-negative integer value that is the new handle -- Success. \n + Negative return value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_island_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_release + Deallocates the specified device handle. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] handle_to_release Handle to release. + + @return + 0 -- Success. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_release(int client_handle, int handle_to_release) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_RELEASE, + handle_to_release); +} + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_handle(int client_handle, int object_handle) +{ + qurt_qdi_obj_t *ret; + + ret = NULL; + + qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_OBJREF_GET, + object_handle, + &ret); + + return ret; +} + +/**@ingroup func_qurt_client_add_memory + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory(int client_handle, qurt_addr_t phys_addr, qurt_size_t size); + +/**@ingroup func_qurt_client_add_memory2 + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting 36-bit address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory2(int user_client_handle, qurt_paddr_64_t phys_addr, qurt_size_t size); + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_pointer(qurt_qdi_obj_t *objptr) +{ + qurt_qdi_obj_t * ret = NULL; + + if (qurt_qdi_obj_ref_inc(objptr) < 0) { + ret = NULL; + } else { + ret = objptr; + } + + return ret; +} + +static __inline void +qurt_qdi_objref_release(qurt_qdi_obj_t *objptr) +{ + if (qurt_qdi_obj_ref_dec(objptr) == 1) { + (*objptr->release)(objptr); + } +} + +/**@ingroup func_qurt_qdi_copy_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the driver buffer. + @param[in] src Base address of the user buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_from_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_FROM_USER, + dest, src, len); +} + +/**@ingroup qurt_qdi_copy_string_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param dest Base address of the driver buffer. + @param src Base address of the user buffer. + @param len Number of bytes to copy. NOTE: This is the destination buffer length. + + @return + Negative error result -- privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +int qurt_qdi_copy_string_from_user(int client_handle, char *dest, const char *src, unsigned len); + +/**@ingroup func_qurt_qdi_copy_to_user + Copies the contents of a driver memory buffer to user memory. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the user buffer. + @param[in] src Base address of the driver buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_to_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_TO_USER, + dest, src, len); +} + +/**@ingroup func_qurt_qdi_safe_cache_ops + Do cache operations on user memory + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] addr Base address of the user memory. + @param[in] size Size of the user memory. + @param[in] opcode Cache operations (QURT_MEM_CACHE_FLUSH, QURT_MEM_CACHE_INVALIDATE...) + @param[in] type Cache type (QURT_MEM_ICACHE, QURT_MEM_DCACHE) + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_safe_cache_ops(int client_handle, qurt_addr_t addr, qurt_size_t size, + qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SAFE_CACHE_OPS, + addr, size, opcode, type); +} + + +/**@ingroup func_qurt_qdi_buffer_lock + Prepares for the direct manipulation of a potentially untrusted buffer provided by a QDI + client. + + This function is used to permit a trusted driver to safely access memory that is + provided by a potentially untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + + This function performs the following security checks: \n + - Verifies that the entire buffer is accessible to the client. \n + - Ensures that the pointer remains valid for the remainder of the QDI driver + operation. \n + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] buf Pointer to the base address of the client buffer address. + @param[in] len Buffer length (in bytes). + @param[in] perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + - #QDI_PERM_R -- Read access \n + - #QDI_PERM_W -- Write access \n + - #QDI_PERM_RW -- Read/write access @tablebulletend + @param[out] obuf Pointer to the buffer address that the driver must use to access the buffer. + + @return + Negative value -- Error; the operation crosses a privilege boundary, indicating a privilege or security violation. \n + Nonzero value -- User passed a buffer that does not fulfill the requested read/write access permission. + In this case the QDI driver call must be terminated cleanly, with an appropriate error code + returned to the client. \n + Zero -- Success; when this occurs the QDI driver must use the pointer at *obuf to access memory, and not the + pointer passed in as buf -- even if the user process changes the mapping of memory at buf, + the mapping of memory at *obuf remains valid until the driver invocation completes. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK, + buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_lock2 + Prepares for the direct manipulation of a possibly-untrusted buffer provided by a QDI + client. + This API permits a trusted driver to safely access memory + provided by a possibly-untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + This function performs the following security checks: \n + -- Entire buffer is accessible to the client. \n + -- Entire buffer is mapped with permissions passed in perms field \n + -- Entire buffer is physically contiguous \n + In addition to the security checks, the API also locks the client mapping such that the client + cannot remove the mapping while the physical memory is used by the trusted + driver. \n + + @note1 Drivers are responsible for calling qurt_qdi_buffer_unlock() at appropriate time. Not + pairing qurt_qdi_buffer_unlock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client. If the client exits abruptly, the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Safe buffer + unmapping or user buffer unlock is not supported in Island mode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + -- #QDI_PERM_R -- Read access \n + -- #QDI_PERM_W -- Write access \n + -- #QDI_PERM_RW -- Read/write access \n + @param obuf Optional parameter that returns a pointer to the buffer address that + the driver must use to access the buffer. If NULL is passed, the API + only performs security checks and does not create a mapping to access the user buffer in + a safe way. + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EPRIVILEGE -- One of the security checks on the user buffer failed. \n + QURT_EFAILED -- Mapping cannot be created for the trusted driver. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock2(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_LOCK, buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_unlock + This API is paired with qurt_qdi_buffer_lock2(). A temporary overlapping mapping + created for the driver is removed. Client mapping for the user buffer is + unlocked. + + @note1 Drivers are responsible for pairing this with qurt_qdi_buffer_lock(). Not + pairing qurt_qdi_buffer_lock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client, and if the client exits abruptly, all the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Actual + unmapping of driver accessible memory or unlocking of the buffer is not + supported in Island bode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param obuf Safe buffer address that was returned in the obuf field after calling + qurt_qdi_buffer_lock2(). + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. \n + other results -- Safe buffer unmapping failed or unlocking of user buffer failed \n. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_unlock(int client_handle, void *buf, unsigned len, + void *obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_UNLOCK, buf, len, obuf); +} + +/**@ingroup func_qurt_qdi_user_malloc + Allocates memory area in the QDI heap that is read/write accessible to both the driver and + the client. \n + @note1hang The QDI heap has a limited amount of memory available, and only the + device driver can free the allocated memory. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param size Size. + + @return + Non-zero -- Success; this returned value points to the allocated memory area. \n + Zero -- Error. + + @dependencies + None. +*/ +void *qurt_qdi_user_malloc(int client_handle, unsigned size); + +/**@ingroup func_qurt_qdi_user_free + Deallocates memory area in the QDI heap. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param ptr Pointer. + + @dependencies + None. +*/ +void qurt_qdi_user_free(int client_handle, void *ptr); + +/**@ingroup funct_qurt_qdi_client_detach + Detaches a client (a process), indicating that the client does not + participate in the qurt_wait() mechanism. This behavior + is opt-in and irrevocable. When a client is detached, it can + not be un-detached. + + @param client_handle Handle of the client to detach. + + @return + Zero -- Success. Detachable clients always return success. + Nonzero value -- client_handle did not refer to a + detachable user client. + + @dependencies + None. +*/ +static __inline int qurt_qdi_client_detach(int client_handle) +{ + return qurt_qdi_handle_invoke(client_handle, QDI_CLIENT_HANDLE_DETACH); +} + +/**@ingroup func_qurt_qdi_signal_group_create + Creates a new signal group for use in a device driver. + A QDI signal group contains up to 32 signals, which can be operated on either + individually (using the qurt_qdi_signal_* functions) or as a group (using the + qurt_qdi_signal_group_* functions). \n + @note1hang Driver implementation is responsible for using the proper signal group + handle in any given situation. \n + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param p_signal_group_handle_local Returns a handle intended for use by code that + resides in the same context and process as the created signal group + (for example, the device driver implementation that allocated the + signal group). + @param p_signal_group_handle_remote Returns a handle intended for use by code + that resides in a different context and process than the created signal group + (for example, the user-mode client of an OS driver). + + @return + Zero return value indicates success.\n + Negative return value indicates could not create signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_create(int client_handle, + int *p_signal_group_handle_local, + int *p_signal_group_handle_remote) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE, + p_signal_group_handle_local, + p_signal_group_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_group_wait + Suspends the current thread until any of the signals are set in the specified signal group. + + If a signal is set in a signal group object, and a thread waits on the signal group object, + the thread is awakened. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @param signal_group_handle Handle of the signal group. + + @return + If the client is remote: + QURT_EOK -- Wait complete \n + QURT_ECANCEL -- Wait cancelled.\n + If the client is local, returns a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_wait(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_group_poll + Returns a value that indicates if any of the signals are set in the specified signal group. + + @param signal_group_handle Handle of the signal group. + + @return + 1 -- Indicates whether any of the signals are set in the signal group.\n + 0 -- Indicates that none of the signals are set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_poll(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_POLL); +} + + +/**@ingroup func_qurt_qdi_signal_create + Creates a new signal in the specified signal group. + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @note1hang Driver implementation is responsible for using the proper signal handle in + any given situation. + + @param signal_group_handle Handle of an existing signal group. + @param p_signal_handle_local Returns a handle intended for use by code that resides in + the same context and process as the created signal (for example, + the device driver implementation that allocated the signal). + @param p_signal_handle_remote Returns a handle intended for use by code that resides in + a different context and process than the created signal (for + example, the user-mode client of an OS driver). + + @return + Nonzero value -- No more signals can be created in the specified + signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_create(int signal_group_handle, + int *p_signal_handle_local, + int *p_signal_handle_remote) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_SIGNAL_CREATE, + p_signal_handle_local, + p_signal_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_set + Sets the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_set(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_SET); +} + +/**@ingroup func_qurt_qdi_signal_clear + Clears the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_clear(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_CLEAR); +} + +/**@ingroup func_qurt_qdi_signal_wait + Suspends the current thread until the specified signal is set. + If a signal is set in a signal object, and a thread waits on the signal object, the + thread is awakened. If the awakened thread has higher priority than the current thread, a + context switch may occur. + + @param signal_handle Handle of the signal. + + @return + If client is remote: + QURT_EOK -- Wait complete. \n + QURT_ECANCEL -- Wait cancelled.\n + If client is local, return a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_wait(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_poll + Returns a value that indicates if the specified signal is set. + + @param signal_handle Handle of the signal. + + @return + 1 -- Signal is set. \n + 0 -- Signal is not set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_poll(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_POLL); +} + +/**@ingroup func_qurt_qdi_devname_register + Registers a QDI device with the generic QDI object in the + current QDI context. + + This function registers an exact name or a directory prefix with a QDI opener object. + Future invocations of qurt_qdi_open() in the context of the caller invokes the + opener object if a match is detected. + + Directory prefix names are specified by ending the name with a forward slash character. + + Example of an exact name: + @code qurt_qdi_devname_register(/dev/foobar, foobar_opener);@endcode + + Example of a directory prefix: + @code qurt_qdi_devname_register(/pipedev/, pipedev_opener);@endcode + + Given the two registrations shown above, the only qurt_qdi_open() requests to + direct to the foobar_opener object are requests for the exact name + "/dev/foobar", Any request beginning with "/pipedev/" is directed to the + pipedev_opener object. + + The pipedev invocation function presumably examines the name argument to + determine exactly how to handle the request. The name is passed to the invocation + function in the a1.ptr argument (Section @xref{sec:invocationFunction}). + + @param name Device name or device name prefix. + @param opener Pointer to the opener object for the device. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. + + @dependencies + None. + */ +static __inline int qurt_qdi_devname_register(const char *name, + qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, + QDI_DEVNAME_REGISTER, + name, + opener); +} + +// Macros for backward compatibility with deprecated APIs +// (These will go away soon) + +#define qurt_qdi_register_devname(name, opener) \ + qurt_qdi_devname_register((name), (void *)(opener)) +#define qurt_qdi_new_handle_from_obj_t(handle, obj) \ + qurt_qdi_handle_create_from_obj_t((handle), (obj)) +#define qurt_qdi_release_handle(client_handle, handle) \ + qurt_qdi_handle_release((client_handle), (handle)) +#define qurt_qdi_lock_buffer(handle, buf, len, perms, obuf) \ + qurt_qdi_buffer_lock((handle), (buf), (len), (perms), (obuf)) +#define qurt_qdi_usermalloc(handle, size) \ + qurt_qdi_user_malloc((handle), (size)) +#define qurt_qdi_userfree(handle, ptr) \ + qurt_qdi_user_free((handle), (ptr)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_ext.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_ext.h new file mode 100755 index 0000000000000..383e1799a15d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_ext.h @@ -0,0 +1,58 @@ +#ifndef QURT_QDI_EXT_H +#define QURT_QDI_EXT_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018, 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct qurt_qdi_ext_device { + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + struct qurt_qdi_ext_device * next; + char * instance; + fdt_node_handle context; +}; +typedef struct qurt_qdi_ext_device *qurt_qdi_ext_device_ptr; + +/**@ingroup func_qurt_qdi_dt_register + Registers a QDI device with the generic QDI object in the current QDI context, + if and only if a compatible device node is found in the device tree. This + function serves as a device tree aware wrapper for qurt_qdi_devname_register(). + + @param name Device name or device name prefix. + @param opener Pointer to QDI ext specialized opener object for the driver. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. +*/ +static __inline int qurt_qdi_dt_register(const char *name, qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_DT_REGISTER, name, opener); +} + +static inline void qurt_qdi_ext_deviceobj_set_name (struct qurt_qdi_ext_device * device, char * name) +{ + device->instance = name; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_imacros.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_imacros.h new file mode 100755 index 0000000000000..c0a8448ac87f8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_imacros.h @@ -0,0 +1,34 @@ +#ifndef QURT_QDI_IMACROS_H +#define QURT_QDI_IMACROS_H + +/** + @file qurt_qdi_imacros.h + @brief Internal macros used for QDI. Mostly consists of tricky (and ugly) + preprocessor hacks that permit us to do varargs function invocations + where we pass optional arguments in registers and where we can do + type casting and checking automatically. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _QDMPASTE(a,b) _QDMPASTE_(a,b) +#define _QDMPASTE_(a,b) a##b +#define _QDMCNT(...) _QDMCNT_(__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _QDMCNT_(a,b,c,d,e,f,g,h,i,j,k,l,cnt,...) cnt + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_proxy.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_proxy.h new file mode 100755 index 0000000000000..f1d8992ea8811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_qdi_proxy.h @@ -0,0 +1,55 @@ +/*============================================================================= + + qurt_qdi_proxy.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef _QURT_QDI_PROXY_H +#define _QURT_QDI_PROXY_H + +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* APIs allowing operation on the proxy object directly */ +int qurt_qdi_proxy_ref_create(void); + +/* APIs allowing to operate on proxy given a known proxy handle + * 1) using qdi handle of the object + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_handle(int proxy_handle, int qdi_handle); +int qurt_qdi_proxy_ref_sub_by_handle(int proxy_handle, int qdi_handle); + +/* 2) using object reference + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); +int qurt_qdi_proxy_ref_sub_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); + +/* API allowing to associate a proxy object with a particular client given a client handle + * successfule return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_install (int client_handle, int proxy_handle); + +/* APIs allowing operation on proxy object from user client + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_add(int qdi_handle); +int qurt_client_proxy_ref_remove(int qdi_handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_QDI_PROXY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex.h new file mode 100755 index 0000000000000..a013a0bbddb1d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_RMUTEX_H +#define QURT_RMUTEX_H +/** + @file qurt_rmutex.h + Prototypes of rmutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013 - 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_rmutex_init + Initializes a recursive mutex object. + The recursive mutex is initialized in unlocked state. + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_destroy + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex protects, and continues executing. + + If a thread performs a lock operation on a mutex that is already use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock_timed + Locks the specified recursive mutex. The wait must be terminated when the specified timeout expires.\n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex is protecting, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked by itself. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + If timeout expires, this wait must be terminated and no access to the mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + + */ +int qurt_rmutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + +/**@ingroup func_qurt_rmutex_unlock + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a mutex. When the mutex is + unlocked, the thread waiting on the mutex awakens. If the awakened + thread has higher priority than the current thread, a context switch occurs. + + @note1hang When a thread unlocks a recursive mutex, the mutex is not available until + the balanced number of locks and unlocks has been performed on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock + Attempts to lock the specified recursive mutex.\n + + If a thread performs a try_lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing.\n + If a thread performs a try_lock operation on a recursive mutex that another thread has + already locked, qurt_rmutex_try_lock immediately returns with a nonzero result + value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex_try_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock_block_once + Attempts to lock a mutex object recursively. If the mutex is available, + it locks the mutex. If the mutex is held by the current thread, + it increases the internal counter and returns 0. If not, it returns a + nonzero value. + If the mutex is already locked by another thread, the caller thread is + suspended. When the mutex becomes available again (because the other + thread has unlocked it), the caller thread is awakened and tries to lock + the mutex; and if it fails, this function returns failure with a nonzero + value. If it succeeds, this function returns success with zero. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the qurt_mutex_t object. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_rmutex_try_lock_block_once(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex2.h new file mode 100755 index 0000000000000..a37e7e4458c4b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_rmutex2.h @@ -0,0 +1,183 @@ +#ifndef QURT_RMUTEX2_H +#define QURT_RMUTEX2_H +/** + @file qurt_rmutex2.h + @brief Prototypes of rmutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT rmutex2 type. + Mutex type used with rmutex2 APIs. + */ +typedef struct { + /** @cond */ + unsigned int holder __attribute__((aligned(8))); /* UGP value of the mutex holder. */ + unsigned short waiters; /* Number of waiting threads. */ + unsigned short refs; /* Number of references to this mutex. */ + unsigned int queue; /* Kernel-maintained futex queuevalue. */ + unsigned int excess_locks; /* Number of excess times the holder has locked the mutex. */ + /** @endcond */ +} qurt_rmutex2_t; +/** @} */ /* end_addtogroup mutex_types */ +/** @cond internal_only*/ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_rmutex2_init + + @deprecated use #qurt_rmutex_init instead. + + Initializes a recursive mutex object. + + The recursive mutex is initially unlocked. + + Objects of type rmutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_destroy + + @deprecated use #qurt_rmutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code must destroy an rmutex2 object prior to + deallocating it; calling qurt_rmutex2_destroy() before deallocating it ensures + that all qurt_rmutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_lock + + @deprecated use #qurt_rmutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that the mutex protects, and continues + to execute. + + If a thread performs a lock operation on a recursive mutex that another thread is using, + the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_unlock + + @deprecated use #qurt_rmutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex awakens. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_rmutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_rmutex2_lock(). When a call to qurt_rmutex2_lock() + succeeds immediately, this function behaves similarly, returning 0 for success. + When a call to qurt_rmutex2_lock() does not succeed immediately, this function has + no effect and returns nonzero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex2_try_lock(qurt_rmutex2_t *lock); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sclk.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sclk.h new file mode 100755 index 0000000000000..a83cf5f1db889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sclk.h @@ -0,0 +1,145 @@ +#ifndef QURT_SCLK_H +#define QURT_SCLK_H +/** + @file qurt_sclk.h + @brief Header file describing the APIs supported by QuRT system SCLK + feature. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + + +/*============================================================================= + + INCLUDE FILES + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + Conversion from microseconds to sleep ticks. + */ +#define QURT_SYSCLOCK_TIMETICK_FROM_US(us) ((us) * 192ULL / 10UL) +#define qurt_sysclock_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_SYSCLOCK_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_SYSCLOCK_MAX_DURATION (1042499uLL * 3600uLL * 1000uLL * 1000uLL) +#define qurt_sysclock_max_duration() QURT_SYSCLOCK_MAX_DURATION +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_SYSCLOCK_MAX_DURATION_TICKS (1042499uLL * 3600uLL * 19200000uLL) +#define qurt_sysclock_max_duration_ticks() QURT_SYSCLOCK_MAX_DURATION_TICKS +/** + Sleep timer error margin for Qtimer is 192 ticks ~10 us. +*/ +#define QURT_SYSCLOCK_ERROR_MARGIN 192U //QURT_TIMER_MIN_DURATION*timer_freq; +#define qurt_sysclock_error_margin() QURT_SYSCLOCK_ERROR_MARGIN + +/*============================================================================= + + DATA DECLARATIONS + +=============================================================================*/ + +/**@ingroup func_qurt_sysclock_get_hw_ticks + @xreflabel{sec:qurt_sysclock_get_hw_ticks} + Gets the hardware tick count.\n + Returns the current value of a 64-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation must be used with care because of the wrap-around behavior. + + @return + Integer -- Current value of 64-bit hardware counter. + + @dependencies + None. + */ +unsigned long long qurt_sysclock_get_hw_ticks (void); + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_32 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_32} + Gets the hardware tick count in 32 bits.\n + Returns the current value of a 32-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 32 bits are the lower 32 bits of the Qtimer counter. + + @return + Integer -- Current value of the 32-bit timer counter. + + @dependencies + None. + */ +static inline unsigned long qurt_sysclock_get_hw_ticks_32 (void) +{ + //Beginning with v61 there is a HW register that can be read directly. + unsigned long count; + __asm__ __volatile__ (" %0 = c30 " : "=r"(count)); + return count; +} + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_16 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_16} + Gets the hardware tick count in 16 bits.\n + Returns the current value of a 16-bit timer counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 16 bits are based on the value of the lower 32 bits in Qtimer + counter, right shifted by 16 bits. + + @return + Integer -- Current value of the 16-bit timer counter, calculated from the lower 32 bits in the + Qtimer counter, right shifted by 16 bits. + + @dependencies + None. + */ + + +static inline unsigned short qurt_sysclock_get_hw_ticks_16 (void) +{ + unsigned long ticks; + + //Beginning with v61 there is a HW register that can be read directly. + __asm__ __volatile__ (" %0 = c30 " : "=r"(ticks)); + __asm__ __volatile__ ( "%0 = lsr(%0, #16) \n" :"+r"(ticks)); + + return (unsigned short)ticks; +} +unsigned long long qurt_timer_timetick_to_us(unsigned long long ticks); +#define qurt_sysclock_timetick_to_us(ticks) qurt_timer_timetick_to_us(ticks) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif /* QURT_SCLK_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_secure_proc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_secure_proc.h new file mode 100755 index 0000000000000..f40c7deb9bca1 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_secure_proc.h @@ -0,0 +1,53 @@ +#ifndef QURT_SECURE_PROC_H +#define QURT_SECURE_PROC_H + +/** + @file qurt_secure_proc.h + @brief Definitions, macros, and prototypes used for handling secure process + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_process_migrate_secure_process + Migrate the user process to Qurt secure process + + @param secure_phy_address Physical starting address of secure memory + @param secure_memory_size Size of secure memory + @param entry Entry function to secure process + + @return + EOK + Negative return value -- Error. + + @dependencies + None. +*/ +int qurt_process_migrate_secure_process(unsigned long long secure_phy_address, unsigned int secure_memory_size, void entry(unsigned)); + +/**@ingroup qurt_process_get_migration_mem_size + get the size of all writable memory regions in a user PD. This is for preparation on secure process migration. + + @return + size of all writable memory regions in a user PD. + + @dependencies + None. +*/ +int qurt_process_get_migration_mem_size(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sem.h new file mode 100755 index 0000000000000..ee5ce4b2d94ab --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_sem.h @@ -0,0 +1,252 @@ +#ifndef QURT_SEM_H +#define QURT_SEM_H +/** + @file qurt_sem.h + Prototypes of semaphore API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup semaphore_types +@{ */ + +/** QuRT semaphore type. */ +typedef union { + /** @cond */ + unsigned int raw[2] __attribute__((aligned(8))); + struct { + unsigned short val; /**< */ + unsigned short n_waiting; /**< */ + unsigned int reserved1; /**< */ + unsigned int queue; /**< */ + unsigned int reserved2; /**< */ + }X; /** @endcond */ +} qurt_sem_t; +/** @} */ /* end_addtogroup semaphore_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_sem_add + Releases access to a shared resource (the specified amount increments the semaphore count value).\n + When a thread performs an add operation on a semaphore, the specified value increments the semaphore count. + The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing. \n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel repeatedly awakens the highest-priority waiting thread and decrements + the semaphore count value until either no waiting threads remain or the + semaphore count value is zero. If any of the awakened threads has higher priority + than the current thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] amt Amount to increment the semaphore count value. + + @return + Unused integer value. + + @dependencies + None. + + */ +int qurt_sem_add(qurt_sem_t *sem, unsigned int amt); + +/**@ingroup func_qurt_sem_up + Releases access to a shared resource. When a thread performs an up operation on a semaphore, + the semaphore count value increments. The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing.\n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel awakens the highest-priority waiting thread and decrements the + semaphore count value. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +static inline int qurt_sem_up(qurt_sem_t *sem) { return qurt_sem_add(sem,1); } + +/**@ingroup func_qurt_sem_down + Requests access to a shared resource. When a thread performs a down operation on a + semaphore, the result depends on the semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +int qurt_sem_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_down_timed + When a thread performs a down operation on a semaphore, the result depends on the + semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. Terminate the wait when the specified timeout expires. + If timeout expires, terminate this wait and grant no access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_sem_down_timed(qurt_sem_t *sem, unsigned long long int duration); + +/**@ingroup func_qurt_sem_try_down + @xreflabel{hdr:qurt_sem_try_down} + Requests access to a shared resource (without suspend). When a thread performs a try down + operation on a semaphore, the result depends on the semaphore count value: \n + - The count value is decremented when it is nonzero. The down operation returns 0 as + the function result, and the thread gains access to the shared resource and is free to + continue executing.\n + - The count value is not decremented when it is zero. The down operation returns -1 + as the function result, and the thread does not gain access to the shared resource + and should not continue executing. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + 0 -- Success. \n + -1 -- Failure. + + @dependencies + None. + + */ +int qurt_sem_try_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init + Initializes a semaphore object. + The default initial value of the semaphore count value is 1. + + @param[out] sem Pointer to the initialized semaphore object. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_destroy + Destroys the specified semaphore.\n + @note1hang Semaphores must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Semaphores must not be destroyed while they are still in use. If this occur, + the behavior of QuRT is undefined. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_sem_destroy(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init_val + Initializes a semaphore object with the specified value. + + @datatypes + #qurt_sem_t + + @param[out] sem Pointer to the initialized semaphore object. + @param[in] val Initial value of the semaphore count value. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init_val(qurt_sem_t *sem, unsigned short val); + +/**@ingroup func_qurt_sem_get_val + Gets the semaphore count value.\n + Returns the current count value of the specified semaphore. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Integer semaphore count value + + @dependencies + None. + */ +static inline unsigned short qurt_sem_get_val(qurt_sem_t *sem ){return sem->X.val;} +int qurt_sem_down_cancellable(qurt_sem_t *sem); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SEM_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_shmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_shmem.h new file mode 100755 index 0000000000000..980557323708a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_shmem.h @@ -0,0 +1,89 @@ +#ifndef QURT_SHMEM_H +#define QURT_SHMEM_H + +/** + @file qurt_shmem.h + + @brief + Prototypes of QuRT inter-process shared memory APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MODE_T +#define MODE_T +typedef unsigned int mode_t; +#endif //MODE_T + +/** + * The shm_open() function establishes a connection between a shared memory object and a file descriptor. + * The file descriptor is used by other functions such as mmap() to refer to that shared memory object. + * + * + * @param name Pointer to string naming a shared memory object. Name has to start with "/shm/" + * @param oflag File status flags and file access modes of the open file description. Following + * flags are defined in and supported: + * O_RDONLY: oepn for read access only + * O_RDWR: Open for read or write access + * O_CREAT: If shared memory object doesn't exist, create one. + * @param mode Permission flags (currently ignored) + * + * @return file descriptor (positive number) if operation successful. + * negative error code if failed + * +*/ + +int shm_open(const char * name, int oflag, mode_t mode); + +/** + * The shm_mmap() function create a shared memory mapping in the virtual address space of the + * the calling process. + * + * @param addr The starting address for the new mapping is specified in addr. + * @param len Specifies the lengh of the shared memory region. + * @param prot Describes the desired memory protection of the mapping. Same as the one in mmap of POSIX. + * @param flags Determines whether updates to the mapping is visible or not to other process. Same as + * the one in mmap of POSIX. + * @param fd The starting adddress for the new mapping is returned. + * @param offset unused. + * + * @return The starting adddress for the new mapping is returned. + * negative error code if failed + * +*/ + +void *shm_mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset); + +/** + * The shm_close() function removes a connection between a shared memory object and a file descriptor. + * If there is no file descriptor connects to the shared memory object, the shared memory object will + * be deleted automatically. Shared memory object has same virtual address in any process. This is + * restriction of single virtual address space. + * + * + * @param fd File descriptor of shared memory object + * + * @return 0 if operation successful. + * negative error code if failed + * +*/ + + +int shm_close(int fd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal.h new file mode 100755 index 0000000000000..3a89c53394ad5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal.h @@ -0,0 +1,518 @@ +#ifndef QURT_SIGNAL_H +#define QURT_SIGNAL_H + +/** + @file qurt_signal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup signals_types +@{ */ +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 /**< Wait any. */ +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 /**< Wait all. */ + +/*===================================================================== + Typedefs + ======================================================================*/ + + +/** QuRT signal type. + */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int signals; + unsigned int waiting; + unsigned int queue; + unsigned int attribute; + }X; + /** @endcond */ +} qurt_signal_t; + + +/** QuRT 64-bit signal type. + */ +typedef struct { + /** @cond */ + qurt_signal_t signal_sum; + unsigned long long signals; + unsigned long long waiting; + /** @endcond */ +} qurt_signal_64_t; +/** @} */ /* end_addtogroup signals_types */ +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal_init + Initializes a signal object. + Signal returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_init(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_destroy + Destroys the specified signal object. + + @note1hang Signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_destroy(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting on the signal. + + If a thread is waiting on a signal object for any of the specified set of signals to set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared when the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread waits to set any of the signals, or to set all of + them. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_timed + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set or until timeout. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared after the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value that identifies the individual signals in the signal object to wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] signals Bitmask of signals that are set + @param[in] duration Duration (microseconds) to wait. Must be in the range + [#QURT_TIMER_MIN_DURATION ... #QURT_TIMER_MAX_DURATION] + + @return + #QURT_EOK -- Success; one or more signals were set \n + #QURT_ETIMEDOUT -- Timed-out \n + #QURT_EINVALID -- Duration out of range + + @dependencies + Timed-waiting support in the kernel. +*/ +/* ======================================================================*/ +int qurt_signal_wait_timed(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, unsigned int *signals, unsigned long long int duration); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_any + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on the thread. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_any(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_all + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_all(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to set the signal, and 0 indicates not to set it. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 32-bit word with current signals + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_get(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_clear + Clear signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_clear(qurt_signal_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal_wait_cancellable + @xreflabel{hdr:qurt_signal_wait_cancellable} + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] return_mask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_signal_wait_cancellable(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, + unsigned int *return_mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_init + Initializes a 64-bit signal object.\n + The signal argument returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore. + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_init(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_destroy + Destroys the specified signal object. + + @note1hang 64-bit signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_destroy(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_wait + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value, which identifies the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_wait(qurt_signal_64_t *signal, unsigned long long mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set it. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifiying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_64_set(qurt_signal_64_t *signal, unsigned long long mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_64_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 64-bit double word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_get(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_clear + Clears signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_clear(qurt_signal_64_t *signal, unsigned long long mask); + +#ifdef __cplusplus +} +#endif + +#endif /* QURT_SIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal2.h new file mode 100755 index 0000000000000..43975100cbf75 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_signal2.h @@ -0,0 +1,340 @@ +#ifndef QURT_SIGNAL2_H +#define QURT_SIGNAL2_H + +/** + @file qurt_signal2.h + @brief Prototypes of kernel signal2 API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 + +/*===================================================================== + Typedefs + ======================================================================*/ + +/** @addtogroup signals2_types +@{ */ +/** qurt_signal2 type. + */ +typedef union { + /** @cond */ + struct{ + unsigned int cur_mask; /* Current set of signal bits that are set. */ + unsigned int sig_state; /* Current state. */ + /* Bit 0 -- in anysignal wait. */ + /* Bit 1 -- in allsignal wait. */ + /* Bit 2 -- in interrupt wait. */ + /* Bits 31-3 -- reference count field. */ + unsigned int queue; /* Kernel-maintained futex queue value. */ + unsigned int wait_mask; /* When sig_state indicates a waiter is present, this is the wait mask. */ + }; + unsigned long long int raw; + /** @endcond */ +} qurt_signal2_t; +/* @} */ /* end_addtogroup signals2_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_init + + @deprecated use #qurt_signal_init instead. + + Initializes a signal2 object. + Signal returns the initialized object. + The signal object is initially cleared. + + Objects of type signal2 solve a potential race condition between + set() and destroy() operations. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + Each mutex-based object has an associated + kernel resource(s), therefore users must call qurt_signal2_destroy() + when this object no longer in use. + */ +/* ======================================================================*/ +void qurt_signal2_init(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_destroy + + @deprecated use #qurt_signal_destroy instead. + + Destroys the specified signal object. + + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont Application code should destroy a signal2 object prior to deallocating it. + Calling qurt_signal2_destroy() before deallocating a + signal2 object ensures completion of all qurt_signal2_set() calls. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_destroy(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait + + @deprecated use #qurt_signal_wait instead. + + Suspends the current thread until the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ANY, the thread will be awakened when + any of the signals specified in the mask are set. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ALL, the thread will be awakened only + when all the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to wait on. + @param[in] attribute Specifies whether the thread waits for any of the signals to be set, or for all of + them to be set. Values:\n + - QURT_SIGNAL_ATTR_WAIT_ANY \n + - QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_any + + @deprecated use #qurt_signal_wait_any instead. + + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened when any of the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_any(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_all + + @deprecated use #qurt_signal_wait_all instead. + + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened only when all the signals specified in the mask are set. + + @note1hang At most one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_all(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_set + + @deprecated use #qurt_signal_set instead. + + Sets signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_get + + @deprecated use #qurt_signal_get instead. + + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the signal object to access. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_get(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_clear + + @deprecated use #qurt_signal_clear instead. + + Clear signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_clear(qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal2_wait_cancellable + + @deprecated use #qurt_signal_wait_cancellable instead. + + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] p_returnmask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +int qurt_signal2_wait_cancellable(qurt_signal2_t *signal, + unsigned int mask, + unsigned int attribute, + unsigned int *p_returnmask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SIGNAL2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_space.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_space.h new file mode 100755 index 0000000000000..2c3f9e4496697 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_space.h @@ -0,0 +1,230 @@ +#ifndef QURT_SPACE_H +#define QURT_SPACE_H +/** + @file qurt_space.h + @brief Prototypes of QuRT process control APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** This flag is a request to the OS to suspend the processes just before calling main() +But it is going to be obsoleted and replaced by QURT_PROCESS_SUSPEND_ON_STARTUP */ +#define SPAWNN_FLAG_SUSPEND_ON_STARTUP QURT_PROCESS_SUSPEND_ON_STARTUP + +/** + * Creates and starts a process from ELF of a specified name. The slash symbols + * "/" or "\" are ignored. Do not include the directory name in the input. This function + * accepts the the SPAWN flags. Multiple SPAWN flags can be specified by OR'ing the flags. + * + * @param name ELF name of the executable. Name shall not contain directories, + * use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf" + * + * @param return + Process ID -- Success \n + Negative error code -- failure\n + #QURT_EPRIVILEGE -- Caller does not have enough privilege for this operation\n + #QURT_EMEM -- Not enough memory to perform the operation \n + #QURT_EFAILED -- Operation failed \n + #QURT_ENOTALLOWED -- Operation not allowed \n + #QURT_ENOREGISTERED -- Not registered \n + #QURT_ENORESOURCE -- Resource exhaustion \n + #QURT_EINVALID -- Invalid argument value +*/ + +int qurt_spawn_flags(const char * name, int flags); + +/** + Creates and starts a process from an ELF of the specified name. The slash symbols + "/" or "\" are ignored. Do not include the directory name in the input. + + @param name ELF name of the executable. Name shall not contain directories, + use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf". + + @return + Process ID -- Success. \m + Negative error code -- Failure. + +*/ +static inline int qurt_spawn(const char *name) +{ + return qurt_spawn_flags(name,0); +} + +/** + * Returns the process ID of the current process. + * + * @return + * Process ID + * +*/ +#define qurt_getpid qurt_process_get_id + +/** + * The qurt_wait() function waits for status change in a child process. It could be used by parent + * process to block on any child process terminates. + * + * This API returns error if there are no user processes or all user processes got detached. + * + * @param status Pointer to status variable. The variable provides the status value of child process. + * The value comes from exit() system call made by child process. + * + * @return + Process ID of the child process that changes status -- Success \n + * Negative error code -- Failure + * +*/ + +int qurt_wait(int *status); + + +/** @cond */ +/* APIs that allow registering callbacks on spawn of user pd */ +typedef void (*QURT_SPAWN_PFN)(int client_handle, void *data_ptr); //no return, since we won't be error checking it in spawn +typedef int (*QURT_CB_PFN)(int client_handle, void *user_data, void *info); +typedef union { + QURT_SPAWN_PFN spawn_pfn; + QURT_CB_PFN cb_pfn; +} qurt_process_callback_pfn_t; +/** @endcond */ + +/** @cond internal_only */ + +/**@ingroup func_qurt_event_register +Sets the specified bits by mask in the signal passed by the caller. The signal gets set +when the client handle indicated by value goes away (at process exit). Multiple clients can register for the signal +to be set. + +@datatypes + +@param[in] type QURT_PROCESS_EXIT is the only event that can be registered for. +@param[in] value Indicates the client handle of the process for which the event is registered. +@param[in] signal Pointer to the signal object to set when the event occurs. +@param[in] mask Mask bits to set in the signal. +@param[out] data Pointer to the variable that would receive the exit code of the exiting process. +@param[in] datasize Size of the data variable. + +@return +#QURT_EOK -- Success \n +#QURT_EMEM -- Not enough memory to allocate resources \n +#QURT_EVAL -- Invalid values passed to the API + +@dependencies +None. +*/ +int qurt_event_register(int type, int value, qurt_signal_t *psig, unsigned int mask, void *data, unsigned int data_size); + +/**@ingroup func_qurt_callback_register_onspawn +Allows registering for a callback on spawn of any user process. + +@datatypes +#QURT_SPAWN_PFN + +@param[in] pFn Callback function to call when any user process is spawned. +@param[in] user_data Pointer to the argument that the callback must be called with. + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_callback_register_onspawn(QURT_SPAWN_PFN pFn, void *user_data); + +/**@ingroup func_qurt_callback_deregister_onspawn +Allows de-registering callback on spawn. + +@param[in] callback_handle Handle returned by qurt_callback_register_onspawn. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_callback_deregister_onspawn(int callback_handle); + +/**@ingroup func_qurt_process_callback_register +Allows registering for a callback during or after image loading. +Generic callback types: + Functions similarly to qurt_callback_register_onspawn(). Callback is called after process is + loaded, before process thread starts. Callback has no return value and has no info provided + from OS. + pFn - QURT_SPAWN_PFN + type - QURT_PROCESS_CB_GENERIC + arg1 - not used + arg2 - not used + arg3 - not used +Note callback types: + Callback is called during process loading: before segment loading(QURT_PROCESS_NOTE_CB_PRE_MAP), + or after segment loading (QURT_PROCESS_NOTE_CB_POST_MAP). OS provides info to the callback. info + argument in callback is populated with pointer to the mapped note corresponding to the callback. + Callback has return value, loader fails if callback returns a value that is not QURT_EOK. + pFn - QURT_CB_PFN + type - QURT_PROCESS_NOTE_CB_PRE_MAP or QURT_PROCESS_NOTE_CB_POST_MAP + arg1 - note type (ex: NOTE_TYPE_POOL_INFO, NOTE_TYPE_SEGMENT_INFO, NOTE_TYPE_ARB_INFO) + arg2 - note name + arg3 - not used + +@datatypes + +@param[in] pFn Callback function to call +@param[in] type Callback type +@param[in] user_data Pointer to the argument that the callback must be called with. +@param[in] arg1 Arguments interpreted by OS based on callback type +@param[in] arg2 Arguments interpreted by OS based on callback type +@param[in] arg3 Arguments interpreted by OS based on callback type (currently not used) + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_process_callback_register(qurt_process_callback_pfn_t pFn, + qurt_process_cb_type_t type, + void *user_data, + qurt_process_callback_arg_t arg1, + qurt_process_callback_arg_t arg2, + qurt_process_callback_arg_t arg3); + + + +/**@ingroup func_qurt_process_callback_deregister +Allows de-registering callback for imate loading. +@param[in] callback_handle Handle returned by qurt_process_callback_register. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_process_callback_deregister(int callback_handle); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SPACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_consts.h new file mode 100755 index 0000000000000..48a8b6a38c402 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_consts.h @@ -0,0 +1,32 @@ +#ifndef QURT_SRM_CONSTS_H +#define QURT_SRM_CONSTS_H +/** + @file qurt_srm_consts.h + @brief Type definitions for srm + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2020-2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +#define QURT_SRM_WAKEUP_REQUEST 1U << 0 /**< Value = 1: Send wakeup request to the SRM server. */ +#define QURT_SRM_SET_HANDLE 1U << 1 /**< Value = 2: Set the client handle for a new SRM client. */ +#define QURT_SRM_ALLOC_KERNEL_PAGES 1U << 2 /**< Value = 4: Allocate pages from the kernel VA space. */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_driver.h new file mode 100755 index 0000000000000..5489e3dddbcca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_srm_driver.h @@ -0,0 +1,140 @@ +#ifndef QURT_SRM_DRIVER_H +#define QURT_SRM_DRIVER_H +/** + @file qurt_srm_driver.h + @brief Definitions, macros, and prototypes used by SRM drivers. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + + =============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Define qurt_srm_driver_t structure, which represents +|| the "registration" object for an SRM driver. +*/ +/** @cond internal_only */ +struct _qurt_srm_driver { + const char *name; + qurt_qdi_obj_t *obj; +}; + +typedef struct _qurt_srm_driver qurt_srm_driver_t; + +/* +|| qurt_srm_object_invoke() is an internal equivalent to qurt_qdi_handle_invoke(). +|| It behaves the same, but it takes a QDI object pointer instead of a handle. +*/ + +#define qurt_srm_object_invoke(o,m,...) \ + _QDMPASTE(_QDMSOI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__) +#define _QDMSOI3(a,b,c) qurt_srm_oi3(a,b,c) +#define _QDMSOI4(a,b,c,d) qurt_srm_oi4(a,b,c,(int)(d)) +#define _QDMSOI5(a,b,c,d,e) qurt_srm_oi5(a,b,c,(int)(d),(int)(e)) +#define _QDMSOI6(a,b,c,d,e,f) qurt_srm_oi6(a,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMSOI7(a,b,c,d,e,f,g) qurt_srm_oi7(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMSOI8(a,b,c,d,e,f,g,h) qurt_srm_oi8(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMSOI9(a,b,c,d,e,f,g,h,i) qurt_srm_oi9(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMSOI10(a,b,c,d,e,f,g,h,i,j) qurt_srm_oi10(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMSOI11(a,b,c,d,e,f,g,h,i,j,k) qurt_srm_oi11(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMSOI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_srm_oi12(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) + +int qurt_srm_oi3(int, qurt_qdi_obj_t *, int); +int qurt_srm_oi4(int, qurt_qdi_obj_t *, int, int); +int qurt_srm_oi5(int, qurt_qdi_obj_t *, int, int, int); +int qurt_srm_oi6(int, qurt_qdi_obj_t *, int, int, int, int); +int qurt_srm_oi7(int, qurt_qdi_obj_t *, int, int, int, int, int); +int qurt_srm_oi8(int, qurt_qdi_obj_t *, int, int, int, int, int, int); +int qurt_srm_oi9(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int); +int qurt_srm_oi10(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int); +int qurt_srm_oi11(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int); +int qurt_srm_oi12(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int, int); + +#define QDI_SRM_INIT 192 + +/* +|| QURT_SRM_DECLARE_DRIVER() declares an SRM driver to the SRM infrastructure. +|| +|| The three arguments are: +|| unique_id -- Unique C identifier, unused but must be a unique global symbol. +|| name -- Name of the driver by which an SRM client attempts to open it. +|| obj -- Pointer to the singleton object of the driver, which handles things such as +|| initialization and QDI_OPEN requests. +*/ + +#define QURT_SRM_DECLARE_DRIVER(unique_id, xname, xobj) \ + __attribute__((section(".srm.rodata.user.main.DECL"))) const qurt_srm_driver_t unique_id = \ + { .name = xname, .obj = xobj } + + +/*@ingroup func_qurt_srm_mapping_create + Creates a memory mapping in pagetable with specified attributes + + @param[in] client_handle Client handle representing the process for which + mapping would be created. + @param[in] pageno_virt pointer to the virtual page. NULL indicates SRM + would indicate the virtual memory. + @param[in] pageno_phys physical page to be used for the mapping + @param[in] page_count number of 4k pages to be mapped + @param[in] cache_attr cache attributes for the mapping + @param[in] perm permissions to be used for the mapping + + @return value greater than 0 indicates a handle which can be passed to + qdi_close() to remove the mapping. Negative value indicates + an error. + + @dependencies + None. +*/ +int qurt_srm_mapping_create(int client_handle, + unsigned *pageno_virt, + unsigned pageno_phys, + unsigned page_count, + qurt_mem_cache_mode_t cache_attr, + qurt_perm_t perm); + + +/**@ingroup func_qurt_srm_get_pid + Gets the PID for the client_handle that is passed. + + @param[in] client_handle Client handle for which PID is required. + + @return PID of the client + Negative PID value '-1' will be returned in case of Error + + @dependencies + None. +*/ +unsigned qurt_srm_get_pid(int client_handle); + + +/*@ingroup func_qurt_srm_get_thread_id + Gets the thread id of the client requesting a service from SRM + + @param[in] None. + + @return thead id of client thread + + @dependencies + None. +*/ +qurt_thread_t qurt_srm_get_client_thread_id(void); + +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_DRIVER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_stid.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_stid.h new file mode 100755 index 0000000000000..379f46aaa4b80 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_stid.h @@ -0,0 +1,73 @@ +#ifndef QURT_STID_H +#define QURT_STID_H +/** + @file qurt_stid.h + Prototypes of software thread identifier(stid) interface APIs. + A stid is 8 bit identifier that can be assigned to a software thread. + The performance monitor logic uses stid as a counting match criteria + for maskable events. stid is also used by the hardware debugger + (ISDB) to match breakpoints. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2024 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_stid_alloc + Allocate a unique stid + + @param[in] pid Process identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - Allocation success + QURT_ENORESOURCE - No stid available for allocation + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_stid_alloc(unsigned int pid, unsigned int *stid); + +/**@ingroup func_qurt_stid_release + Release the stid. + + + @param[in] pid Process identifier + @param[in] stid STID to release + + @note1hang + User shall ensure to clear the released stid from process or thread(s) + to default value (QURT_STID_DEFAULT) before releasing that stid + + @return + QURT_EOK - Release success + QURT_ENOTALLOWED - Operation not allowed for a pid + QURT_EINVALID - Invalid stid + + @dependencies + None. + */ +int qurt_stid_release(unsigned int pid, unsigned int stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_STID_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread.h new file mode 100755 index 0000000000000..499699e7c72e2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread.h @@ -0,0 +1,1260 @@ +#ifndef QURT_THREAD_H +#define QURT_THREAD_H +/** + @file qurt_thread.h + @brief Prototypes of Thread API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2020-2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +#include +#include "qurt_pmu.h" +#include "qurt_api_version.h" +#endif /* __ASSEMBLER__ */ +#include "qurt_consts.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/* + Bitmask configuration to select DSP hardware threads. + To select all the hardware threads, use #QURT_THREAD_CFG_BITMASK_ALL + and the following: \n + - For QDSP6 V2/V3, all six hardware threads are selected \n + - For QDSP6 V3L, all four hardware threads are selected \n + - For QDSP6 V4, all three hardware threads are selected + */ + +#define QURT_THREAD_CFG_BITMASK_HT0 0x00000001 /**< HTO. */ +#define QURT_THREAD_CFG_BITMASK_HT1 0x00000002 /**< HT1. */ +#define QURT_THREAD_CFG_BITMASK_HT2 0x00000004 /**< HT2. */ +#define QURT_THREAD_CFG_BITMASK_HT3 0x00000008 /**< HT3. */ +#define QURT_THREAD_CFG_BITMASK_HT4 0x00000010 /**< HT4. */ +#define QURT_THREAD_CFG_BITMASK_HT5 0x00000020 /**< HT5. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{sec:qurt_thread_cfg} */ + +#define QURT_THREAD_CFG_BITMASK_ALL 0x000000ffU /**< Select all the hardware threads. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_CFG_USE_RAM 0x00000000 /**< Use RAM. */ +#define QURT_THREAD_CFG_USE_TCM 0x00000100 /**< Use TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_BUS_PRIO_DISABLED 0 /**< Thread internal bus priority disabled. */ +#define QURT_THREAD_BUS_PRIO_ENABLED 1 /**< Thread internal bus priority enabled. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_AUTOSTACK_DISABLED 0 /**< Thread has autostack v2 feature disabled. */ +#define QURT_THREAD_AUTOSTACK_ENABLED 1 /**< Thread has autostack v2 feature enabled. */ + +/* + Macros for QuRT thread attributes. + */ +#define QURT_HTHREAD_L1I_PREFETCH 0x1 /**< Enables hardware L1 instruction cache prefetching. */ +#define QURT_HTHREAD_L1D_PREFETCH 0x2 /**< Enables hardware L1 data cache prefetching. */ +#define QURT_HTHREAD_L2I_PREFETCH 0x4 /**< Enables hardware L2 instruction cache prefetching. */ +#define QURT_HTHREAD_L2D_PREFETCH 0x8 /**< Enables hardware L2 data cache prefetching. */ +#define QURT_HTHREAD_DCFETCH 0x10 /**< Enables DC fetch to the provided virtual address. + DC fetch indicates the hardware that a data memory access is likely. + Instructions are dropped when there is high bus utilization. */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{hdr:partition_tcm} */ +/* + Below value is used to create legacy QuRT threads by default. + If a thread has this as the detach_state, the thread can be joined + on until it exits. When we are able to change default behavior of all + QuRT threads to JOINABLE (posix default), we can remove this legacy + behavior. +*/ +#define QURT_THREAD_ATTR_CREATE_LEGACY 0U /**< Create a legacy QuRT thread by default. If a thread has this as a detach state, the thread can be joined on until it exits. */ +#define QURT_THREAD_ATTR_CREATE_JOINABLE 1U /**< Create a joinable thread. */ +#define QURT_THREAD_ATTR_CREATE_DETACHED 2U /**< Create a detached thread. */ +/** @} */ /* end_addtogroup thread_macros */ + + +#define QURT_THREAD_ATTR_NAME_MAXLEN 16 /**< Maximum name length. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_RAM 0 /**< Creates threads in RAM/DDR. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_TCM 1 /**< Creates threads in TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT QURT_THREAD_ATTR_TCB_PARTITION_RAM /**< Backward compatibility. */ +#define QURT_THREAD_ATTR_PRIORITY_DEFAULT 254 /**< Priority.*/ +#define QURT_THREAD_ATTR_ASID_DEFAULT 0 /**< ASID. */ +#define QURT_THREAD_ATTR_AFFINITY_DEFAULT (-1) /**< Affinity. */ +#define QURT_THREAD_ATTR_BUS_PRIO_DEFAULT 255 /**< Bus priority. */ +#define QURT_THREAD_ATTR_AUTOSTACK_DEFAULT 0 /**< Default autostack v2 disabled thread. */ +#define QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT (-2) /**< Timetest ID. */ +#define QURT_THREAD_ATTR_STID_DEFAULT QURT_STID_DEFAULT /**< STID. */ +#define QURT_THREAD_ATTR_STID_ENABLE 1 /**< Indicate to allocate STID during thread creation. */ + +#define QURT_PRIORITY_FLOOR_DEFAULT 255U /**< Default floor. */ +/** @} */ /* end_addtogroup thread_macros */ + +// Option for suspending thread +#define QURT_THREAD_SUSPEND_SYNCHRONOUS 0x0U // bit#0 +#define QURT_THREAD_SUSPEND_ASYNCHRONOUS 0x1U // bit#0 +#define QURT_THREAD_SUSPEND_KEEP_HMX 0x0U // bit#1 +#define QURT_THREAD_SUSPEND_DETACH_HMX 0x2U // bit#1 + +// Option for resuming thread +#define QURT_THREAD_RESUME_DEFAULT 0x0 + +// Thread property IDs +#define QURT_THREAD_PROPERTY_SUSPENDABLE 0x0U +#define QURT_THREAD_PROPERTY_RESUMABLE 0x1 + +// Thread group +#define QURT_THREAD_DEFAULT_GROUP_ID 0x0U +#define QURT_THREAD_GROUP_ID_MASK 0x3FU + +/** @endcond*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup thread_types +@{ */ +/** @cond rest_reg_dist */ +typedef unsigned int qurt_cache_partition_t; /**< QuRT cache partition type. */ + +#define CCCC_PARTITION 0U /**< Use the CCCC page attribute bits to determine the main or auxiliary partition. */ +#define MAIN_PARTITION 1U /**< Use the main partition. */ +#define AUX_PARTITION 2U /**< Use the auxiliary partition. */ +#define MINIMUM_PARTITION 3U /**< Use the minimum. Allocates the least amount of cache (no-allocate policy possible) for this thread. */ +/** @endcond */ + +/** Thread ID type. */ +typedef unsigned int qurt_thread_t; + +/** @cond rest_reg_dist */ +/** Thread attributes. */ +typedef struct _qurt_thread_attr { + + char name[QURT_THREAD_ATTR_NAME_MAXLEN]; /**< Thread name. */ + unsigned char tcb_partition; /**< Indicates whether the thread TCB resides in RAM or + on chip memory (TCM). */ + unsigned char stid; /**< Software thread ID used to configure the stid register + for profiling purposes. */ + unsigned short priority; /**< Thread priority. */ + unsigned char autostack:1; /**< Autostack v2 enabled thread. */ + unsigned char group_id:6; /**< Group ID. */ + unsigned char reserved:1; /**< Reserved bits. */ + unsigned char bus_priority; /**< Internal bus priority. */ + unsigned short timetest_id; /**< Timetest ID. */ + unsigned int stack_size; /**< Thread stack size. */ + void *stack_addr; /**< Pointer to the stack address base. The range of the stack is + (stack_addr, stack_addr+stack_size-1). */ + unsigned short detach_state; /**< Detach state of the thread. */ + +} qurt_thread_attr_t; +/** @endcond */ + +/** @cond rest_reg_dist */ +/** Dynamic TLS attributes. */ +typedef struct qurt_tls_info { + unsigned int module_id; /**< Module ID of the loaded dynamic linked library. */ + unsigned int tls_start; /**< Start address of the TLS data. */ + unsigned int tls_data_end; /**< End address of the TLS RW data. */ + unsigned int tls_end; /**< End address of the TLS data. */ +}qurt_tls_info; +/** @endcond */ + +/** @} */ /* end_addtogroup thread_types */ + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_thread_attr_init + Initializes the structure used to set the thread attributes when a thread is created. + After an attribute structure is initialized, Explicity set the individual attributes in the structure + using the thread attribute operations. + + The initialize operation sets the following default attribute values: \n + - Name -- NULL string \n + - TCB partition -- QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT + - Priority -- QURT_THREAD_ATTR_PRIORITY_DEFAULT \n + - Autostack -- QURT_THREAD_ATTR_AUTOSTACK_DEFAULT \n + - Bus priority -- QURT_THREAD_ATTR_BUS_PRIO_DEFAULT \n + - Timetest ID -- QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT \n + - stack_size -- 0 \n + - stack_addr -- NULL \n + - detach state -- #QURT_THREAD_ATTR_CREATE_LEGACY \n + - STID -- #QURT_THREAD_ATTR_STID_DEFAULT + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_init (qurt_thread_attr_t *attr) +{ + + attr->name[0] = '\0'; + attr->tcb_partition = QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT; + attr->priority = QURT_THREAD_ATTR_PRIORITY_DEFAULT; + attr->autostack = QURT_THREAD_ATTR_AUTOSTACK_DEFAULT; /* Default attribute for autostack v2*/ + attr->bus_priority = QURT_THREAD_ATTR_BUS_PRIO_DEFAULT; + attr->timetest_id = (unsigned short)QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT; + attr->stack_size = 0; + attr->stack_addr = NULL; + attr->detach_state = QURT_THREAD_ATTR_CREATE_LEGACY; + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + attr->group_id = QURT_THREAD_DEFAULT_GROUP_ID; +} + +/**@ingroup func_qurt_thread_attr_set_name + Sets the thread name attribute.\n + This function specifies the name to use by a thread. + Thread names identify a thread during debugging or profiling. + Maximum name length is 16 charactes \n + @note1hang Thread names differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] name Pointer to the character string containing the thread name. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_name (qurt_thread_attr_t *attr, const char *name) +{ + strlcpy (attr->name, name, QURT_THREAD_ATTR_NAME_MAXLEN); + attr->name[QURT_THREAD_ATTR_NAME_MAXLEN - 1] = '\0'; +} + + +/**@ingroup func_qurt_thread_attr_set_tcb_partition + Sets the thread TCB partition attribute. + Specifies the memory type where a TCB of a thread is allocated. + Allocates TCBs in RAM or TCM/LPM. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] tcb_partition TCB partition. Values:\n + - 0 -- TCB resides in RAM \n + - 1 -- TCB resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_tcb_partition (qurt_thread_attr_t *attr, unsigned char tcb_partition) +{ + attr->tcb_partition = tcb_partition; +} + +/**@ingroup func_qurt_thread_attr_set_priority + Sets the thread priority to assign to a thread. + Thread priorities are specified as numeric values in the range 1 to 254, with 1 representing + the highest priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] priority Thread priority. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_priority (qurt_thread_attr_t *attr, unsigned short priority) +{ + attr->priority = priority; +} + +/**@ingroup func_qurt_thread_attr_set_detachstate + Sets the thread detach state with which thread is created. + Thread detach state is either joinable or detached; specified by the following values: + - #QURT_THREAD_ATTR_CREATE_JOINABLE \n + - #QURT_THREAD_ATTR_CREATE_DETACHED \n + + When a detached thread is created (QURT_THREAD_ATTR_CREATE_DETACHED), its thread + ID and other resources are reclaimed as soon as the thread exits. When a joinable thread + is created (QURT_THREAD_ATTR_CREATE_JOINABLE), it is assumed that some + thread waits to join on it using a qurt_thread_join() call. + By default, detached state is QURT_THREAD_ATTR_CREATE_LEGACY + If detached state is QURT_THREAD_ATTR_CREATE_LEGACY then other + thread can join before thread exits but it will not wait other thread to join. + + @note1hang For a joinable thread (QURT_THREAD_ATTR_CREATE_JOINABLE), it is very + important that some thread joins on it after it terminates, otherwise + the resources of that thread are not reclaimed, causing memory leaks. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] detachstate Thread detach state. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_detachstate (qurt_thread_attr_t *attr, unsigned short detachstate) +{ + if(detachstate == QURT_THREAD_ATTR_CREATE_JOINABLE || detachstate == QURT_THREAD_ATTR_CREATE_DETACHED){ + attr->detach_state = detachstate; + } +} + + +/**@ingroup func_qurt_thread_attr_set_timetest_id + Sets the thread timetest attribute.\n + Specifies the timetest identifier to use by a thread. + + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] timetest_id Timetest identifier value. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_thread_attr_set_timetest_id (qurt_thread_attr_t *attr, unsigned short timetest_id) +{ + attr->timetest_id = timetest_id; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute.\n + Specifies the size of the memory area to use for a call stack of a thread. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_size Size (in bytes) of the thread stack. + + @return + None. + + @dependencies + None. +*/ + +static inline void qurt_thread_attr_set_stack_size (qurt_thread_attr_t *attr, unsigned int stack_size) +{ + attr->stack_size = stack_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size2 + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute for island threads that require a higher guest OS stack size than the stack size + defined in the configuration XML.\n + Specifies the size of the memory area to use for a call stack of an island thread in User and Guest mode. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] user_stack_size Size (in bytes) of the stack usage in User mode. + @param[in] root_stack_size Size (in bytes) of the stack usage in Guest mode. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_size2 (qurt_thread_attr_t *attr, unsigned short user_stack_size, unsigned short root_stack_size) +{ + union qurt_thread_stack_info{ + unsigned int raw_size; + struct{ + unsigned short user_stack; + unsigned short root_stack; + }; + }user_root_stack_size; + user_root_stack_size.user_stack = user_stack_size; + user_root_stack_size.root_stack = root_stack_size; + + attr->stack_size = user_root_stack_size.raw_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_addr + @xreflabel{sec:set_stack_addr} + Sets the thread stack address attribute. \n + Specifies the base address of the memory area to use for a call stack of a thread. + + stack_addr must contain an address value that is 8-byte aligned. + + The thread stack address and stack size (Section @xref{sec:set_stack_size}) specify the memory area used as a + call stack for the thread. \n + @note1hang The user is responsible for allocating the memory area used for the thread + stack. The memory area must be large enough to contain the stack that the thread + creates. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_addr Pointer to the 8-byte aligned address of the thread stack. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_addr (qurt_thread_attr_t *attr, void *stack_addr) +{ + attr->stack_addr = stack_addr; +} + +/**@ingroup func_qurt_thread_attr_set_bus_priority + Sets the internal bus priority state in the Hexagon core for this software thread attribute. + Memory requests generated by the thread with bus priority enabled are + given priority over requests generated by the thread with bus priority disabled. + The default value of bus priority is disabled. + + @note1hang Sets the internal bus priority for Hexagon processor version V60 or greater. + The priority is not propagated to the bus fabric. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + + @param[in] bus_priority Enabling flag. Values: \n + - #QURT_THREAD_BUS_PRIO_DISABLED \n + - #QURT_THREAD_BUS_PRIO_ENABLED @tablebulletend + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_bus_priority ( qurt_thread_attr_t *attr, unsigned short bus_priority) +{ + attr->bus_priority = (unsigned char)bus_priority; +} + +/**@ingroup func_qurt_thread_attr_set_autostack + Enables autostack v2 feature in the thread attributes. + + When autostack is enabled by the subsystem, in the case that + an autostack enabled thread gets framelimit exception, kernel will + allocate more stack for thread and return to normal execution. + + If autostack is not enabled by the subsystem, or it is not enabled + for the thread, the framelimit exception will be fatal. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] autostack Autostack enable or disable flag. Values: \n + - #QURT_THREAD_AUTOSTACK_DISABLED \n + - #QURT_THREAD_AUTOSTACK_ENABLED @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_autostack ( qurt_thread_attr_t *attr, unsigned short autostack) +{ + attr->autostack = (unsigned char)autostack; +} +/**@ingroup qurt_thread_attr_enable_stid + Set STID in the thread attributes. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] enable_stid STID to be set. Values: \n + - #QURT_THREAD_ATTR_STID_DEFAULT (0): Default STID. \n + - #QURT_THREAD_ATTR_STID_ENABLE (1): QuRT assigns an STID that is not already in use \n + - #2 through #255 : User provided STID. @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_enable_stid ( qurt_thread_attr_t *attr, char enable_stid) +{ + if (enable_stid != '\0') { + attr->stid = enable_stid; + } + else + { + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + } +} + +/**@ingroup func_qurt_thread_attr_set_stid + Sets the stid thread attribute. + The default stid value is QURT_THREAD_ATTR_STID_DEFAULT + + @note1hang When a thread is created with non default stid , + the stid set in thread attribute will be assigned to a thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] stid Stid to be set for a thread. + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stid( qurt_thread_attr_t *attr, unsigned int stid){ + attr->stid = stid; +} + +/**@ingroup func_qurt_thread_attr_set_group_id + Sets group id in the thread attributes. + Primordial/first thread has group ID 0. + If a new thread is created without assigning group_id, it + inherits the group ID from its parent thread. + + @note1hang + 1) Group ID can only be set before creating a thread. It cannot be + changed after the thread is created. + 2) If a non-activated group_id is passed, thread creation will fail. + 3) Only a thread with Group ID #0 can set Group ID for its child threads. + 4) If thread with non-zero group ID set the group ID for its child threads, + QuRT will ingore this parameter and child threads will inherit the parent + thread's group ID. But if passed group ID is not activated, thread creation + will still fail. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] group_id Group identifier. Its valid range is 0 ~ 63 + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_group_id(qurt_thread_attr_t *attr, unsigned int group_id) +{ + attr->group_id = group_id & QURT_THREAD_GROUP_ID_MASK; +} + +/**@ingroup func_qurt_thread_set_autostack + Sets autostack enable in the TCB. + + @param[in] Pointer to UGP + + @return + None. + + @dependencies + None. +*/ + +void qurt_thread_set_autostack(void *); + + +/**@ingroup func_qurt_thread_get_name + Gets the thread name of current thread.\n + Returns the thread name of the current thread. + Thread names are assigned to threads as thread attributes, see qurt_thread_attr_set_name(). Thread names + identify a thread during debugging or profiling. + + @param[out] name Pointer to a character string, which specifies the address where the returned thread name is stored. + @param[in] max_len Maximum length of the character string that can be returned. + + @return + None. + + @dependencies + None. +*/ +void qurt_thread_get_name (char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_create + @xreflabel{hdr:qurt_thread_create} + Creates a thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + @param[in] entrypoint C function pointer, which specifies the main function of a thread. + @param[in] arg Pointer to a thread-specific argument structure + + + @return + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_thread_create (qurt_thread_t *thread_id, qurt_thread_attr_t *attr, void (*entrypoint) (void *), void *arg); + +/**@ingroup func_qurt_thread_stop + Stops the current thread, frees the kernel TCB, and yields to the next highest ready thread. + + @return + void + + @dependencies + None. + */ +void qurt_thread_stop(void); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_resume + When a demand-loading paging solution is enabled, this function + will resumes the execution of a thread that was suspended due to + a page miss. + + @param[in] thread_id Thread identifier. + + @return + #QURT_EOK -- Thread successfully resumed. \n + #QURT_EFATAL -- Resume operation failed. + + @dependencies + None. + */ +int qurt_thread_resume(unsigned int thread_id); +/** @endcond */ + +/**@ingroup func_qurt_thread_get_id + Gets the identifier of the current thread.\n + Returns the thread identifier for the current thread. + + @return + Thread identifier -- Identifier of the current thread. + + @dependencies + None. + */ +qurt_thread_t qurt_thread_get_id (void); + + +/**@ingroup func_qurt_thread_get_l2cache_partition + Returns the current value of the L2 cache partition assigned to the caller thread.\n + + @return + Value of the #qurt_cache_partition_t data type. + + @dependencies + None. + */ +qurt_cache_partition_t qurt_thread_get_l2cache_partition (void); + +/**@ingroup func_qurt_thread_set_timetest_id + Sets the timetest identifier of the current thread. + Timetest identifiers are used to identify a thread during debugging or profiling.\n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @param[in] tid Timetest identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_timetest_id (unsigned short tid); + +/**@ingroup func_qurt_thread_set_cache_partition + Sets the cache partition for the current thread. This function uses the qurt_cache_partition_t type + to select the cache partition of the current thread for the L1 Icache, L1 Dcache, and L2 cache. + + @datatypes + #qurt_cache_partition_t + + @param[in] l1_icache L1 I cache partition. + @param[in] l1_dcache L1 D cache partition. + @param[in] l2_cache L2 cache partition. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_cache_partition(qurt_cache_partition_t l1_icache, qurt_cache_partition_t l1_dcache, qurt_cache_partition_t l2_cache); + + +/**@ingroup func_qurt_thread_get_timetest_id + Gets the timetest identifier of the current thread.\n + Returns the timetest identifier of the current thread.\n + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @return + Integer -- Timetest identifier. + + @dependencies + None. + */ +unsigned short qurt_thread_get_timetest_id (void); + +/**@ingroup func_qurt_thread_exit + @xreflabel{sec:qurt_thread_exit} + Stops the current thread, awakens threads joined to it, then destroys the stopped + thread. + + Threads that are suspended on the current thread (by performing a thread join + Section @xref{sec:thread_join}) are awakened and passed a user-defined status value + that indicates the status of the stopped thread. + + @note1hang Exit must be called in the context of the thread to stop. + + @param[in] status User-defined thread exit status value. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_exit(int status); + +/**@ingroup func_qurt_thread_join + @xreflabel{sec:thread_join} + Waits for a specified thread to finish; the specified thread is another thread within + the same process. + The caller thread is suspended until the specified thread exits. When the unspecified thread + exits, the caller thread is awakened. \n + @note1hang If the specified thread has already exited, this function returns immediately + with the result value #QURT_ENOTHREAD. \n + @note1cont Two threads cannot call qurt_thread_join to wait for the same thread to finish. + If this occurs, QuRT generates an exception (see Section @xref{sec:exceptionHandling}). + + @param[in] tid Thread identifier. + @param[out] status Destination variable for thread exit status. Returns an application-defined + value that indicates the termination status of the specified thread. + + @return + #QURT_ENOTHREAD -- Thread has already exited. \n + #QURT_EOK -- Thread successfully joined with valid status value. + + @dependencies + None. + */ +int qurt_thread_join(unsigned int tid, int *status); + +/**@ingroup qurt_thread_detach + @xreflabel{sec:thread_detach} + Detaches a joinable thread. The specified thread is another thread within the + same process. Create the thread as a joinable thread; only joinable threads + can be detached. + If a joinable thread is detached, it finishes execution and exits. + + @param[in] tid Thread identifier. + + @return + #QURT_ENOTHREAD -- Thread specifed by TID does not exist. \n + #QURT_EOK -- Thread successfully detached. + + @dependencies + None. + */ +int qurt_thread_detach(unsigned int tid); + + +/**@ingroup func_qurt_thread_get_priority + Gets the priority of the specified thread. \n + Returns the thread priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. \n + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + + @return + -1 -- Invalid thread identifier. \n + 1 through 254 -- Thread priority value. + + @dependencies + None. + */ +int qurt_thread_get_priority (qurt_thread_t threadid); + +/**@ingroup func_qurt_thread_set_priority + Sets the priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. For more + information, see Section @xref{sec:AppDev}. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + @param[in] newprio New thread priority value. + + @return + 0 -- Priority successfully set. \n + -1 -- Invalid thread identifier. \n + + @dependencies + None. + */ +int qurt_thread_set_priority (qurt_thread_t threadid, unsigned short newprio); + + + +/**@ingroup func_qurt_thread_attr_get + Gets the attributes of the specified thread. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[out] attr Pointer to the destination structure for thread attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid argument. + + @dependencies + None. + */ +int qurt_thread_attr_get (qurt_thread_t thread_id, qurt_thread_attr_t *attr); + + + +/**@ingroup func_qurt_thread_get_tls_base + Gets the base address of thread local storage (TLS) of a dynamically loaded module + for the current thread. + + @datatypes + #qurt_tls_info + + @param[in] info Pointer to the TLS information for a module. + + @return + Pointer to the TLS object for the dynamically loaded module.\n + NULL -- TLS information is invalid. + + @dependencies + None. + */ +void * qurt_thread_get_tls_base(qurt_tls_info* info); + +/**@ingroup func_qurt_thread_pktcount_get + Gets the PKTCOUNT of a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + PKTCOUNT + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_get (qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_pktcount_set + Sets the PKTCOUNT for the current QuRT thread. + + @return + Value to which pktcount is set. + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_set (long long int); + +/**@ingroup func_qurt_thread_stid_get + Gets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + STID + + @dependencies + None. + */ + +char qurt_thread_stid_get(qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_stid_get2 + Returns the set stid for a thread + + @param[in] thread_id thread identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - success + QURT_ENOTALLOWED - operation not allowed for a thread + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_thread_stid_get2(unsigned int thread_id, unsigned int *stid); + +/**@ingroup func_qurt_thread_stid_set + Sets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] stid Thread identifier. + + @return + #QURT_EOK -- STID set created. \n + #QURT_EFAILED -- STID not set. + + @dependencies + None. + */ + +int qurt_thread_stid_set(char stid); + +/**@ingroup qurt_thread_stid_set2 + Sets the stid for a specified thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[in] stid Stid to be set for a thread. + + @return + QURT_EOK -- Success + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_EVAL -- Failure because of invalid inputs. + + @dependencies + None. +*/ +int qurt_thread_stid_set2(unsigned int thread_id, unsigned int stid); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_get_running_ids + Returns the thread IDs of the running threads in the system; use only during fatal error handling. + + @datatypes + #qurt_thread_t + + @param[in,out] * Array of thread identifier of size #QURT_MAX_HTHREAD_LIMIT + 1. + + @return + #QURT_EINVALID -- Incorrect argument \n + #QURT_ENOTALLOWED -- API not called during error handling \n + #QURT_EOK -- Success, returns a NULL-terminated array of thread_id + + @dependencies + None. + */ +int qurt_thread_get_running_ids(qurt_thread_t *); +/** @endcond */ + + +/**@ingroup func_qurt_thread_get_thread_id + Gets the thread identifier of the thread with the matching name in the same process + of the caller. + + @datatypes + #qurt_thread_t + + @param[out] thread_id Pointer to the thread identifier. + @param[in] name Pointer to the name of the thread. + + @return + #QURT_EINVALID -- No thread with matching name in the process of the caller \n + #QURT_EOK -- Success + + @dependencies + None. + */ +int qurt_thread_get_thread_id (qurt_thread_t *thread_id, char *name); + +/**@ingroup func_qurt_sleep + Suspends the current thread for the specified amount of time. + + @note1hang Because QuRT timers are deferrable, this call is guaranteed to block + at least for the specified amount of time. If power-collapse is + enabled, the maximum amount of time this call can block depends on + the earliest wakeup from power-collapse past the specified duration. + + @param[in] duration Duration (in microseconds) for which the thread is suspended. + + @return + None. + + @dependencies + None. + */ +void qurt_sleep (unsigned long long int duration); + + +/**@ingroup func_qurt_system_set_priority_floor + Sets a priority floor to move threads with thread priority lower than the floor out of the running state. + Running threads with thread priority lower than the priority floor are moved into the kernel ready queue, and they + are not scheduled to run when the thread priority is lower than the floor. + Later the caller should reset the priority floor back to the default value of QURT_PRIORITY_FLOOR_DEFAULT. + Threads in the kernel ready queue are scheduled to run when the thread priority is higher than the floor. + + The priority floor is set and associated to the user process of the caller. When the caller gets into QuRTOS and + sets a new floor, the new floor is associated to its original user process, not the QuRTOS process. + The floor associated to the user process is reset when the user process exits or is killed, but not at the time + when the user thread of the caller exits. + + The priority floor cannot be set to a priority higher than the thread priority of the caller. + + The priority floor cannot be set to a priority lower than the default #QURT_PRIORITY_FLOOR_DEFAULT system floor. + + This function is not supported in Island mode. + + After the system floor is set above QURT_PRIORITY_FLOOR_DEFAULT, power collapse is skipped, and sleep task + is not scheduled to run. + + @param[in] priority_floor Priority floor. + + @return + #QURT_EOK -- Success \n + #QURT_ENOTALLOWED -- Floor setting is not allowed + + @dependencies + None. + */ +int qurt_system_set_priority_floor (unsigned int priority_floor); + + +/**@ingroup func_qurt_thread_suspend_thread + Suspend a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent process. + After the target thread is suspended, the kernel will not schedule it to run until it is resumed later. + + If the target thread is set as non-suspendable, this function call returns an error without suspending + the target thread. + + If the target thread is already suspended, this function call returns success to confirm + the target thread suspend. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + suspending the target thread. + + If the target thread is running in the guest OS/root process via a QDI call, this function call does not suspend + the target thread in guest OS, but marks the target thread as suspend-pending. The target thread is + suspended when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success even with the #QURT_THREAD_SUSPEND_SYNCHRONOUS option, while the target + thread can runn in the guest OS, and is suspended when exiting the guest OS. + + QuRT debug monitor threads that are in a user process are non-suspendable. This function does not suspend + those threads. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, multiple options can be ORed. \n + #QURT_THREAD_SUSPEND_SYNCHRONOUS (default) -- set to synchronous function call, + the function returns after the thread is completely suspended.\n + #QURT_THREAD_SUSPEND_ASYNCHRONOUS -- set to asynchronous function call, the function returns + after the kernel acts to suspend the target thread. The target thread + might still be running before it is completely suspended. \n + #QURT_THREAD_SUSPEND_KEEP_HMX (default) -- keep the HMX attachment on the target thread + if it locks the HMX with qurt_hmx_lock(). In this case, the HMX cannot be re-used by other threads. \n + #QURT_THREAD_SUSPEND_DETACH_HMX -- detach HMX from the target thread if it locks the HMX with qurt_hmx_lock(). + Later when the target thread resumes, the HMX is re-attached to the thread. Note that, this option is only + supported for the caller from the same user process of the target thread, not for a caller from the parent + process of the target thread, or other processes. With the HMX detach option, Qurt does not save the HMX + context. Thus, the HMX context state will be lost. It is the responsibility of caller to ensure HMX operations + and its context state saving when calling qurt_thread_suspend_thread() with the HMX detach option. + If a thread from another process uses this detach option, QURT_EHMXNOTDETACHABLE will be returned; in this + case, if the caller is qualified to suspend the target thread, the target thread will be moved to suspended + state without HMX detached. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in secure process/CPZ process. + #QURT_EHMXNOTDETACHABLE -- Failure because HMX is not detachable from the target thread. + + @dependencies + None. + */ +int qurt_thread_suspend_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_resume_thread + Resume a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent + process. After the target thread resumes, the kernel scheduler can schedule the thread to run based on + the thread priority. + + There is an option argument in this function, with only one default option as of now, + QURT_THREAD_RESUME_DEFAULT: resume the target thread in default way. + + By default, this is an asynchronous function. The function returns after kernel moves the + target thread from suspended state to runnable state. The thread is scheduled to run based on its + thread priority. + + If the target thread is set as non-resumable, this function call does not resume the target thread. + + If the target thread has already resumed, this function confirms that the target thread resumes + by returning success. + + If the target thread is in a secure user process or CPZ process, this function call returns an error without + resuming the operation. + + If the target thread runs in the guest OS/root process via a QDI call, this function call clears the mark of + suspend-pending on the target thread, and the target thread is not suspended when it exits the + guest OS. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, #QURT_THREAD_RESUME_DEFAULT, which resumes the target thread. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + #QURT_EHMXNOTAVAIL -- Failure because when resume a HMX thread, the HMX is not available/free for the HMX thread resume. + + @dependencies + None. + */ +int qurt_thread_resume_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_set_thread_property + Set a QuRT thread property with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be from the same user process of the target thread, or from its parent process. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + changing the property of the target thread. + + @param[in] thread_id Thread identifier \n + @param[in] property_id Thread property identifier \n + #QURT_THREAD_PROPERTY_SUSPENDABLE -- thread is suspendable. Default is TRUE. \n + #QURT_THREAD_PROPERTY_RESUMEABLE -- thread is resumable. Default is TRUE + @param[in] value Proper value: \n + TRUE(1) -- TRUE for the property \n + FALSE(0) -- FALSE for the property + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_thread_set_thread_property( unsigned int thread_id, unsigned int property_id, unsigned int value ); + +/**@ingroup func_qurt_thread_get_group_id + Get the group id of the thread specified by thread_id.\n + + @param[in] thread_id Thread identifier + @param[out] group_id Pointer to the variable of group identifier + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Thread id is invalid, or the process has no groups enabled \n + #QURT_ENOTALLOWED -- Operation is not allowed \n + + @dependencies + None. +*/ +int qurt_thread_get_group_id(qurt_thread_t thread_id, unsigned int* group_id); + +#endif /* __ASSEMBLER__ */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread_context.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread_context.h new file mode 100755 index 0000000000000..bab09deec8889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_thread_context.h @@ -0,0 +1,234 @@ +#ifndef QURT_THREAD_CONTEXT_H +#define QURT_THREAD_CONTEXT_H +/** + @file qurt_thread_context.h + @brief Kernel thread context structure + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond internal_only */ + +#define THREAD_ITERATOR_END ((qurt_thread_t)(-1)) /**< Thread iterator is complete. */ + + +/**@ingroup func_qurt_thread_iterator_create +Gives the ability to the caller to enumerate threads in the system. + +@return +Handle of the newly created iterator must be passed for +subsequent operations on the iterator. + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_create(void) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_OS_THREAD_ITERATOR_CREATE); +} + +/**@ingroup func_qurt_thread_iterator_next +Iterates over the list of threads in the system. + +@datatypes +#qurt_thread_t + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#THREAD_ITERATOR_END -- iterator has reached the end of the thread list. \n +Other values indicate a valid thread_id. + +@dependencies +None. +*/ +static inline qurt_thread_t qurt_thread_iterator_next(int iter) +{ + return (qurt_thread_t)qurt_qdi_handle_invoke(iter, QDI_OS_THREAD_ITERATOR_NEXT); +} + +/**@ingroup func_qurt_thread_iterator_destroy +Cleans up thread iterator resources. + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#QURT_EOK -- Successful completion of operation \n +#QURT_EFATAL -- Invalid handle passed + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_destroy(int iter) +{ + return qurt_qdi_close(iter); +} + +/**@ingroup func_qurt_thread_context_get_tname +Gets the name of the thread from the specified thread ID. + +@param[in] thread_id Thread for which name is returned. +@param[in,out] name Pointer to the local buffer where name is copied back. +@param[in] max_len Size of the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_tname(unsigned int thread_id, char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_context_get_prio +Gets the priority for the specified thread. + +@param[in] thread_id Thread for which priority is returned. +@param[in,out] prio Pointer to the local variable where priority is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_prio(unsigned int thread_id, unsigned char *prio); + +/**@ingroup func_qurt_thread_context_get_pcycles +Gets pcycles for the specified thread. + +@param[in] thread_id Thread for which processor cycles are returned. +@param[in,out] pcycles Pointer to the local variable where processor cycles are written. + +@return +#QURT_EOK -- Success \n +Failure otherwise. + +@dependencies +None. +*/ +int qurt_thread_context_get_pcycles(unsigned int thread_id, unsigned long long int *pcycles); + +/**@ingroup func_qurt_thread_context_get_stack_base +Gets the stack base address for the specified thread. + +@param[in] thread_id Thread for which stack base address is returned. +@param[in,out] sbase Pointer to the local variable where stack base address is written. + +@return +QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_base(unsigned int thread_id, unsigned int *sbase); + +/**@ingroup func_qurt_thread_context_get_stack_size +Gets the stack size for the specified thread. + +@param[in] thread_id Thread for which stack size is returned. +@param[in,out] ssize Pointer to the local variable where stack size is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_size(unsigned int thread_id, unsigned int *ssize); + +/**@ingroup func_qurt_thread_context_get_pid +Gets the process ID for the specified thread. + +@param[in] thread_id Thread for which process ID is returned. +@param[in,out] pid Pointer to the local variable where process id is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pid(unsigned int thread_id, unsigned int *pid); + +/**@ingroup func_qurt_thread_context_get_pname +Gets the process name for the specified thread. + +@param[in] thread_id Represents the thread for which process name is returned. +@param[in, out] name Pointer to the local buffer where process name is copied back. +@param[in] len Length allocated to the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pname(unsigned int thread_id, char *name, unsigned int len); + +/** @addtogroup thread_types +@{ */ +/** Structure that defines how TCB is interpreted to crash dump tools.*/ +/* Keys are defined in consts.h */ +struct qurt_debug_thread_info { +/** @cond */ + char name[QURT_MAX_NAME_LEN]; /**< Name of the thread. */ + struct { + unsigned key; + unsigned val; + } os_info[40]; + unsigned gen_regs[32]; /**< General mode registers. */ + unsigned user_cregs[32]; /**< User mode registers. */ + unsigned guest_cregs[32]; /**< Guest mode registers. */ + unsigned monitor_cregs[64]; /**< Monitor mode registers. */ +/** @endcond */ +}; /* should add up to 1K */ +/** @} */ /* end_addtogroup thread_types */ + + +/**@ingroup func_qurt_system_tcb_dump_get +Cleans up thread iterator resources. + +@datatypes +#qurt_thread_t + +@param[in] thread_id Thread on which the operation must be performed. +@param[in, out] ptr Pointer to the local buffer where contents are written. +@param[in] size Size of the debug thread information structure obtained by calling + qurt_system_tcb_dump_get_size(). + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_system_tcb_dump_get(qurt_thread_t thread_id, void *ptr, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_CONTEXT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_timer.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_timer.h new file mode 100755 index 0000000000000..7bdfdb8f3c3df --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_timer.h @@ -0,0 +1,560 @@ +#ifndef QURT_TIMER_H +#define QURT_TIMER_H +/** + @file qurt_timer.h + @brief Prototypes of qurt_timer API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include "qurt_anysignal.h" +#include "qurt_signal2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@addtogroup timer_const_macros +@{ */ +/** + Default values. +*/ +/** @xreflabel{hdr:QURT_TIMER_ONESHOT}*/ +#define QURT_TIMER_DEFAULT_TYPE QURT_TIMER_ONESHOT /**< One shot.*/ +#define QURT_TIMER_DEFAULT_DURATION 1000uL /**< Default duration. */ +#define QURT_TIMER_DEFAULT_EXPIRY 0uL /**< Default expiration. */ + +/** + Conversion from microseconds to timer ticks. + */ +#define QURT_TIMER_TIMETICK_FROM_US(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_TIMER_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** Minimum microseconds value is 100 microseconds (sleep timer).*/ +#define QURT_TIMER_MIN_DURATION 100uL + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_TIMER_MAX_DURATION QURT_SYSCLOCK_MAX_DURATION + +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_TIMER_MAX_DURATION_TICKS QURT_SYSCLOCK_MAX_DURATION_TICKS + +/** + Sleep timer error margin for Qtimer is 1,000 ticks ~52 us. +*/ +#define QURT_TIMETICK_ERROR_MARGIN QURT_SYSCLOCK_ERROR_MARGIN + +/* + qurt_timer group defines. +*/ +#define QURT_TIMER_MAX_GROUPS 5U /**< Maximum groups.*/ +#define QURT_TIMER_DEFAULT_GROUP 0U /**< Default groups. */ +/** @} */ /* end_addtogroup timer_const_macros */ + +/** @addtogroup timer_types +@{ */ +/** + QuRT timer types. + */ +typedef enum +{ + QURT_TIMER_ONESHOT = 0, /**< One shot.*/ + /** @xreflabel{hdr:QURT_TIMER_PERIODIC}*/ + QURT_TIMER_PERIODIC /**< Periodic. */ +} qurt_timer_type_t; + + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT timer type.*/ +typedef unsigned int qurt_timer_t; + +/** QuRT timer duration type. */ +typedef unsigned long long qurt_timer_duration_t; + +/** QuRT timer time type. */ +typedef unsigned long long qurt_timer_time_t; + +typedef void (*pfn_t)(void); +/** QuRT timer attribute type. */ +typedef struct +{ + /** @cond */ + unsigned int magic; /**< Magic number to verify the qmsgq_attr_t pointer. */ + + qurt_timer_duration_t duration; /**< Specifies the duration of the new timer. */ + + qurt_timer_time_t expiry; /**< Specifies the absolute expiry of the new timer. */ + + qurt_timer_duration_t remaining; /**< Specifies the remaining time of an active timer. */ + + qurt_timer_type_t type; /**< Specifies the timer type; only #QURT_TIMER_ONESHOT and + #QURT_TIMER_PERIODIC are supported. */ + + unsigned int group; /**< Group number of the timer; the criterion used to disable or enable the set + of timers. */ + pfn_t pFn; /**< Callback other than the signal set */ + /** @endcond */ +} +qurt_timer_attr_t; + +/** @} */ /* end_addtogroup timer_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_timer_stop + @xreflabel{sec:qurt_timer_stop} + Stops a running timer. + The timer must be a one-shot timer. + + @note1hang Restart stopped timers with the timer restart operation, + see Section @xref{sec:qurt_timer_restart}. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one shot timer. \n + #QURT_EMEM -- Out of memory error. + + @dependencies + None. + */ +int qurt_timer_stop (qurt_timer_t timer); + +/**@ingroup func_qurt_timer_restart + @xreflabel{sec:qurt_timer_restart} + Restarts a stopped timer with the specified duration. The timer must be a one-shot timer. + Timers stop after they have expired or after they are explicitly stopped with qurt_timer_stop(). + A restarted timer expires after the specified duration, the starting time is when the function is called. + + @note1hang Timers stop after they have expired or after they are explicitly + stopped with the timer stop operation, see Section @xref{sec:qurt_timer_stop}. + + @datatypes + #qurt_timer_t \n + #qurt_timer_duration_t + + @param[in] timer Timer object. + @param[in] duration Timer duration (in microseconds) before the restarted timer + expires again. + The valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one-shot timer. \n + #QURT_EMEM -- Out-of-memory error. + + @dependencies + None. + */ +int qurt_timer_restart (qurt_timer_t timer, qurt_timer_duration_t duration); + + +/**@ingroup func_qurt_timer_create + Creates a timer.\n + Allocates and initializes a timer object, and starts the timer. + + @note1hang A timer event handler must be defined to wait on the specified signal + to handle the timer event. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t \n + #qurt_anysignal_t + + @param[out] timer Pointer to the created timer object. + @param[in] attr Pointer to the timer attribute structure. + @param[in] signal Pointer to the signal object set when timer expires. + @param[in] mask Signal mask, which specifies the signal to set in the signal object when the + time expires. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to create the timer. \n + #QURT_EINVALID -- One of the arguments in the attr field is invalid. \n + Other error code -- Operation failed. \n + + @dependencies + None. + */ +int qurt_timer_create (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_anysignal_t *signal, unsigned int mask); + +int qurt_timer_create_sig2 (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_timer_attr_init + Initializes the specified timer attribute structure with default attribute values: \n + - Timer duration -- #QURT_TIMER_DEFAULT_DURATION (Section @xref{dox:timers}) \n + - Timer type -- #QURT_TIMER_ONESHOT \n + - Timer group -- #QURT_TIMER_DEFAULT_GROUP + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_init(qurt_timer_attr_t *attr); + + +/*Tech Comm note: removed qurt_timer_attr_set_pfn from documentation 9/10/2020 +@ingroup func_qurt_timer_attr_set_pfn + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + @param[in] pFn pFn. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_pfn(qurt_timer_attr_t *attr, pfn_t pFn); + + +/**@ingroup func_qurt_timer_attr_set_duration + Sets the timer duration in the specified timer attribute structure.\n + + The timer duration specifies the interval (in microseconds) between the creation of the + timer object and the generation of the corresponding timer event. + + The timer duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). Otherwise, the set operation is ignored. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] duration Timer duration (in microseconds). + Valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_attr_set_expiry + Sets the absolute expiry time in the specified timer attribute structure.\n + The timer expiry specifies the absolute time (in microseconds) of the generation of the + corresponding timer event.\n + Timer expiries are relative to when the system first began executing. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_time_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] time Timer expiry. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_expiry(qurt_timer_attr_t *attr, qurt_timer_time_t time); + +/**@ingroup func_qurt_timer_attr_get_duration + Gets the timer duration from the specified timer attribute structure. + The value returned is the duration that was originally set for the timer. + + @note1hang This function does not return the remaining time of an active timer; + use qurt_timer_attr_get_remaining() to get the remaining time. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attributes object + @param[out] duration Pointer to the destination variable for timer duration. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t *duration); + +/**@ingroup func_qurt_timer_attr_get_remaining + Gets the timer remaining duration from the specified timer attribute structure. \n + + The timer remaining duration indicates (in microseconds) how much time remains before + the generation of the next timer event on the corresponding timer. + In most cases this function assumes that the timer attribute structure was obtained by + calling qurt_timer_get_attr(). + + @note1hang This attribute is read-only and thus has no set operation defined for it. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attribute object. + @param[out] remaining Pointer to the destination variable for remaining time. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_remaining(qurt_timer_attr_t *attr, qurt_timer_duration_t *remaining); + +/**@ingroup func_qurt_timer_attr_set_type + Sets the timer type in the specified timer attribute structure. + + The timer type specifies the functional behavior of the timer: \n + - A one-shot timer (#QURT_TIMER_ONESHOT) waits for the specified timer duration + and then generates a single timer event. After this the timer is nonfunctional. \n + - A periodic timer (#QURT_TIMER_PERIODIC) repeatedly waits for the specified + timer duration and then generates a timer event. The result is a series of timer + events with interval equal to the timer duration. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] type Timer type. Values are: \n + - #QURT_TIMER_ONESHOT -- One-shot timer. \n + - #QURT_TIMER_PERIODIC -- Periodic timer. @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_type(qurt_timer_attr_t *attr, qurt_timer_type_t type); + +/**@ingroup func_qurt_timer_attr_get_type + Gets the timer type from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] type Pointer to the destination variable for the timer type. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_type(qurt_timer_attr_t *attr, qurt_timer_type_t *type); + +/**@ingroup func_qurt_timer_attr_set_group + Sets the timer group identifier in the specified timer attribute structure.\n + The timer group identifier specifies the group that the timer belongs to. Timer groups are + used to enable or disable one or more timers in a single operation. \n + The timer group identifier value must be between 0 and (#QURT_TIMER_MAX_GROUPS - 1). + See Section @xref{dox:timers}. + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the timer attribute object. + @param[in] group Timer group identifier; + Valid range is 0 to (#QURT_TIMER_MAX_GROUPS - 1). + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_group(qurt_timer_attr_t *attr, unsigned int group); + +/**@ingroup func_qurt_timer_attr_get_group + Gets the timer group identifier from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] group Pointer to the destination variable for the timer group identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_group(qurt_timer_attr_t *attr, unsigned int *group); + +/**@ingroup func_qurt_timer_get_attr + @xreflabel{hdr:qurt_timer_get_attr} + Gets the timer attributes of the specified timer when it was created. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t + + @param[in] timer Timer object. + @param[out] attr Pointer to the destination structure for timer attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_get_attr(qurt_timer_t timer, qurt_timer_attr_t *attr); + +/**@ingroup func_qurt_timer_delete + Deletes the timer.\n + Destroys the specified timer and deallocates the timer object. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_delete(qurt_timer_t timer); + +/**@ingroup func_qurt_timer_sleep + Suspends the current thread for the specified amount of time. + The sleep duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). + + @datatypes + #qurt_timer_duration_t + + @param[in] duration Interval (in microseconds) between when the thread is suspended + and when it is re-awakened. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to perform the operation. + + @dependencies + None. + */ + +int qurt_timer_sleep(qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_group_disable + Disables all timers that are assigned to the specified timer group. + If a specified timer is already disabled, ignore it. + If a specified timer is expired, do not process it. + If the specified timer group is empty, do nothing. + + @note1hang When a timer is disabled its remaining time does not change, thus it + cannot generate a timer event. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_disable (unsigned int group); + +/**@ingroup func_qurt_timer_group_enable + Enables all timers that are assigned to the specified timer group. + If a specified timer is already enabled, ignore it. + If a specified timer is expired, process it. + If the specified timer group is empty, do nothing. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_enable (unsigned int group); + + +/** + Notifies the timer server recovery from power collapse. The server + must account for any missed interrupts during power collapse. + */ +void qurt_timer_recover_pc (void); + +/** + Determines whether the Qtimer is initialized. + + @return + 0 -- Not initialized. \n + Nonzero -- Initialized. + */ +static inline int qurt_timer_is_init (void) {return 1;} + +/**@ingroup func_qurt_timer_get_ticks + Gets current ticks. The ticks are accumulated since the RTOS + has started. Each tick is equal to a single timer clock + cycle, where the frequency is 32 KHz on RGPT or 19.2 MHz on Qtimer. + + @return + Ticks since system started. + */ +unsigned long long qurt_timer_get_ticks (void); + +#define qurt_timer_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TIMER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tlb.h new file mode 100755 index 0000000000000..b1b2d261d31c0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tlb.h @@ -0,0 +1,215 @@ +#ifndef QURT_TLB_H +#define QURT_TLB_H + +/** + @file qurt_tlb.h + @brief Prototypes of TLB API + The TLB APIs allow explicit control of the portion of TLB between TLB_first_replaceble and TLB_LAST_REPLACEABLE. + Both are nonconfigurable for the time being. This portion of TLB is permanently assigned/locked unless manually removed + by qurt_tlb_remove. Implementation does not change depending on the configuration, such as whether CONFIG_STATIC is set or not. + In CONFIG_STATIC=y, TLB_LAST_REPLACEABLE is set to the last TLB index, which indicates that the entire TLB is permanently + assigned and is not backed up by page table (page table does not exist). TLB indicies are maintained through a 64-bit bitmask. + A new entry is placed in the first available slot. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tlb_entry_create + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (such as if the address is not aligned with the + size), the entry is created and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the ASID argument to -1. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr Physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry is not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry is not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry is not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_t paddr, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_create_64 + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (the address is not aligned with the + size), the entry is not created, and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the asid argument to -1. + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr_64 64-bit physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry was not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry was not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry was not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create_64 (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_delete + Deletes the specified TLB entry from the TLB of the Hexagon processor. + If the specified entry does not exist, no deletion occurs and an error result is returned. + + @param[in] entry_id TLB entry identifier. + + @return + #QURT_EOK -- TLB entry successfully deleted. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_delete (unsigned int entry_id); + +/**@ingroup func_qurt_tlb_entry_query + Searches for the specified TLB entry in the TLB of the Hexagon processor. + If the TLB entry is found, its entry identifier is returned. + + @datatypes + #qurt_addr_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_query (unsigned int *entry_id, qurt_addr_t vaddr, int asid); + +/**@ingroup func_qurt_tlb_entry_set + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[in] entry 64-bit TLB entry to store. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set (unsigned int entry_id, unsigned long long int entry); + +/**@ingroup func_qurt_tlb_entry_get + Gets the TLB entry. \n + Returns the specified 64-bit TLB entry in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[out] entry 64-bit TLB entry. + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_get (unsigned int entry_id, unsigned long long int *entry); + +/**@ingroup func_qurt_tlb_get_pager_physaddrs + Searches the TLB of the Hexagon processor, and returns all physical addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_phys_addrs Pointer to the return array of pager physical addresses. + + @return + Integer -- Number of addresses returned in array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_physaddr(unsigned int** pager_phys_addrs); + +/**@ingroup func_qurt_tlb_get_pager_virtaddr + Searches the TLB of the Hexagon processor, and returns all virtual addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_virt_addrs Pointer to the return array of pager virtual addresses. + + @return + Integer -- Number of addresses returned in the array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_virtaddr(unsigned int** pager_virt_addrs); + + +/**@ingroup func_qurt_tlb_entry_set2 + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. An additional option can be passed + to lock the TLB entry in the TLB of the Hexagon processor. + + @param[in] id TLB entry identifier. + @param[in] tlb 64-bit TLB entry to store. + @param[in] lock Nonzero value indicates that the TLB entry must be locked in the hardware TLB. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set2(unsigned id, unsigned long long tlb, unsigned lock); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLB_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tls.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tls.h new file mode 100755 index 0000000000000..6ec3b39ff5cb0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_tls.h @@ -0,0 +1,100 @@ +#ifndef QURT_TLS_H +#define QURT_TLS_H +/** + @file qurt_tls.h + @brief Prototypes of TLS APIs + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tls_create_key + @xreflabel{sec:tls_create_key} + Creates a key for accessing a thread local storage data item.\n + Subsequent get and set operations use the key value. + + @note1hang The destructor function performs any clean-up operations needed by a thread + local storage item when its containing thread is deleted (Section @xref{sec:qurt_thread_exit}). + + @param[out] key Pointer to the newly created thread local storage key value. + @param[in] destructor Pointer to the key-specific destructor function. Passing NULL + specifies that no destructor function is defined for the key. + + @return + #QURT_EOK -- Key successfully created. \n + #QURT_ETLSAVAIL -- No free TLS key available. + + @dependencies + None. + */ +int qurt_tls_create_key (int *key, void (*destructor)(void *)); + +/**@ingroup func_qurt_tls_set_specific + Stores a data item to thread local storage along with the specified key. + + @param[in] key Thread local storage key value. + @param[in] value Pointer to user data value to store. + + @return + #QURT_EOK -- Data item successfully stored. \n + #QURT_EINVALID -- Invalid key. \n + #QURT_EFAILED -- Invoked from a non-thread context. + */ +int qurt_tls_set_specific (int key, const void *value); + +/**@ingroup func_qurt_tls_get_specific + Loads the data item from thread local storage. \n + Returns the data item that is stored in thread local storage with the specified key. + The data item is always a pointer to user data. + + @param[in] key Thread local storage key value. + + @return + Pointer -- Data item indexed by key in thread local storage. \n + 0 (NULL) -- Key out of range. + + @dependencies + None. + */ +void * __attribute__((section(".text.qurt_tls_get_specific "))) qurt_tls_get_specific (int key); + + +/**@ingroup func_qurt_tls_delete_key + Deletes the specified key from thread local storage. + + @note1hang Explicitly deleting a key does not execute any destructor function that is + associated with the key (Section @xref{sec:tls_create_key}). + + @param[in] key Thread local storage key value to delete. + + @return + #QURT_EOK -- Key successfully deleted. \n + #QURT_ETLSENTRY -- Key already free. + + @dependencies + None. + */ +int qurt_tls_delete_key (int key); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_trace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_trace.h new file mode 100755 index 0000000000000..541f8f1d34bf6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_trace.h @@ -0,0 +1,317 @@ +#ifndef QURT_TRACE_H +#define QURT_TRACE_H +/** + @file qurt_trace.h + @brief Prototypes of system call tracing helpers API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + GLOBAL VARIABLES +=============================================================================*/ +/** @cond internal_only */ +/** @addtogroup etm_macros +@{ */ +/* ETM trace types. */ +#define QURT_ETM_TYPE_PC_ADDR (1U<<0) /**< PC address.*/ +#define QURT_ETM_TYPE_MEMORY_ADDR (1U<<1) /**< Memory address. */ +#define QURT_ETM_TYPE_TESTBUS (1U<<2) /**< Test bus. */ +#define QURT_ETM_TYPE_CYCLE_ACCURATE (1U<<3) /**< Cycle accurate. */ +#define QURT_ETM_TYPE_CYCLE_COARSE (1U<<4) /**< Cycle coarse. */ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR) /**< PC and memory address. */ +#define QURT_ETM_TYPE_PC_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC address and test bus. */ +#define QURT_ETM_TYPE_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< Memory address and test bus.*/ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC, memory address, and test bus. */ + +/* ETM routes. */ +#define QURT_ETM_ROUTE_TO_QDSS 0U /**< ETM route to QDSS. */ +#define QURT_ETM_ROUTE_TO_Q6ETB 1U /**< ETM route to Q6ETB. */ + +/* ETM filters. */ +#define QURT_ETM_TRACE_FILTER_ALL_DEFAULT 0U /*< Filter all as default. */ +#define QURT_ETM_TRACE_FILTER_HNUM0 (1U<<0) /*< Filter HNUM0. */ +#define QURT_ETM_TRACE_FILTER_HNUM1 (1U<<1) /*< Filter HNUM1. */ +#define QURT_ETM_TRACE_FILTER_HNUM2 (1U<<2) /*< Filter HNUM2. */ +#define QURT_ETM_TRACE_FILTER_HNUM3 (1U<<3) /*< Filter HNUM3. */ +#define QURT_ETM_TRACE_FILTER_HNUM4 (1U<<4) /*< Filter HNUM4. */ +#define QURT_ETM_TRACE_FILTER_HNUM5 (1U<<5) /*< Filter HNUM5. */ +#define QURT_ETM_TRACE_FILTER_HNUM6 (1U<<6) /*< Filter HNUM6. */ +#define QURT_ETM_TRACE_FILTER_HNUM7 (1U<<7) /*< Filter HNUM7. */ +#define QURT_ETM_TRACE_FILTER_HNUM8 (1U<<8) /*< Filter HNUM8. */ +#define QURT_ETM_TRACE_FILTER_HNUM9 (1U<<9) /*< Filter HNUM9. */ +#define QURT_ETM_TRACE_FILTER_HNUM10 (1U<<10) /*< Filter HNUM10. */ +#define QURT_ETM_TRACE_FILTER_HNUM11 (1U<<11) /*< Filter HNUM11. */ +#define QURT_ETM_TRACE_FILTER_HNUM12 (1U<<12) /*< Filter HNUM12. */ +#define QURT_ETM_TRACE_FILTER_HNUM13 (1U<<13) /*< Filter HNUM13. */ +#define QURT_ETM_TRACE_FILTER_HNUM14 (1U<<14) /*< Filter HNUM14. */ +#define QURT_ETM_TRACE_FILTER_HNUM15 (1U<<15) /*< Filter HNUM15. */ +#define QURT_ETM_TRACE_FILTER_ALL QURT_ETM_TRACE_FILTER_ALL_DEFAULT + +#define QURT_ETM_TRACE_FILTER_CLUSTER0 (1<<16) /*< Filter trace cluster0 address. */ +#define QURT_ETM_TRACE_FILTER_CLUSTER1 (1<<17) /*< Filter trace cluster1 address. */ +#define QURT_ETM_TRACE_FILTER_PC_RANGE (1<<19) /*< Filter PC address range. */ + +/* ETM memory source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< ETM memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< ETM memory source of SAC* is data. */ + +/* Period between synchronization traces */ +#define QURT_ETM_ASYNC_PERIOD 0 /**< Async.*/ +#define QURT_ETM_ISYNC_PERIOD 1 /**< Isync.*/ +#define QURT_ETM_GSYNC_PERIOD 2 /**< Gsync. */ + +/* ETM enable flags */ +#define QURT_ETM_OFF 0U /**< ETM off. */ +#define QURT_ETM_ON 1U /**< ETM on. */ +/** @endcond */ +/** @} */ /* end_addtogroup etm_macros */ + +/** @addtogroup function_tracing_macro +@{ */ +/* ETM setup return values */ +#define QURT_ETM_SETUP_OK 0 /**< ETM setup OK. */ +#define QURT_ETM_SETUP_ERR 1 /**< ETM setup error. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* ETM breakpoint types */ +#define QURT_ETM_READWRITE_BRKPT 0U /**< ETM read/write breakpoint. */ +#define QURT_ETM_READ_BRKPT 1U /**< ETM read breakpoint. */ +#define QURT_ETM_WRITE_BRKPT 2U /**< ETM write breakpoint. */ +#define QURT_ETM_BRKPT_INVALIDATE 3U /**< Invalidate breakpoint. */ +/** @addtogroup function_tracing_macro +@{ */ +/* ATB status flags */ +#define QURT_ATB_OFF 0 /**< ATB off. */ +#define QURT_ATB_ON 1 /**< ATB on. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* DTM enable flags */ +#define QURT_DTM_OFF 0 /**< DTM off. */ +#define QURT_DTM_ON 1 /**< DTM on. */ + +/** @addtogroup function_tracing_datatypes +@{ */ +/**STM trace information. */ +typedef struct qurt_stm_trace_info { + /** @cond */ + unsigned int stm_port_addr[6]; /* STM port address to which trace data must be written.*/ + unsigned int thread_event_id; /* Event ID for context switches.*/ + unsigned int interrupt_event_id; /* Event ID for interrupts. */ + unsigned int marker; /* Marker value that must be written at the beginning of the trace. */ + /** @endcond */ +} qurt_stm_trace_info_t; +/** @} */ /* end_addtogroup function_tracing_datatypes */ +/*============================================================================= + GLOBAL FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_trace_get_marker + Gets the kernel trace marker.\n + Returns the current value of the kernel trace marker. + The marker consists of a hardware thread identifier and an index into the kernel trace + buffer. The trace buffer records kernel events. + + @note1hang Using this function with qurt_trace_changed() + determines whether certain kernel events occurred in a block of code. + + @return + Integer -- Kernel trace marker. + + @dependencies + None. +*/ +unsigned int qurt_trace_get_marker(void); + +/**@ingroup func_qurt_trace_changed + Determines whether specific kernel events have occurred. \n + Returns a value that indicates whether the specified kernel events are recorded in the + kernel trace buffer since the specified kernel trace marker was obtained. + + The prev_trace_marker parameter specifies a kernel trace marker that was obtained by calling + qurt_trace_get_marker(). + @cond rest_dist For more information on the mask value, see the description of the trace_mask element in + @xhyperref{80VB41992,80-VB419-92}. \n @endcond + + @note1hang Used with qurt_trace_get_marker(), this function determines whether + certain kernel events occurred in a block of code.\n + @note1cont This function cannot determine whether a specific kernel event type has + occurred unless that event type has been enabled in the trace_mask element + of the system configuration file. \n + @note1cont QuRT supports the recording of interrupt and context switch events only (such as + a trace_mask value of 0x3). + + @param[in] prev_trace_marker Previous kernel trace marker. + @param[in] trace_mask Mask value that indicates which kernel events to check for. + + @returns + 1 -- Kernel events of the specified type have occurred since the + specified trace marker was obtained.\n + 0 -- No kernel events of the specified type have occurred since the + specified trace marker was obtained. + + @dependencies + None. +*/ +int qurt_trace_changed(unsigned int prev_trace_marker, unsigned int trace_mask); + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup function_tracing_macro +@{ */ +#ifndef QURT_DEBUG +#define QURT_TRACE(str, ...) __VA_ARGS__ + /**< Function tracing is implemented with the QURT_TRACE debug macro, which + optionally generates printf statements both before and after every function call that is + passed as a macro argument. + + For example, in the following macro calls in the source code: + @code + QURT_TRACE(myfunc, my_func(33)) + + @endcode + generates the following debug output: + @code + myfile:nnn: my_func >>> calling my_func(33) + myfile:nnn: my_func >>> returned my_func(33) + @endcode + The debug output includes the source file and line number of the function call, along with + the text of the call. Compile the client source file with -D __FILENAME__ + defined for its file name. + + The library function qurt_printf() generates the debug output. + The QURT_DEBUG symbol controls generation of the debug output. If this symbol is + not defined, function tracing is not generated.\n + @note1hang The debug macro is accessed through the QuRT API header file. + */ +#else +#define QURT_TRACE(str, ...) \ + do { \ + qurt_printf("%s:%d: %s: >>> calling %s\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + __VA_ARGS__; \ + qurt_printf("%s:%d: %s: <<< %s returned\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + } while (0); +#endif +/** @} */ /* end_addtogroup function_tracing_macro */ + +/**@ingroup func_qurt_etm_set_pc_range + Sets the PC address range for ETM filtering. + Depending on the Hexagon core design, a maximum of four PC ranges are supported. + + @param[in] range_num 0 to 3. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_pc_range(unsigned int range_num, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_range + Sets the address range for ETM filtering. + It allows the user to select the source type of addresses - QURT_ETM_SOURCE_PC and QURT_ETM_SOURCE_DATA. + + @param[in] addr_source_type Type of the address source:\n + - #QURT_ETM_SOURCE_PC \n + - #QURT_ETM_SOURCE_DATA @tablebulletend + @param[in] trig_block_num 0 to 3. + @param[in] pid pid of the process + 1. Any valid PID number will enable the ASID based trace filtering. + 2. QURT_ETM_NO_PID - Disable the ASID based trace filtering. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_range(unsigned int addr_source_type, unsigned int trig_block_num, unsigned int pid, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_atb + Sets the advanced trace bus (ATB) state to notify QuRT that the ATB is actively enabled or disabled. + QuRT performs the corresponding actions at low power management. + + @param[in] flag Values: \n + #QURT_ATB_ON \n + #QURT_ATB_OFF + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure + + @dependencies + None. +*/ +unsigned int qurt_etm_set_atb(unsigned int flag); + +/**@ingroup func_qurt_etm_set_sync_period + Sets the period for types of synchronization trace packets. \n + ASYNC defines the period between alignment synchronization packets. + Period is in terms of bytes in the packet stream. \n + ISYNC defines the period between instruction synchronization packets. + Period is per thread and is defined as the bytes sent out for that thread. \n + GSYNC is the defined period in thread cycles between GSYNC packets. + + @param[in] sync_type Type of synchronization packets: \n + #QURT_ETM_ASYNC_PERIOD \n + #QURT_ETM_ISYNC_PERIOD \n + #QURT_ETM_GSYNC_PERIOD + @param[in] period Period value. + + @return + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. + */ +unsigned int qurt_etm_set_sync_period(unsigned int sync_type, unsigned int period); + +/**@ingroup func_qurt_stm_trace_set_config + Sets up a STM port for tracing events. + + @datatypes + #qurt_stm_trace_info_t + + @param[in] stm_config_info Pointer to the STM trace information used to set up the trace + in the kernel. + The strucure must have the following:\n + - One port address per hardware thread \n + - Event ID for context switches \n + - Event ID for interrupt tracing n + - Header or marker to identify the beginning of the trace. @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Failure; possibly because the passed port address is not in the page table. + + @dependencies + None. + */ +unsigned int qurt_stm_trace_set_config(qurt_stm_trace_info_t *stm_config_info); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TRACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_types.h new file mode 100755 index 0000000000000..bdb83a3fe2fb2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_types.h @@ -0,0 +1,294 @@ +#ifndef QURT_TYPES_H +#define QURT_TYPES_H +/** + @file qurt_types.h + @brief Contains types common to all configurations + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +//#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define PGA_BITFIELD_MASK(hi,lo) (((~0u)>>(31U-((hi)-(lo))))<<(lo)) +#define PGA_BITFIELD_GET(x,hi,lo) (((x)&PGA_BITFIELD_MASK((hi),(lo)))>>(lo)) +#define PGA_BITFIELD_INS(hi,lo,v) (((v)<<(lo))&PGA_BITFIELD_MASK((hi),(lo))) +#define PGA_BITFIELD_SET(x,hi,lo,v) ((x)=((x)&~PGA_BITFIELD_MASK((hi),(lo)))|PGA_BITFIELD_INS((hi),(lo),(v))) +#define QURT_PGATTR_C_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 3U, 0U) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 5U, 4U) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_C_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 3U, 0U, (v)) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 5U, 4U, (v)) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_MKRAW(v) ((qurt_pgattr_t){.pga_value = (v)}) +#define QURT_PGATTR_MK(c,a) QURT_PGATTR_MKRAW(PGA_BITFIELD_INS(3U,0U,(c))|PGA_BITFIELD_INS(5U,4U,(a))) + +/*return types for qurt_island_get_status2*/ +#define QURT_ISLAND_MODE_NORMAL 0U /**< Normal operating mode */ +#define QURT_ISLAND_MODE_ISLAND 1U /**< Island mode */ +#define QURT_ISLAND_MODE_EXITING 2U /**< In transition from Island mode to Normal mode */ + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/** @addtogroup memory_management_types +@{ */ +typedef unsigned int qurt_addr_t; /**< QuRT address type.*/ +typedef unsigned int qurt_paddr_t; /**< QuRT physical memory address type. */ +/** @cond rest_reg_dist */ +typedef unsigned long long qurt_addr_64_t; /**< QuRT 64-bit memory address type. */ +typedef unsigned long long qurt_paddr_64_t; /**< QuRT 64-bit physical memory address type. */ +typedef unsigned int qurt_mem_region_t; /**< QuRT memory regions type. */ +typedef unsigned int qurt_mem_fs_region_t; /**< QuRT memory FS region type. */ +/**@endcond */ +typedef unsigned int qurt_mem_pool_t; /**< QuRT memory pool type.*/ +typedef unsigned int qurt_size_t; /**< QuRT size type. */ +/** @cond */ +typedef unsigned long long qurt_mmu_entry_t;/**< QuRT MMU entry type. */ +#define QURT_PHYSPOOL_NAME_LEN (32) +typedef char qurt_physpool_name_t[QURT_PHYSPOOL_NAME_LEN]; + + +/* + * Mapping type + * + * QMEM_MAPPING_VIRTUAL is the default mode, in which the system + * picks up the available range of the virtual address, and maps it to + * available contiguous physical addresses. Physical-to-virtual + * is not guaranteed to be 1:1; both virtual and physical memory is + * contiguous. + * + * In QMEM_MAPPING_IDEMPOTENT mode, the user provides the physical address; + * the kernel allocates 1:1 physical-to-virtual memory. Primary use of + * of this mapping is to allocate physical-to-virtual memory 1:1. + * + * In QMEM_MAPPING_PHYS_CONTIGUOUS mode, the virtual address might + * not be the same as the physical address. But the physical address of the + * memory region is guaranteed to be contiguous starting at the provided + * address, it is required to provide a fixed physical address. The primary + * use of this mapping is to allocate physical memory from a particular + * address, where 1:1 physical-to-virtual is not required. + * + * QMEM_MAPPING_NONE mode must be used to reserve a virtual memory + * area (VMA); no physical memory is reserved or mapped to this virtual + * space; all standard qmem_region APIs apply to a VMA, however physical + * address is always INVALID_ADDR. qmem_region_create() in this mode + * returns a handle to the VMA, both virt_addr and phys_addr must + * be set to INVALID_ADDR, kernel allocates any available virtual + * memory of the specified size. Obtain the starting virtual address + * of VMA through qmem_region_attr_getvirtaddr(). + * Primary purpose of this mapping mode is to provide a mechanism for + * delayed binding in QuRT, for example reserve virtual memory and map it at + * some later time to possibly discontiguous physical blocks. Thus, a + * single VMA can be partitioned among several physical-virtual mappings + * created via qmem_region_create() with QMEM_VIRTUAL_FIXED mapping mode. + * Each VMA keeps track of associated mapped regions. + * Deletion of VMA succeeds only if all associated "virtual_fixed" + * regions are freed prior to VMA deletion. + * + * Use QMEM_MAPPING_VIRTUAL_FIXED mode to create a region + * from virtual space that has been reserved via qmem_region_create() + * with QMEM_MAPPING_NONE mapping. A valid virt_add is required, if + * phys_addr is specified, the kernel attempts to map it accordingly, + * if no phys_addr is specified, kernel maps any available physical + * memory. All standard qmem_region APIs apply to such region. Remapping + * a virtual range without prior freeing of the region is not permitted. + * When such region is deleted its corresponding VMA remains intact. + * + * QMEM_MAPPING_PHYS_DISCONTIGUOUS mode can obtain contiguous + * virtual memory but physical memory can be discontiguous. This method + * tries to club small physical memory blocks to obtain requested + * memory and is useful in case where there is no contiguous full block + * of requested size. If client does not need contiguous physical memory, + * (for example, if client does not use physical addressing), this helps + * use smaller physical memory blocks rather than using contiguous memory. + * Note: When memory is allocated through this method, physical address is + * not returned to the caller using the qurt_mem_region_attr_get() API as there might + * not be a single physical address. + * + */ +/**@endcond */ +/** QuRT memory region mapping type. */ +typedef enum { + QURT_MEM_MAPPING_VIRTUAL=0, /**< Default mode. The region virtual address range maps to an + available contiguous area of physical memory. For the most + efficient use of virtual memory, the QuRT system + chooses the base address in physical memory. This works for most memory + use cases.*/ + QURT_MEM_MAPPING_PHYS_CONTIGUOUS = 1, /**< The region virtual address space must be mapped to a + contiguous area of physical memory. This is necessary when the + memory region is accessed by external devices that bypass Hexagon + virtual memory addressing. The base address in physical + memory must be explicitly specified.*/ + QURT_MEM_MAPPING_IDEMPOTENT=2, /**< Region virtual address space maps + to the identical area of physical memory. */ + QURT_MEM_MAPPING_VIRTUAL_FIXED=3, /**< Virtual address space of the region maps either to the + specified area of physical memory or (if no area is specified) + to available physical memory. Use this mapping to create + regions from virtual space that was reserved by calling + qurt_mem_region_create() with mapping. */ + QURT_MEM_MAPPING_NONE=4, /**< Reserves a virtual memory area (VMA). Remapping a virtual range is not + permitted without first deleting the memory region. When such a region is + deleted, its corresponding virtual memory addressing remains intact. */ + QURT_MEM_MAPPING_VIRTUAL_RANDOM=7, /**< System chooses a random virtual address and + maps it to available contiguous physical addresses.*/ + QURT_MEM_MAPPING_PHYS_DISCONTIGUOUS=8, /**< While virtual memory is contiguous, allocates in discontiguous physical + memory blocks. This helps when there are smaller contiguous blocks + than the requested size. + Physical address is not provided as part of the get_attr call */ + QURT_MEM_MAPPING_INVALID=10, /**< Reserved as an invalid mapping type. */ +} qurt_mem_mapping_t; + + +/** QuRT cache mode type. */ +typedef enum { + QURT_MEM_CACHE_WRITEBACK=7, /**< Write back. */ + QURT_MEM_CACHE_NONE_SHARED=6, /**< Normal uncached memory that can be shared with other subsystems.*/ + QURT_MEM_CACHE_WRITETHROUGH=5, /**< Write through. */ + QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE=0, /**< Write back non-L2-cacheable.*/ + QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE=1, /**< Write through non-L2-cacheable. */ + QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE=QURT_MEM_CACHE_WRITEBACK, /**< Write back L2 cacheable. */ + QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE=QURT_MEM_CACHE_WRITETHROUGH, /**< Write through L2 cacheable. */ + QURT_MEM_CACHE_DEVICE = 4, /**< Volatile memory-mapped device. Access to device memory cannot be cancelled by interrupts, re-ordered, or replayed.*/ + QURT_MEM_CACHE_NONE = 4, /**< Deprecated -- use #QURT_MEM_CACHE_DEVICE instead. */ + QURT_MEM_CACHE_DEVICE_SFC = 2, /**< Enables placing limitations on the number of outstanding transactions. */ + QURT_MEM_CACHE_INVALID=10, /**< Reserved as an invalid cache type. */ +} qurt_mem_cache_mode_t; + +/** Memory access permission. */ +#define QURT_PERM_NONE 0x0U /**< No permission. */ +#define QURT_PERM_READ 0x1U /**< Read permission. */ +#define QURT_PERM_WRITE 0x2U /**< Write permission. */ +#define QURT_PERM_EXECUTE 0x4U /**< Execution permission. */ +#define QURT_PERM_NODUMP 0x8U + /**< Skip dumping the mapping. During process domain dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and DSP process + crashed before the mapping is removed. */ +#define QURT_PERM_FULL QURT_PERM_READ | QURT_PERM_WRITE | QURT_PERM_EXECUTE /**< Read, write, and execute permission. */ + +typedef unsigned char qurt_perm_t; + + +/** @cond rest_reg_dist*/ +/** QuRT cache type; specifies data cache or instruction cache. */ +typedef enum { + QURT_MEM_ICACHE, /**< Instruction cache.*/ + QURT_MEM_DCACHE /**< Data cache.*/ +} qurt_mem_cache_type_t; + +/** QuRT cache operation code type. */ +typedef enum { + QURT_MEM_CACHE_FLUSH, /**< Flush. */ + QURT_MEM_CACHE_INVALIDATE, /**< Invalidate */ + QURT_MEM_CACHE_FLUSH_INVALIDATE, /**< Flush invalidate. */ + QURT_MEM_CACHE_FLUSH_ALL, /**< Flush all. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_ALL, /**< Flush invalidate all. */ + QURT_MEM_CACHE_TABLE_FLUSH_INVALIDATE, /**< Table flush invalidate. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_L2, /**< L2 flush invalidate.*/ +} qurt_mem_cache_op_t; + +/** QuRT memory region type. */ +typedef enum { + QURT_MEM_REGION_LOCAL=0, /**< Local. */ + QURT_MEM_REGION_SHARED=1, /**< Shared.*/ + QURT_MEM_REGION_USER_ACCESS=2, /**< User access. */ + QURT_MEM_REGION_FS=4, /**< FS. */ + QURT_MEM_REGION_INVALID=10, /**< Reserved as an invalid region type. */ +} qurt_mem_region_type_t; + +/* Cache and bus attributes are combined into a value of this type for convenience, + and macros for combining and extracting fields are defined here. */ +/** @cond */ +struct qurt_pgattr { + unsigned pga_value; /**< PGA value.*/ +}; +typedef struct qurt_pgattr qurt_pgattr_t; +/** @endcond */ +/** QuRT memory region attributes type.*/ +/* QMEM_MAPPING_IDEMPOTENT and QMEM_MAPPING_PHYS_CONTIGUOUS mode can specify physaddr. + virtaddr cannot be specified for a memory region, it can only be queried by the + qmem_attr_getvirtaddr() function. + */ +typedef struct { + /** @cond */ + qurt_mem_mapping_t mapping_type; + unsigned char perms; + unsigned short owner; + qurt_pgattr_t pga; + unsigned ppn; //physical page number (physical>>12) + qurt_addr_t virtaddr; + qurt_mem_region_type_t type; + qurt_size_t size; + /** @endcond */ +} qurt_mem_region_attr_t; + + +/** QuRT user physical memory pool type. */ +typedef struct { + /** @cond */ + char name[32]; + struct ranges{ + unsigned int start; + unsigned int size; + } ranges[MAX_POOL_RANGES]; + /** @endcond */ +} qurt_mem_pool_attr_t; + +/** QuRT memory pool status type.*/ +typedef struct _qurt_mem_pool_status { + + qurt_size_t contig_size; /**< Largest contiguous free memory in bytes. */ + qurt_size_t free_size; /**< Total free memory in bytes. */ + qurt_size_t total_size; /**< Total declared memory in bytes. */ + +} qurt_mem_pool_status_t; + +typedef enum { + HEXAGON_L1_I_CACHE = 0, /**< Hexagon L1 instruction cache. */ + HEXAGON_L1_D_CACHE = 1, /**< Hexagon L1 data cache. */ + HEXAGON_L2_CACHE = 2 /**< Hexagon L2 cache. */ +} qurt_cache_type_t; + +typedef enum { + FULL_SIZE = 0, /**< Fully shared cache, without partitioning. */ + HALF_SIZE = 1, /**< 1/2 for main, 1/2 for auxiliary. */ + THREE_QUARTER_SIZE = 2, /**< 3/4 for main, 1/4 for auxiliary. */ + SEVEN_EIGHTHS_SIZE = 3 /**< 7/8 for main, 1/8 for auxiliary; for L2 cache only. */ +} qurt_cache_partition_size_t; + +typedef enum { + QURT_PROCESS_CB_GENERIC, /**< generic unconditional cb called after image loading. */ + QURT_PROCESS_NOTE_CB_PRE_MAP, /**< note cb called before segment loading. */ + QURT_PROCESS_NOTE_CB_POST_MAP /**< note cb called after segment loading. */ +} qurt_process_cb_type_t; + +typedef union { + void *ptr; + int num; +} qurt_process_callback_arg_t; + + +/**@endcond*/ + +/** @} */ /* end_addtogroup memory_management_types */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TYPES_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_user_dma.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_user_dma.h new file mode 100755 index 0000000000000..e05a6429fd703 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_user_dma.h @@ -0,0 +1,44 @@ +#ifndef QURT_USER_DMA_H +#define QURT_USER_DMA_H + +/** + @file qurt_user_dma.h + @brief Definitions, macros, and prototypes used for handling user DMA. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_user_dma_dmsyncht + Sends the DMSyncht command to the user DMA engine. + + Call this function to ensure all posted DMA memory operations are + complete. + + This stalls the current thread until the instruction + is complete and returns. + + @return + QURT_EOK - On dmsyncht completion \n + QURT_ENOTSUPPORTED - User DMA not supported + + @dependencies + None. +*/ +int qurt_user_dma_dmsyncht(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_vtlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_vtlb.h new file mode 100755 index 0000000000000..e064042e447ac --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/include/qurt/qurt_vtlb.h @@ -0,0 +1,76 @@ +/*============================================================================= + + qurt_vtlb.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef QURT_VTLB_H +#define QURT_VTLB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Names starting with "qurt_i_vtlb" are the internal low-level functions. +|| These should be considered subject to change. +*/ + +int qurt_i_vtlb_entry_create(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension); + +int qurt_i_vtlb_entry_create_with_pid(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension, + unsigned target_pid); + +int qurt_i_vtlb_entry_delete(unsigned index); + +int qurt_i_vtlb_entry_read(unsigned index, unsigned *tlbinfo); + +int qurt_i_vtlb_entry_write(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension); + +int qurt_i_vtlb_entry_write_with_pid(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension, unsigned target_pid); + +int qurt_i_vtlb_entry_probe(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex); + +int qurt_i_vtlb_entry_probe_with_pid(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex, unsigned target_pid); + + +int qurt_i_vtlb_statistics(unsigned *stats); // Returns stats[0] -- total number of VTLB entries + // stats[1] -- number of available VTLB entries + // stats[2] -- max size of VTLB tree since boot + +//can return index to an entry that was specialed, change it to take addresses instead of pages +int qurt_i_vtlb_set_special(int index, unsigned pageno, unsigned asid, unsigned size); + +int qurt_i_vtlb_queue_ppage(unsigned pageno, unsigned vtlb_index); + +#define QURT_VTLB_EXT_DEFAULT 0U +#define QURT_VTLB_EXT_LOCKED 1U +#define QURT_VTLB_EXT_EXCLUDE_DUMP 2U /* Temporary ability to skip certain mappings in pd dump */ +#define QURT_VTLB_EXT_FREELIST 0x800000u + +#define QURT_VTLB_ERR_OVERLAP -64 +#define QURT_VTLB_ERR_TREE_NO_SPACE -65 +#define QURT_VTLB_ERR_INVALID_SIZE -68 +#define QURT_VTLB_ERR_INVALID_EXT -69 +#define QURT_VTLB_ERR_DEL_PGT_LOCKED -70 +#define QURT_VTLB_ERR_PGT_LOCK_CNT -71 + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_VTLB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libposix.a new file mode 100755 index 0000000000000..ca0bdbacb0604 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurt.a new file mode 100755 index 0000000000000..91fc230d94d3b Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurtcfs.a new file mode 100755 index 0000000000000..e7a8102d8cb40 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_island.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_island.a new file mode 100755 index 0000000000000..32ce17efe453e Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_island.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_main.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_main.a new file mode 100755 index 0000000000000..a67c32e005b95 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/libtimer_main.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libposix.a new file mode 100755 index 0000000000000..1e0afa4db765b Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurt.a new file mode 100755 index 0000000000000..fff03b0877eb8 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurtcfs.a new file mode 100755 index 0000000000000..e7a8102d8cb40 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libtimer.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libtimer.a new file mode 100755 index 0000000000000..cd856bdb8c5cf Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev69/lib/pic/libtimer.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/confname.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/confname.h new file mode 100755 index 0000000000000..d9ca3135501e3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/confname.h @@ -0,0 +1,528 @@ +#ifndef CONFNAME_H +#define CONFNAME_H +/** + @file confname.h + @brief Named literals for 'name' argument of sysconf, pathconf + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly. Instead include unistd.h. For now since + toolchain doesnt provide a hook by including bits/confname.h, we stick this + header in QuRT's sys/types.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum +{ + _PC_LINK_MAX, +#define _PC_LINK_MAX _PC_LINK_MAX + _PC_MAX_CANON, +#define _PC_MAX_CANON _PC_MAX_CANON + _PC_MAX_INPUT, +#define _PC_MAX_INPUT _PC_MAX_INPUT + _PC_NAME_MAX, +#define _PC_NAME_MAX _PC_NAME_MAX + _PC_PATH_MAX, +#define _PC_PATH_MAX _PC_PATH_MAX + _PC_PIPE_BUF, +#define _PC_PIPE_BUF _PC_PIPE_BUF + _PC_CHOWN_RESTRICTED, +#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED + _PC_NO_TRUNC, +#define _PC_NO_TRUNC _PC_NO_TRUNC + _PC_VDISABLE, +#define _PC_VDISABLE _PC_VDISABLE + _PC_SYNC_IO, +#define _PC_SYNC_IO _PC_SYNC_IO + _PC_ASYNC_IO, +#define _PC_ASYNC_IO _PC_ASYNC_IO + _PC_PRIO_IO, +#define _PC_PRIO_IO _PC_PRIO_IO + _PC_SOCK_MAXBUF, +#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF + _PC_FILESIZEBITS, +#define _PC_FILESIZEBITS _PC_FILESIZEBITS + _PC_REC_INCR_XFER_SIZE, +#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE + _PC_REC_MAX_XFER_SIZE, +#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE + _PC_REC_MIN_XFER_SIZE, +#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE + _PC_REC_XFER_ALIGN, +#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN + _PC_ALLOC_SIZE_MIN, +#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN + _PC_SYMLINK_MAX, +#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX + _PC_2_SYMLINKS +#define _PC_2_SYMLINKS _PC_2_SYMLINKS +}; + +/* Values for the argument to `sysconf'. */ +enum +{ + _SC_ARG_MAX, +#define _SC_ARG_MAX _SC_ARG_MAX + _SC_CHILD_MAX, +#define _SC_CHILD_MAX _SC_CHILD_MAX + _SC_CLK_TCK, +#define _SC_CLK_TCK _SC_CLK_TCK + _SC_NGROUPS_MAX, +#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX + _SC_OPEN_MAX, +#define _SC_OPEN_MAX _SC_OPEN_MAX + _SC_STREAM_MAX, +#define _SC_STREAM_MAX _SC_STREAM_MAX + _SC_TZNAME_MAX, +#define _SC_TZNAME_MAX _SC_TZNAME_MAX + _SC_JOB_CONTROL, +#define _SC_JOB_CONTROL _SC_JOB_CONTROL + _SC_SAVED_IDS, +#define _SC_SAVED_IDS _SC_SAVED_IDS + _SC_REALTIME_SIGNALS, +#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + _SC_PRIORITY_SCHEDULING, +#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + _SC_TIMERS, +#define _SC_TIMERS _SC_TIMERS + _SC_ASYNCHRONOUS_IO, +#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + _SC_PRIORITIZED_IO, +#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO + _SC_SYNCHRONIZED_IO, +#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + _SC_FSYNC, +#define _SC_FSYNC _SC_FSYNC + _SC_MAPPED_FILES, +#define _SC_MAPPED_FILES _SC_MAPPED_FILES + _SC_MEMLOCK, +#define _SC_MEMLOCK _SC_MEMLOCK + _SC_MEMLOCK_RANGE, +#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + _SC_MEMORY_PROTECTION, +#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + _SC_MESSAGE_PASSING, +#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING + _SC_SEMAPHORES, +#define _SC_SEMAPHORES _SC_SEMAPHORES + _SC_SHARED_MEMORY_OBJECTS, +#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + _SC_AIO_LISTIO_MAX, +#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX + _SC_AIO_MAX, +#define _SC_AIO_MAX _SC_AIO_MAX + _SC_AIO_PRIO_DELTA_MAX, +#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX + _SC_DELAYTIMER_MAX, +#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX + _SC_MQ_OPEN_MAX, +#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX + _SC_MQ_PRIO_MAX, +#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX + _SC_VERSION, +#define _SC_VERSION _SC_VERSION + _SC_PAGESIZE, +#define _SC_PAGESIZE _SC_PAGESIZE +#define _SC_PAGE_SIZE _SC_PAGESIZE + _SC_RTSIG_MAX, +#define _SC_RTSIG_MAX _SC_RTSIG_MAX + _SC_SEM_NSEMS_MAX, +#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX + _SC_SEM_VALUE_MAX, +#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX + _SC_SIGQUEUE_MAX, +#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX + _SC_TIMER_MAX, +#define _SC_TIMER_MAX _SC_TIMER_MAX + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, +#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX + _SC_BC_DIM_MAX, +#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX + _SC_BC_SCALE_MAX, +#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX + _SC_BC_STRING_MAX, +#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX + _SC_COLL_WEIGHTS_MAX, +#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX + _SC_EQUIV_CLASS_MAX, +#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX + _SC_EXPR_NEST_MAX, +#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX + _SC_LINE_MAX, +#define _SC_LINE_MAX _SC_LINE_MAX + _SC_RE_DUP_MAX, +#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX + _SC_CHARCLASS_NAME_MAX, +#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX + + _SC_2_VERSION, +#define _SC_2_VERSION _SC_2_VERSION + _SC_2_C_BIND, +#define _SC_2_C_BIND _SC_2_C_BIND + _SC_2_C_DEV, +#define _SC_2_C_DEV _SC_2_C_DEV + _SC_2_FORT_DEV, +#define _SC_2_FORT_DEV _SC_2_FORT_DEV + _SC_2_FORT_RUN, +#define _SC_2_FORT_RUN _SC_2_FORT_RUN + _SC_2_SW_DEV, +#define _SC_2_SW_DEV _SC_2_SW_DEV + _SC_2_LOCALEDEF, +#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF + + _SC_PII, +#define _SC_PII _SC_PII + _SC_PII_XTI, +#define _SC_PII_XTI _SC_PII_XTI + _SC_PII_SOCKET, +#define _SC_PII_SOCKET _SC_PII_SOCKET + _SC_PII_INTERNET, +#define _SC_PII_INTERNET _SC_PII_INTERNET + _SC_PII_OSI, +#define _SC_PII_OSI _SC_PII_OSI + _SC_POLL, +#define _SC_POLL _SC_POLL + _SC_SELECT, +#define _SC_SELECT _SC_SELECT + _SC_UIO_MAXIOV, +#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV + _SC_IOV_MAX = _SC_UIO_MAXIOV, +#define _SC_IOV_MAX _SC_IOV_MAX + _SC_PII_INTERNET_STREAM, +#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM + _SC_PII_INTERNET_DGRAM, +#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM + _SC_PII_OSI_COTS, +#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS + _SC_PII_OSI_CLTS, +#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS + _SC_PII_OSI_M, +#define _SC_PII_OSI_M _SC_PII_OSI_M + _SC_T_IOV_MAX, +#define _SC_T_IOV_MAX _SC_T_IOV_MAX + + /* Values according to POSIX 1003.1c (POSIX threads). */ + _SC_THREADS, +#define _SC_THREADS _SC_THREADS + _SC_THREAD_SAFE_FUNCTIONS, +#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + _SC_GETGR_R_SIZE_MAX, +#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX + _SC_GETPW_R_SIZE_MAX, +#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX + _SC_LOGIN_NAME_MAX, +#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX + _SC_TTY_NAME_MAX, +#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX + _SC_THREAD_DESTRUCTOR_ITERATIONS, +#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + _SC_THREAD_KEYS_MAX, +#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + _SC_THREAD_STACK_MIN, +#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN + _SC_THREAD_THREADS_MAX, +#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + _SC_THREAD_ATTR_STACKADDR, +#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + _SC_THREAD_ATTR_STACKSIZE, +#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + _SC_THREAD_PRIORITY_SCHEDULING, +#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + _SC_THREAD_PRIO_INHERIT, +#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + _SC_THREAD_PRIO_PROTECT, +#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + _SC_THREAD_PROCESS_SHARED, +#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + + _SC_NPROCESSORS_CONF, +#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF + _SC_NPROCESSORS_ONLN, +#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN + _SC_PHYS_PAGES, +#define _SC_PHYS_PAGES _SC_PHYS_PAGES + _SC_AVPHYS_PAGES, +#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES + _SC_ATEXIT_MAX, +#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX + _SC_PASS_MAX, +#define _SC_PASS_MAX _SC_PASS_MAX + + _SC_XOPEN_VERSION, +#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION + _SC_XOPEN_XCU_VERSION, +#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION + _SC_XOPEN_UNIX, +#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX + _SC_XOPEN_CRYPT, +#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT + _SC_XOPEN_ENH_I18N, +#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + _SC_XOPEN_SHM, +#define _SC_XOPEN_SHM _SC_XOPEN_SHM + + _SC_2_CHAR_TERM, +#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM + _SC_2_C_VERSION, +#define _SC_2_C_VERSION _SC_2_C_VERSION + _SC_2_UPE, +#define _SC_2_UPE _SC_2_UPE + + _SC_XOPEN_XPG2, +#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2 + _SC_XOPEN_XPG3, +#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3 + _SC_XOPEN_XPG4, +#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4 + + _SC_CHAR_BIT, +#define _SC_CHAR_BIT _SC_CHAR_BIT + _SC_CHAR_MAX, +#define _SC_CHAR_MAX _SC_CHAR_MAX + _SC_CHAR_MIN, +#define _SC_CHAR_MIN _SC_CHAR_MIN + _SC_INT_MAX, +#define _SC_INT_MAX _SC_INT_MAX + _SC_INT_MIN, +#define _SC_INT_MIN _SC_INT_MIN + _SC_LONG_BIT, +#define _SC_LONG_BIT _SC_LONG_BIT + _SC_WORD_BIT, +#define _SC_WORD_BIT _SC_WORD_BIT + _SC_MB_LEN_MAX, +#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX + _SC_NZERO, +#define _SC_NZERO _SC_NZERO + _SC_SSIZE_MAX, +#define _SC_SSIZE_MAX _SC_SSIZE_MAX + _SC_SCHAR_MAX, +#define _SC_SCHAR_MAX _SC_SCHAR_MAX + _SC_SCHAR_MIN, +#define _SC_SCHAR_MIN _SC_SCHAR_MIN + _SC_SHRT_MAX, +#define _SC_SHRT_MAX _SC_SHRT_MAX + _SC_SHRT_MIN, +#define _SC_SHRT_MIN _SC_SHRT_MIN + _SC_UCHAR_MAX, +#define _SC_UCHAR_MAX _SC_UCHAR_MAX + _SC_UINT_MAX, +#define _SC_UINT_MAX _SC_UINT_MAX + _SC_ULONG_MAX, +#define _SC_ULONG_MAX _SC_ULONG_MAX + _SC_USHRT_MAX, +#define _SC_USHRT_MAX _SC_USHRT_MAX + + _SC_NL_ARGMAX, +#define _SC_NL_ARGMAX _SC_NL_ARGMAX + _SC_NL_LANGMAX, +#define _SC_NL_LANGMAX _SC_NL_LANGMAX + _SC_NL_MSGMAX, +#define _SC_NL_MSGMAX _SC_NL_MSGMAX + _SC_NL_NMAX, +#define _SC_NL_NMAX _SC_NL_NMAX + _SC_NL_SETMAX, +#define _SC_NL_SETMAX _SC_NL_SETMAX + _SC_NL_TEXTMAX, +#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX + + _SC_XBS5_ILP32_OFF32, +#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32 + _SC_XBS5_ILP32_OFFBIG, +#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG + _SC_XBS5_LP64_OFF64, +#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64 + _SC_XBS5_LPBIG_OFFBIG, +#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG + + _SC_XOPEN_LEGACY, +#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY + _SC_XOPEN_REALTIME, +#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME + _SC_XOPEN_REALTIME_THREADS, +#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + _SC_ADVISORY_INFO, +#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO + _SC_BARRIERS, +#define _SC_BARRIERS _SC_BARRIERS + _SC_BASE, +#define _SC_BASE _SC_BASE + _SC_C_LANG_SUPPORT, +#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT + _SC_C_LANG_SUPPORT_R, +#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R + _SC_CLOCK_SELECTION, +#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION + _SC_CPUTIME, +#define _SC_CPUTIME _SC_CPUTIME + _SC_THREAD_CPUTIME, +#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME + _SC_DEVICE_IO, +#define _SC_DEVICE_IO _SC_DEVICE_IO + _SC_DEVICE_SPECIFIC, +#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC + _SC_DEVICE_SPECIFIC_R, +#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R + _SC_FD_MGMT, +#define _SC_FD_MGMT _SC_FD_MGMT + _SC_FIFO, +#define _SC_FIFO _SC_FIFO + _SC_PIPE, +#define _SC_PIPE _SC_PIPE + _SC_FILE_ATTRIBUTES, +#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES + _SC_FILE_LOCKING, +#define _SC_FILE_LOCKING _SC_FILE_LOCKING + _SC_FILE_SYSTEM, +#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM + _SC_MONOTONIC_CLOCK, +#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + _SC_MULTI_PROCESS, +#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS + _SC_SINGLE_PROCESS, +#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS + _SC_NETWORKING, +#define _SC_NETWORKING _SC_NETWORKING + _SC_READER_WRITER_LOCKS, +#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + _SC_SPIN_LOCKS, +#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS + _SC_REGEXP, +#define _SC_REGEXP _SC_REGEXP + _SC_REGEX_VERSION, +#define _SC_REGEX_VERSION _SC_REGEX_VERSION + _SC_SHELL, +#define _SC_SHELL _SC_SHELL + _SC_SIGNALS, +#define _SC_SIGNALS _SC_SIGNALS + _SC_SPAWN, +#define _SC_SPAWN _SC_SPAWN + _SC_SPORADIC_SERVER, +#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER + _SC_THREAD_SPORADIC_SERVER, +#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + _SC_SYSTEM_DATABASE, +#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE + _SC_SYSTEM_DATABASE_R, +#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R + _SC_TIMEOUTS, +#define _SC_TIMEOUTS _SC_TIMEOUTS + _SC_TYPED_MEMORY_OBJECTS, +#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + _SC_USER_GROUPS, +#define _SC_USER_GROUPS _SC_USER_GROUPS + _SC_USER_GROUPS_R, +#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R + _SC_2_PBS, +#define _SC_2_PBS _SC_2_PBS + _SC_2_PBS_ACCOUNTING, +#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + _SC_2_PBS_LOCATE, +#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE + _SC_2_PBS_MESSAGE, +#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE + _SC_2_PBS_TRACK, +#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK + _SC_SYMLOOP_MAX, +#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX + _SC_STREAMS, +#define _SC_STREAMS _SC_STREAMS + _SC_2_PBS_CHECKPOINT, +#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + + _SC_V6_ILP32_OFF32, +#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + _SC_V6_ILP32_OFFBIG, +#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + _SC_V6_LP64_OFF64, +#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + _SC_V6_LPBIG_OFFBIG, +#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + + _SC_HOST_NAME_MAX, +#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX + _SC_TRACE, +#define _SC_TRACE _SC_TRACE + _SC_TRACE_EVENT_FILTER, +#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + _SC_TRACE_INHERIT, +#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT + _SC_TRACE_LOG, +#define _SC_TRACE_LOG _SC_TRACE_LOG + + _SC_LEVEL1_ICACHE_SIZE, +#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE + _SC_LEVEL1_ICACHE_ASSOC, +#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC + _SC_LEVEL1_ICACHE_LINESIZE, +#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE + _SC_LEVEL1_DCACHE_SIZE, +#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE + _SC_LEVEL1_DCACHE_ASSOC, +#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC + _SC_LEVEL1_DCACHE_LINESIZE, +#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE + _SC_LEVEL2_CACHE_SIZE, +#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE + _SC_LEVEL2_CACHE_ASSOC, +#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC + _SC_LEVEL2_CACHE_LINESIZE, +#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE + _SC_LEVEL3_CACHE_SIZE, +#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE + _SC_LEVEL3_CACHE_ASSOC, +#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC + _SC_LEVEL3_CACHE_LINESIZE, +#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE + _SC_LEVEL4_CACHE_SIZE, +#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE + _SC_LEVEL4_CACHE_ASSOC, +#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC + _SC_LEVEL4_CACHE_LINESIZE, +#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE + /* Leave room here, maybe we need a few more cache levels some day. */ + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, +#define _SC_IPV6 _SC_IPV6 + _SC_RAW_SOCKETS, +#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS + + _SC_V7_ILP32_OFF32, +#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32 + _SC_V7_ILP32_OFFBIG, +#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG + _SC_V7_LP64_OFF64, +#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64 + _SC_V7_LPBIG_OFFBIG, +#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG + + _SC_SS_REPL_MAX, +#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX + + _SC_TRACE_EVENT_NAME_MAX, +#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + _SC_TRACE_NAME_MAX, +#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + _SC_TRACE_SYS_MAX, +#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + _SC_TRACE_USER_EVENT_MAX, +#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + + _SC_XOPEN_STREAMS, +#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS + + _SC_THREAD_ROBUST_PRIO_INHERIT, +#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT + _SC_THREAD_ROBUST_PRIO_PROTECT +#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT + +}; +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/posix1_lim.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/posix1_lim.h new file mode 100755 index 0000000000000..0739958c5a6c4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/bits/posix1_lim.h @@ -0,0 +1,34 @@ +#ifndef POSIX1_LIM_H +#define POSIX1_LIM_H +/** + @file posix1_lim.h + @brief POSIX Minimum values + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +TODO + This header should be ideally relocated under api/posix/bits (something that + doesnt exist today) and be included from api/posix/bits/limits.h which inturn + should be included from toolchain's limits.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +#ifndef _POSIX_PATH_MAX +/** @brief Maximum number of bytes in a pathname, including the terminating + nul character */ +#define _POSIX_PATH_MAX 256 +#endif + +#ifndef _POSIX_SEM_NSEMS_MAX +/** @brief Maximum number of semaphores that a process may have */ +#define _POSIX_SEM_NSEMS_MAX 16 +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/common/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/common/time.h new file mode 100755 index 0000000000000..76b0d39ab7039 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/common/time.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/fcntl.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/fcntl.h new file mode 100755 index 0000000000000..c80ec98a449b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/fcntl.h @@ -0,0 +1,51 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/*========================================================================== + * FILE: fcntl.h + * + * SERVICES: POSIX fcntl.h + * + * DESCRIPTION: The header is needed by the open() and fcntl() + * system calls, which have a variety of parameters and + * flags. They are described here. + * + * The formats of the calls to each of these are: + * + * open(path, oflag [,mode]) open a file + * fcntl(fd, cmd [,arg]) get or set file attributes + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Oflag values for open(). POSIX Table 6-4. */ +#define POSIX_O_CREAT 0x100 /* creat file if it doesn't exist */ +#define POSIX_O_EXCL 0x200 /* exclusive use flag */ +#define POSIX_O_NOCTTY 0x400 /* do not assign a controlling terminal */ +#define POSIX_O_TRUNC 0x1000 /* truncate flag */ + +/* File status flags for open() and fcntl(). POSIX Table 6-5. */ +#define POSIX_O_APPEND 0x2000 /* set append mode */ +#define POSIX_O_NONBLOCK 0x4000 /* no delay */ + +/* File access modes for open() and fcntl(). POSIX Table 6-6. */ +#define POSIX_O_RDONLY 0 /* open(name, POSIX_O_RDONLY) opens read only */ +#define POSIX_O_WRONLY 1 /* open(name, POSIX_O_WRONLY) opens write only */ +#define POSIX_O_RDWR 2 /* open(name, POSIX_O_RDWR) opens read/write */ + +/* Mask for use with file access modes. POSIX Table 6-7. */ +#define POSIX_O_ACCMODE 0x3 /* mask for file access modes */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FCNTL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/hooks/unistd.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/hooks/unistd.h new file mode 100755 index 0000000000000..1c618bfe36b4f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/hooks/unistd.h @@ -0,0 +1,115 @@ +#ifndef UNISTD_H +#define UNISTD_H +/** + @file posix/hooks/unistd.h + @brief POSIX related declarations in that are missing in toolchain + header + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly! Instead include unistd.h. + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include /* For various POSIX ID types from toolchain headers */ + +#ifdef __cplusplus +extern "C" { +#endif +extern long pathconf (char const * path, int name); + +/* Process*/ + +/** The getppid() function shall return the parent process ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the parent process ID + */ +pid_t getppid(void); + +/** The getpgid() function shall return the process group ID of the process whose process ID is equal to pid + * Please refer to POSIX standard for details. + * @param thread [in] process ID + * @param value_ptr [out] process group ID + */ +pid_t getpgid(pid_t pid); + +/** The getpgrp() function shall return the process group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] process group ID of the calling process + */ +pid_t getpgrp(void); + +/**The getuid() function shall return the real user ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the real user ID of the calling process. + */ +uid_t getuid(void); + +/** The geteuid() function shall return the effective user ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective user ID of the calling process + */ +uid_t geteuid(void); + +/** The getegid() function shall return the effective group ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective group ID of the calling process. + */ +gid_t getegid(void); + +/** The getgid() function shall return the real group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] real group ID of the calling process. + */ + gid_t getgid(void); + +/** seteuid set effective user ID + * Please refer to POSIX standard for details. + * @param thread [in] effective user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int seteuid(uid_t uid); + +/** setpgrp - set the process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setpgrp(void); + +/** setuid - set user ID + * Please refer to POSIX standard for details. + * @param thread [in] user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setuid(uid_t uid); + +/** setpgid - set process group ID for job control + * Please refer to POSIX standard for details. + * @param thread [in] PID of process, PGID to be set + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setpgid(pid_t pid, pid_t pgid); + +/** setsid - create session and set process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setsid(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/mqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/mqueue.h new file mode 100755 index 0000000000000..74dcc2fa202c6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/mqueue.h @@ -0,0 +1,203 @@ +#ifndef _POSIX_MQUEUE_H_ +#define _POSIX_MQUEUE_H_ + +/*========================================================================== + * FILE: mqueue.h + * + * SERVICES: POSIX Message Queue API interface + * + * DESCRIPTION: POSIX Message Queue API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technlogies, Inc. + *==========================================================================*/ + +#include /*ssize_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MQ_PRIO_MAX 255 /* max priority */ +#define MQ_PRIO_DEFAULT 0 /* default priority */ + +typedef int mqd_t; + +struct mq_attr +{ + long mq_flags; /* message queue flags */ + long mq_maxmsg; /* maximum number of messages */ + long mq_msgsize; /* maximum message size */ + long mq_curmsgs; /* number of messages currently queued */ +}; + +typedef struct mq_attr mqueue_attr; + +/** \details + * This provides POSIX Message Queue API. + * + * mq_notify is not supported. + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * it only supports Message sending and receiving within one process. + * Message sending and receiving among processes are not supported. + */ + +/** \defgroup mqueue POSIX Message Queue API */ +/** \ingroup mqueue */ +/** @{ */ + +/** Open a message queue. + * Please refer to POSIX standard for details. + */ +mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */...); + +/** Close a message queue. + * Please refer to POSIX standard for details. + */ +int mq_close(mqd_t mq_desc); + +/** Remove a message queue. + * Please refer to POSIX standard for details. + */ +int mq_unlink(const char *name); + +/** Send a message to a message queue. + * Please refer to POSIX standard for details. + * + * If the queue is full, instead of blocking the sender, this function + * will return -1 with errno EAGAIN, in this implementation. This behavior + * may change in the future. + */ +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); + +/** Send a message to a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); + +/** Receive a message from a message queue. + * Please refer to POSIX standard for details. + */ +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); + +/** Receive a message from a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msg_prio, const struct timespec *restrict abs_timeout); + +/** Get message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); + +/** Set message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, struct mq_attr *restrict omqstat); + +/** @} */ + +#define NBBY 8U /* number of bits in a byte */ + +/* + * Select uses bit masks of file descriptors in longs. These macros + * manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here should + * be enough for most uses. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256U +#endif + +typedef unsigned long fd_mask; +#define NFDBITS (sizeof(fd_mask) * (unsigned int)NBBY) /* bits per mask */ + +#ifndef howmany +#define howmany(x, y) (((x) + ((y) - 1U)) / (y)) +#endif + +//equivalent of fd_set fpr WINNT env +typedef struct fd_set +{ + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +/** \addtogroup mqueue */ +/** @{ */ + +/** Sets the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_SET(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] |= (1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Clears the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_CLR(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] &= ~(1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise. + */ +#define FD_ISSET(n, p) ((unsigned long)(p)->fds_bits[((unsigned int) (n)) / NFDBITS] & (unsigned long)((unsigned)1U << (((unsigned int) (n)) % NFDBITS))) + +/** Copies the file descriptor set. + */ +#define FD_COPY(f, t) (void)(memcpy)((t), (f), sizeof(*(f))) + +/** Initializes the file descriptor set fdset to have zero bits for all file descriptors. + */ +#define FD_ZERO(p) (void)memset((p), 0, sizeof(*(p))) + +/** Error check the file descriptor set. + */ +#define FD_BAD(fd) ((fd) < 0 /*|| fd >= fd_arraylen || fd_array[fd].obj == 0*/) + +/*! Wait for both message queues and signals. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int pselect(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict sigmask); + +/*! Wait for multiple message queues. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout); + +/** @} */ + +/* this function is needed for test framework which needs to clean up memory when teardown */ +void _mq_teardown(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread.h new file mode 100755 index 0000000000000..f64242e8dc683 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread.h @@ -0,0 +1,287 @@ +#ifndef QURT_PTHREAD_H +#define QURT_PTHREAD_H + +/*========================================================================== + * FILE: pthread.h + * + * SERVICES: POSIX pthread API interface + * + * DESCRIPTION: POSIX pthread API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016,2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *========================================================================== + * + * EDIT HISTORY FOR MODULE + * + * This section contains comments describing changes made to the module. + * Notice that changes are listed in reverse chronological order. + * + * + * + * when who what, where, why + * -------- --- ------------------------------------------------------- + * 10/13/08 cz Initial version. + *==========================================================================*/ + +#include +#include "sys/sched.h" /* For struct sched_param */ +#include "sys/errno.h" /* error values */ +#include +#include +#include +#include +#include +#include "pthread_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* the range of the set supported by the kernel data type used to represent CPU sets. */ +#define CONFIG_NR_CPUS QURT_THREAD_CFG_BITMASK_ALL + +#define UNIMPLEMENTED(FUNC, RETURNTYPE, ARGS) static inline RETURNTYPE FUNC ARGS { qurt_printf("Unimplemented: %s... exiting\n", __FUNCTION__); exit(1); } + +/** @brief Magic (non-portable) value for a stack's address to enable usage + of auto-stack feature (if available) */ +#define PTHREAD_AUTO_STACK_MAGIC_ADDR_NP ((void *)0xFFF) + +/** \details + * This provides POSIX thread API. + * + */ + +/** \defgroup pthread POSIX pthread API */ +/** \ingroup pthread */ +/** @{ */ + +/** Compare Two Threads. + * Please refer to POSIX standard for details. + */ +static inline int pthread_equal(pthread_t t1, pthread_t t2) +{ + return (t1 == t2) ? 1 : 0; +} + +/** Create Thread. + * Please refer to POSIX standard for details. + */ +int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void *(*start)(void *), void *arg); + +/** Terminate Calling Thread. + * Please refer to POSIX standard for details. + */ +void pthread_exit(void *value_ptr); + +/** Wait for thread termination. + * Please refer to POSIX standard for details. + * @param thread [in] the thread to be joined + * @param value_ptr [out] the pointer of the exit status + */ +int pthread_join(pthread_t thread, void **value_ptr); + +/** Detach a joinable thread. + * Please refer to POSIX standard for details. + * @param id [in] id of the tread the thread to be detached. + */ +int pthread_detach(pthread_t id); + +/** Dynamic package initialisation + * Please refer to POSIX standard for details. + */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + +pthread_t pthread_self(void); +int pthread_cancel(pthread_t thread); +static inline void pthread_yield(void) +{ + return; +} + +int pthread_kill(pthread_t thread, int sig); + +/** + * @brief Return name of thread + * @warning Donot call this in the error handling path as it may cause deadlock + * due to underlying OS calls + * @param thread [in] thread Thread whose name is to be retrieved + * @param name [out] name Buffer used to return thread name + * @param len [in] len Number of bytes available in name + * @return 0 on success, ESRCH, ERANGE on failure + */ +extern int pthread_getname_np (pthread_t thread, char * name, size_t len); + +int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param); +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); +int pthread_setschedprio(pthread_t thread, int prio); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); + +/* Attribute functions */ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const sched_param *restrict param); +int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, sched_param *restrict param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr); +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void ** stackaddr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); +int pthread_attr_setscope(pthread_attr_t *attr, int scope); +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_getguardsize(const pthread_attr_t * attr, size_t * guardsize); +int pthread_attr_setautostack(pthread_attr_t *attr); +int pthread_attr_setbuspriority(pthread_attr_t *attr, unsigned short bus_priority); + +/* Qualcomm additions to pthread get/set attribute functions */ +int pthread_attr_setthreadname(pthread_attr_t *attr, const char * name); +int pthread_attr_getthreadname(const pthread_attr_t *attr, char * name, int size); +int pthread_attr_settimetestid(pthread_attr_t *attr, unsigned int tid); +int pthread_attr_gettimetestid(const pthread_attr_t *attr, unsigned int* tid); + +/* Mutexes */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling); +int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling); + +/* For Mutex with type PTHREAD_MUTEX_NORMAL, Priority Inheritance is not + * supported even PTHREAD_PRIO_INHERIT is defined since QURT does not support + * this kind of Mutex */ +int pthread_mutexattr_init(pthread_mutexattr_t *attr); +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling); + +/* Spinlocks */ +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); + +/* Condition variables */ +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); +int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); +int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock); +int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock); +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *time); + +/* Barriers */ +int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); +int pthread_barrier_destroy(pthread_barrier_t *barrier); +int pthread_barrier_wait(pthread_barrier_t *barrier); +int pthread_barrierattr_init(pthread_barrierattr_t *attr); +int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); + + +/*Read-Write locks*/ +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +int pthread_rwlock_rdlock(pthread_rwlock_t *); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *); +int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); +int pthread_rwlock_unlock(pthread_rwlock_t *); + + +/** please refer to POSIX standard document + */ +int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/** set CPU affinity attribute in thread attributes object. + + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [in] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpuset specified a CPU that was outside the set supported + by the kernel. (The kernel configuration option + CONFIG_NR_CPUS defines the range of the set supported by + the kernel data type used to represent CPU sets.) + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); + +/** get CPU affinity attribute in thread attributes object. + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [out] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpusetsize is smaller than the size of the affinity mask + used by the kernel. + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset); + +/* TLS */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_getattr_np(pthread_t thread, pthread_attr_t * restrict attr); + +/** @} */ + +/* Calling non-pthread calls this function to create pthred tcb w/o creating actual thread */ +int pthread_fake(pthread_t * restrict thread, const pthread_attr_t * restrict attr); +int pthread_fake_destroy(pthread_t thread); + +//amitkulk: move these to unistd.h after we move that header within qurt +int posix_memalign(void **memptr, size_t alignment, size_t size); +void exit(int status); +#ifdef __cplusplus +} +#endif + +#endif /* QURT_PTHREAD_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread_types.h new file mode 100755 index 0000000000000..51c3b9dbca243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/pthread_types.h @@ -0,0 +1,193 @@ +#ifndef _PTHREAD_TYPES_H_ +#define _PTHREAD_TYPES_H_ + +/*========================================================================== + * FILE: pthread_types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2016, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif + +#define _SSIZE_T + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PTHREAD_MAX_THREADS 512U + +#define PTHREAD_NAME_LEN 16 +#define PTHREAD_MIN_STACKSIZE 512 //4096 +#define PTHREAD_MAX_STACKSIZE 1048576 +#define PTHREAD_DEFAULT_STACKSIZE 16384 + +#define PTHREAD_STACK_MIN (4096U*2U) +#define PTHREAD_MIN_PRIORITY 0U +#define PTHREAD_MAX_PRIORITY 255U +#define PTHREAD_DEFAULT_PRIORITY 1 + +/*Mutex initialization status*/ +#define PTHREAD_MUTEX_ATTR_UNINITIALIZED 0 +#define PTHREAD_MUTEX_ATTR_INITIALIZED 1 + +/*Conditional attributes initialization status*/ +#define PTHREAD_COND_ATTR_UNINITIALIZED 0 +#define PTHREAD_COND_ATTR_INITIALIZED 1 + +#define PTHREAD_DEFAULT_NAME "Anonymous" + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFFU) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFFU) + +/* mutex and cond_var shared */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* mutex type */ +#define PTHREAD_MUTEX_ERRORCHECK 0 +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT 3 + +/* mutex protocol */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_SPINLOCK_UNLOCKED 0 +#define PTHREAD_SPINLOCK_LOCKED 1 + +#define PTHREAD_ONCE_INIT (0) + +#define PTHREAD_MUTEX_OPAQUE //ToDo: amitkulk: debug + +typedef signed int ssize_t; + +/*detatchstate of a pthread*/ +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 0 + +/*contention scope*/ +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 + +/*scheduler*/ +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Types and structure definitions + * + */ +typedef unsigned int cpu_set_t; + +typedef unsigned int pthread_t; + +typedef struct pthread_attr_t +{ + void *stackaddr; + int internal_stack; /* this flag==1 means the stack needs to be freed by posix */ + size_t stacksize; + int priority; + unsigned short timetest_id; + /* This flag indicate if thread will be autostack thread*/ + unsigned short autostack:1; + /* This flag is to indicate thread's bus_priority high/low + bus_priority = 0 -- Bus_priority is low + bus_priority = 1 -- Bus_priority is high + bus_priority = 3 -- Bus_priority is default (takes the default set for the process) + */ + unsigned short bus_priority:2; + unsigned short reserved:13; + cpu_set_t cpumask; + char name[PTHREAD_NAME_LEN]; + /* This flag indicates whether pthread lib should create thread contexts for other OSALs */ + /* This is used internally by POSIX and not available for general usage */ + int ext_context; + int detachstate; +} pthread_attr_t; + +//mutex attr +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +struct pthread_mutexattr_t +{ + int is_initialized; + int type; + int pshared; + int protocol; +}; + +typedef unsigned int pthread_mutex_t; + +typedef unsigned int pthread_spinlock_t; + +typedef struct pthread_condattr_t +{ + int is_initialized; + int pshared; + clockid_t clock_id; +} pthread_condattr_t; + +typedef unsigned int pthread_cond_t; + +typedef struct pthread_barrierattr_t +{ + int is_initialized; + int pshared; +} pthread_barrierattr_t; + +typedef unsigned int pthread_barrier_t; + +typedef int pthread_key_t; + +typedef int pthread_once_t; + + +/*Read-Write locks*/ +#define PTW32_RWLOCK_MAGIC 0xfacade2 +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +#ifdef __cplusplus +} +#endif + +#endif /* _PTHERAD_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sched.h new file mode 100755 index 0000000000000..faf3365be9f82 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sched.h @@ -0,0 +1,21 @@ +/*============================================================================= + + sched.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include "sys/sched.h" + +#endif //__SCHED_H__ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/semaphore.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/semaphore.h new file mode 100755 index 0000000000000..d9145b295ae62 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/semaphore.h @@ -0,0 +1,114 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +/*========================================================================== + * FILE: semaphore.h + * + * SERVICES: POSIX semaphore API interface + * + * DESCRIPTION: POSIX semaphore API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ +#include // Get all C sys types - includes POSIX specific +#include "sys/errno.h" // error values + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** User facing semaphore container with opaque pointer to implementation */ +typedef struct +{ + unsigned int *opaque; +} sem_t; +#define _SEM_T + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* constant definitions */ +#define SEM_FAILED ((sem_t*) 0) + +/* @todo siqbal Should we put such configuration items in a common place + instead of this user-facing header? */ +#define SEM_VALUE_MAX ((unsigned int) 30) // If need be increase this + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/** \details + * POSIX standard comes with two kinds of semaphores: named and unnamed + * semaphores. + * + * This implementation of POSIX kernel API provide unnamed & named semaphore. + * + * + * sem_timedwait() is not provided. + */ + +/** \defgroup semaphore POSIX Semaphore API */ + +/** \ingroup semaphore */ +/** @{ */ + +/** Initialize an unnamed semaphore. + * Please refer to POSIX standard for details. + * @param pshared [in] This implementation does not support non-zero value, + * i.e., semaphore cannot be shared between processes in this implementation. + */ +int sem_init(sem_t *sem, int pshared, unsigned int value); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_wait(sem_t *sem); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_trywait(sem_t *sem); + +/** Unlock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_post(sem_t *sem); + +/** Get the value of a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_getvalue(sem_t *sem, int *value); + +/** Destroy an unnamed semaphore. + * Please refer to POSIX standard for details. + */ +int sem_destroy(sem_t *sem); + +/** creates and initializes a named semaphore. + * Please refer to POSIX standard for details. + */ +sem_t * sem_open(const char* name , int oflag , ...); + +/** closes a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_close(sem_t *sem); + +/** unlinkes a named semaphore. + * Please refer to POSIX standard for details. + */ +int sem_unlink(const char *name); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SEMAPHORE_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/signal.h new file mode 100755 index 0000000000000..35cb1f1a9a319 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/signal.h @@ -0,0 +1,201 @@ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/*========================================================================== + * FILE: signal.h + * + * SERVICES: POSIX Signal API interface + * + * DESCRIPTION: POSIX Signal API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX signal bits */ + +#define POSIX_MSG 7 /* POSIX msg type used in Qube API */ +#define POSIX_NOTIF 8 /* POSIX msg type used in Qube API */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ + +#define SIGRTMIN 10 +#define SIGRTMAX 32 + +/* Notification Types. */ +/* No asynchronous notification is delivered when the event of interest occurs. */ +#define SIGEV_NONE 0 +/* The signal specified in sigev_signo shall be generated for the process when + the event of interest occurs. */ +#define SIGEV_SIGNAL 1 +/* A notification function is called to perform notification. */ +#define SIGEV_THREAD 2 +#define SA_SIGINFO 1 + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +typedef unsigned long int sigset_t; + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent sigevent; +struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; +}; + +typedef struct siginfo_t siginfo_t; +struct siginfo_t +{ + int si_signo; + int si_code; + union sigval si_value; +/* int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band;*/ +}; +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_sigaction)(int, siginfo_t *, void *); +}; + +/* Signal functions */ + +/** \details + * This provides POSIX Signal API. Please note that this + * implementation does not fully comply with POSIX standard. + * + * In POSIX standard, Signal can be used as 'interrupt', which means + * an incoming signal will interrupt a running thread. After the + * registered signal handler is executed, the thread will resume. + * This behavior cannot be implemented w/o modifying L4 or QURT kernel. + * On the ohter hand, appliation need to be carefully written to avoid + * problems caused by 'interrupting' signals. + * + * Therefore, in this implementation of POSIX signal, thread will + * only receive signals when it explicitly waits for signals, i.e., when + * the thread calls either sigwait() or sigsuspend(). + * + * Therefore, pthread_sigmask(), which set or get signal mask for a thread, + * is not supported, since the signal mask will be set by sigwait() and + * sigsuspend(). + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * only threads can send and receive signals. The functions related to + * signal operations with processes, such as kill(), sigqueue(), + * sigprocmask(), are not provided. + * + * Queued signal is not supported. + * + * Applications will use signals from SIGRTMIN to SIGRTMAX. + * + * SIGEV_SIGNAL and SIGEV_THREAD are supported. SIGEV_NONE is not + * supported. + * + */ + +/** \defgroup signal POSIX Signal API */ +/** \ingroup signal */ +/** @{ */ + +/** Wait for signals. This implementation does not support queued signals. + * + * Please refer to POSIX standard for details. + */ +int sigwait(const sigset_t *restrict set, int *restrict sig); + +/** Examine and Change Signal Action. + * Please refer to POSIX standard for details. + * + * @param act [in] A pointer to the sigaction structure that describes the + * action to be taken for the signal. Can be NULL. + * The following flags for sa_flags field in struct sigaction are not + * supported: SA_NOCLDSTOP, SA_ONSTACK, SA_RESETHAND, SA_RESTART, + * SA_NOCLDWAIT and SA_NODEFER. Only flag SA_SIGINFO is supported. + * + * @note Define sigaction as macro to avoid a warning when included from + * C++ code - it's causing a "sigaction(...) hides constructor for + * 'struct sigaction'" warning. + */ +/*lint -esym(123,sigaction) Suppress "macro used with no arguments" */ +#define sigaction(sig,act,oact) _sigaction((sig),(act),(oact)) + +/** Wait for signals. + * Please refer to POSIX standard for details. + */ +int sigsuspend(const sigset_t *sigmask); + +/** Add Signal to Signal Set. + * Please refer to POSIX standard for details. + */ +int sigaddset(sigset_t *set, int signo); + +/** Delete Signal from Signal Set. + * Please refer to POSIX standard for details. + */ +int sigdelset(sigset_t *set, int signo); + +/** Initialize and Empty Signal Set. + * Please refer to POSIX standard for details. + */ +int sigemptyset(sigset_t *set); + +/** Initialize and Fill Signal Set. + * Please refer to POSIX standard for details. + */ +int sigfillset(sigset_t *set); + +/** Test for Signal in Signal Set. + * Please refer to POSIX standard for details. + */ +int sigismember(const sigset_t *set, int signo); + +/** @} */ + +/* this is not a public api function */ +int _sigaction(int sig, const struct sigaction *act, struct sigaction *oact); + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +/** Wait for the time interval specified in the timespec structure referenced + * by timeout. This implementation does not support queued signals. + * For struct siginfo_t, si_code and si_value are ignored in this implementation. + * + * Please refer to POSIX standard for details. + */ +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SIGNAL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/errno.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/errno.h new file mode 100755 index 0000000000000..b9edf57bab6c3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/errno.h @@ -0,0 +1,20 @@ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +/*========================================================================== + * FILE: errno.h + * + * SERVICES: POSIX errno header file + * + * DESCRIPTION: POSIX errno based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#ifndef EOK +#define EOK 0 +#endif + +#endif /* _SYS_ERRNO_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/sched.h new file mode 100755 index 0000000000000..2acc34d821725 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/sched.h @@ -0,0 +1,67 @@ +#ifndef _POSIX_SCHED_H_ +#define _POSIX_SCHED_H_ + +/*========================================================================== + * FILE: sched.c + * + * SERVICES: POSIX Thread sched API interface + * + * DESCRIPTION: POSIX Thread sched API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCHED_FIFO 0 /* First in, first out (FIFO) scheduling policy. */ +#define SCHED_RR 1 /* Round robin scheduling policy. */ +#define SCHED_SPORADIC 2 /* Sporadic server scheduling policy. */ +#define SCHED_OTHER 3 /* Another scheduling policy. */ + +typedef struct sched_param sched_param; +struct sched_param +{ + void *unimplemented; + int sched_priority; +}; + +/** \details + * This provides POSIX sched API. + */ + +/** \defgroup sched POSIX sched API */ +/** \ingroup sched */ +/** @{ */ + +/** Relinquish the CPU. + * Please refer to POSIX standard for details. + */ +static inline int sched_yield(void) +{ + return 0; +} + +/** Get the maximum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_max(int policy); + +/** Get the minimum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_min(int policy); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SCHED_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/types.h new file mode 100755 index 0000000000000..700026f9f9e4e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/sys/types.h @@ -0,0 +1,35 @@ +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/*========================================================================== + * FILE: types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#if !defined( _PID_T ) || !defined( __pid_t_defined ) +/* POSIX defines pid_t as signed 32-bit type. Hexagon toolchain's header + defines it as unsigned 32-bit type citing conflict with QuRT POSIX + compatibility later. If any such conflicts exist, we should fix them. + pid_t is being defined *BEFORE* inclusion of generic/sys/types.h + *INTENTIONALLY* to fix this */ +typedef int pid_t; +#define _PID_T +#define __pid_t_defined +#endif +#include +#include +#include +#include + +#ifndef __DEFINED_off_t +typedef long off_t; +#define __DEFINED_off_t +#endif + +#endif /* _SYS_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/time.h new file mode 100755 index 0000000000000..13aeb1ea9920d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/posix/time.h @@ -0,0 +1,142 @@ +#ifndef _POSIX_TIME_H_ +#define _POSIX_TIME_H_ + +/*========================================================================== + * FILE: time.h + * + * SERVICES: POSIX Timer API interface + * + * DESCRIPTION: POSIX Timer API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *==========================================================================*/ + + +#include + +typedef int clockid_t; /* ignored */ +#define _CLOCKID_T +#define _PROVIDE_POSIX_TIME_DECLS 1 +#include +/* @todo anandj sys/time.h has definition for struct timeval but is not + included by generic/time.h */ +#include + +#define CLOCK_FREQ_NOT_DEFINED -1 +/* Frequency of Sclk used */ +#define TIME_CONV_SCLK_FREQ 19200000 + +#define RES_CONV_FACTOR1 1 +#define RES_CONV_FACTOR2 1000000000 + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +#endif + +#if !defined(CLOCK_MONOTONIC) +# define CLOCK_MONOTONIC 1 +#endif + +#if !defined(CLOCK_THREAD_CPUTIME_ID) +# define CLOCK_THREAD_CPUTIME_ID 2 +#endif + +#if !defined(CLOCK_PROCESS_CPUTIME_ID) +# define CLOCK_PROCESS_CPUTIME_ID 3 +#endif + +#if !defined(CLOCK_MONOTONIC_RAW) +# define CLOCK_MONOTONIC_RAW 4 +#endif + +#if !defined(CLOCK_REALTIME_COARSE) +# define CLOCK_REALTIME_COARSE 5 +#endif + +#if !defined(CLOCK_MONOTONIC_COARSE) +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +#if !defined(CLOCK_BOOTTIME) +# define CLOCK_BOOTTIME 7 +#endif + +struct itimerspec +{ + struct timespec it_interval; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer functions */ + +/** \details + * POSIX timers can be either of two types: a one-shot type or a periodic + * type. + * + * A one-shot is an armed timer that is set to an expiration time relative + * to either a current time or an absolute time. The timer expires once and + * is disarmed. + * + * A periodic timer is armed with an initial expiration time and a repetition + * interval. Every time the interval timer + * expires, the timer is reloaded with the repetition interval. The timer + * is then rearmed. + */ + +/** \defgroup timer POSIX Timer API */ + +/** \ingroup timer */ +/** @{ */ + +/** Create a POSIX timer. + * Please refer to POSIX standard for details. + * @param clockid [in] ignored in this implementation + * @param evp [in] if non-NULL, points to a sigevent structure. This + * structure, allocated by the application, defines the asynchronous + * notification to occur when the timer expires. If the evp argument is + * NULL, the effect is as if the evp argument pointed to a sigevent + * structure with the sigev_notify member having the value SIGEV_SIGNAL, + * the sigev_signo having a default signal number (SIGALRM), and the + * sigev_value member having the value of the timer ID. + */ +int timer_create(clockid_t clockid, struct sigevent *restrict evp, + timer_t *restrict timerid); + +/** Delete a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_delete(timer_t timerid); + +/** Get the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_gettime(timer_t timerid, struct itimerspec *value); + + +/** Set the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + * @param flags [in] ignored in this implementation + */ +int timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); +/** Obtain ID of a process CPU-time clock + * @param pid [in] Process ID + * @param clock_id [out] Clock ID + * @return Error values as per POSIX standard + */ +int clock_getcpuclockid (pid_t pid, clockid_t * clock_id); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_TIME_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qube/qube.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qube/qube.h new file mode 100755 index 0000000000000..1e31e2deedb38 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qube/qube.h @@ -0,0 +1,51 @@ +#ifndef QUBE_H +#define QUBE_H +/*============================================================================= + + qube.h -- H E A D E R F I L E + +GENERAL DESCRIPTION + Prototypes of qpd API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Define Error codes as QuRT error codes preceed with QURT_ */ +#ifndef EOK +#define EOK QURT_EOK +#endif /* EOK */ +#ifndef EVAL +#define EVAL QURT_EVAL +#endif /* EVAL */ +#ifndef EMEM +#define EMEM QURT_EMEM +#endif /* EMEM */ +#ifndef EINVALID +#define EINVALID QURT_EINVALID +#endif /* EINVALID */ + + +/*============================================================================= + FUNCTION DECLARATIONS +=============================================================================*/ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QUBE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops.h new file mode 100755 index 0000000000000..0a9a9f8ba7db5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops.h @@ -0,0 +1,197 @@ +#ifndef ATOMIC_OPS_H +#define ATOMIC_OPS_H +/** + @file atomic_ops.h + + @brief Type definitions backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * Author: Carlos Dyonisio + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_plain_word_t; + +/*-------------------------------------------------------------------------*/ + /* Atomic Ops API. */ + +/* + * IMPORTANT! + * If you plan to change the structure atomic_word_t, please add the new + * elements after value. For more information, read the comment in + * arch/arm/libs/atomic_ops/v5/src/arm_atomic_ops.spp:66 + */ + +typedef struct { + volatile atomic_plain_word_t value; +} atomic_word_t; + +#define ATOMIC_INIT(i) { (i) } + +static inline void +atomic_init(atomic_word_t *a, atomic_plain_word_t v) +{ + a->value = v; +} + +#if defined(ARCH_ARM) && defined(ARCH_VER) && (ARCH_VER < 6) && \ + (!defined(__ATOMIC_OPS_IN_KERNEL__) || defined(MACHINE_SMP)) + +/* + * If it is ARMv4/v5, the function declarations may change + * and are defined in the arch specific header file, + * as some of then cannot be declared static because of + * the assembler implementation. + */ + +#else + +/* Arithmetic operations. */ + +void atomic_sub(atomic_word_t *target, atomic_plain_word_t v); + +/* Architecture independent definitions. */ + +static inline atomic_plain_word_t atomic_read(atomic_word_t *target) +{ + return target->value; +} + +typedef unsigned long long atomic64_plain_word_t; + +typedef struct { + volatile atomic64_plain_word_t value; +} atomic64_word_t; + +static inline void +atomic64_init(atomic64_word_t *a, atomic64_plain_word_t v) +{ + a->value = v; +} + +/********************* + Support 64-bit + *********************/ + +atomic64_plain_word_t atomic64_set(atomic64_word_t* target, + atomic64_plain_word_t value); + +void atomic64_xor(atomic64_word_t* target, + atomic64_plain_word_t mask); + +/*---------------------------------------------------------------------------*/ + +/* Architecture independent definitions. */ + +static inline atomic64_plain_word_t atomic64_read(atomic64_word_t *target) +{ + return target->value; +} + +#endif + + +/* Architecture dependent definitions. */ +#include + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops_plat.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops_plat.h new file mode 100755 index 0000000000000..b54b3ff83d978 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/atomic_ops_plat.h @@ -0,0 +1,86 @@ +#ifndef ATOMIC_OPS_PLAT_H +#define ATOMIC_OPS_PLAT_H +/** + @file atomic_ops_plat.h + + @brief Prototypes of atomic operations API backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define atomic_set(a,b) qurt_atomic_set((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and(a,b) qurt_atomic_and((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and_return(a,b) qurt_atomic_and_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or(a,b) qurt_atomic_or((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or_return(a,b) qurt_atomic_or_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor(a,b) qurt_atomic_xor((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor_return(a,b) qurt_atomic_xor_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_set_bit(a,b) qurt_atomic_set_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_clear_bit(a,b) qurt_atomic_clear_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_change_bit(a,b) qurt_atomic_change_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add(a,b) qurt_atomic_add((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_return(a,b) qurt_atomic_add_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_unless(a,b,c) qurt_atomic_add_unless((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_sub(a,b) qurt_atomic_sub((unsigned int *)(a),(unsigned int)(b)) +#define atomic_sub_return(a,b) qurt_atomic_sub_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_inc(a) qurt_atomic_inc((unsigned int *)(a)) +#define atomic_inc_return(a) qurt_atomic_inc_return((unsigned int *)(a)) +#define atomic_dec(a) qurt_atomic_dec((unsigned int *)(a)) +#define atomic_dec_return(a) qurt_atomic_dec_return((unsigned int *)(a)) +#define atomic_compare_and_set(a,b,c) qurt_atomic_compare_and_set((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_barrier qurt_atomic_barrier +#define atomic_barrier_write qurt_atomic_barrier_write +#define atomic_barrier_write_smp qurt_atomic_barrier_write_smp +#define atomic_barrier_read_smp qurt_atomic_barrier_read_smp +#define atomic_barrier_smp qurt_atomic_barrier_smp + +/*============================ + * 64 bits support + *============================ */ +#define atomic64_set(a,b) qurt_atomic64_set((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and(a,b) qurt_atomic64_and((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and_return(a,b) qurt_atomic64_and_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or(a,b) qurt_atomic64_or((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or_return(a,b) qurt_atomic64_or_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor(a,b) qurt_atomic64_xor((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor_return(a,b) qurt_atomic64_xor_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_set_bit(a,b) qurt_atomic64_set_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_clear_bit(a,b) qurt_atomic64_clear_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_change_bit(a,b) qurt_atomic64_change_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add(a,b) qurt_atomic64_add((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add_return(a,b) qurt_atomic64_add_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub(a,b) qurt_atomic64_sub((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub_return(a,b) qurt_atomic64_sub_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_inc(a) qurt_atomic64_inc((unsigned long long *)(a)) +#define atomic64_inc_return(a) qurt_atomic64_inc_return((unsigned long long *)(a)) +#define atomic64_dec(a) qurt_atomic64_dec((unsigned long long *)(a)) +#define atomic64_dec_return(a) qurt_atomic64_dec_return((unsigned long long *)(a)) +#define atomic64_compare_and_set(a,b,c) qurt_atomic64_compare_and_set((unsigned long long *)(a),(unsigned long long )(b),(unsigned long long )(c)) +#define atomic64_barrier qurt_atomic64_barrier +#define atomic64_barrier_write qurt_atomic64_barrier_write +#define atomic64_barrier_write_smp qurt_atomic64_barrier_write_smp +#define atomic64_barrier_read_smp qurt_atomic64_barrier_read_smp +#define atomic64_barrier_smp qurt_atomic64_barrier_smp + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_PLAT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt.h new file mode 100755 index 0000000000000..4d25c9b2b6243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt.h @@ -0,0 +1,111 @@ +#ifndef QURT_H +#define QURT_H + +/** + @file qurt.h + @brief Contains kernel header files that provide kernel OS API functions, constants, and + definitions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013,2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +/*====================================================================== + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Notice that changes are listed in reverse chronological + * order. + * + * + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------ + * 2011-02-25 op Add Header file + 2012-12-16 cm (Tech Pubs) Edited/added Doxygen comments and markup. + ======================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "qurt_consts.h" +#include "qurt_api_version.h" +#include "qurt_alloc.h" +#include "qurt_futex.h" +#include "qurt_mutex.h" +#include "qurt_pipe.h" +#include "qurt_printf.h" +#include "qurt_assert.h" +#include "qurt_thread.h" +#include "qurt_trace.h" +#include "qurt_cycles.h" +#include "qurt_profile.h" +#include "qurt_sem.h" +#include "qurt_cond.h" +#include "qurt_barrier.h" +#include "qurt_fastint.h" +#include "qurt_allsignal.h" +#include "qurt_anysignal.h" +#include "qurt_signal.h" +#include "qurt_rmutex.h" +#include "qurt_pimutex.h" +#include "qurt_signal2.h" +#include "qurt_rmutex2.h" +#include "qurt_pimutex2.h" +#include "qurt_int.h" +#include "qurt_lifo.h" +#include "qurt_power.h" +#include "qurt_event.h" +#include "qurt_pmu.h" +#include "qurt_stid.h" +//#include "qurt_version.h" +#include "qurt_tlb.h" +#include "qurt_vtlb.h" +#include "qurt_memory.h" +#include "qurt_qdi.h" +#include "qurt_sclk.h" +#include "qurt_space.h" +#include "qurt_process.h" +#include "qurt_timer.h" +#include "qurt_tls.h" +#include "qurt_thread_context.h" +#include "qurt_hvx.h" +#include "qurt_hmx.h" +#include "qurt_mailbox.h" +#include "qurt_island.h" +#include "qurt_qdi_proxy.h" +#include "qurt_l2cfg.h" +#include "qurt_mmap.h" +#include "qurt_isr.h" +#include "qurt_busywait.h" +#include "qurt_ecc.h" +#include "qurt_callback.h" +#include "qurt_error.h" +#include "qurt_except.h" +#include "qurt_mq.h" +#include "qurt_user_dma.h" +#include "qurt_fs_hub.h" +#include "qurt_os_services.h" + +#ifndef MAIN_ONLY +#define INCLUDE_ISLAND_CONTENTS +#endif +#ifndef ISLAND_ONLY +#define INCLUDE_MAIN_CONTENTS +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_alloc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_alloc.h new file mode 100755 index 0000000000000..da37a4c0a714e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_alloc.h @@ -0,0 +1,145 @@ +#ifndef QURT_ALLOC_H +#define QURT_ALLOC_H + +/** + @file qurt_alloc.h + @brief Prototypes of kernel memory allocation API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_malloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated memory area. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] size Size (in bytes) of the memory area. + + @return + Nonzero -- Pointer to the allocated memory area. \n + 0 -- Not enough memory in heap to allocate memory area. + + @dependencies + None. + + */ +/* ======================================================================*/ +void *qurt_malloc( unsigned int size); + +/*======================================================================*/ +/**@ingroup func_qurt_calloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated array. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] elsize Size (in bytes) of each array element. + @param[in] num Number of array elements. + + @return + Nonzero -- Pointer to allocated array.\n + Zero -- Not enough memory in heap to allocate array. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_calloc(unsigned int elsize, unsigned int num); + +/*======================================================================*/ +/**@ingroup func_qurt_realloc + Reallocates memory on the heap. \n + Changes the size of a memory area that is already allocated on the QuRT system heap. + The reallocate memory operation is functionally similar to realloc. It accepts a pointer + to an existing memory area on the heap, and resizes the memory area to the specified size + while preserving the original contents of the memory area. + + @note1hang This function might change the address of the memory area. + If the value of ptr is NULL, this function is equivalent to + qurt_malloc(). + If the value of new_size is 0, it is equivalent to qurt_free(). + If the memory area is expanded, the added memory is not initialized. + + @param[in] *ptr Pointer to the address of the memory area. + @param[in] newsize Size (in bytes) of the reallocated memory area. + + @return + Nonzero -- Pointer to reallocated memory area. \n + 0 -- Not enough memory in heap to reallocate the memory area. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_realloc(void *ptr, int newsize); + +/*======================================================================*/ +/**@ingroup func_qurt_free + Frees allocated memory from the heap.\n + Deallocates the specified memory from the QuRT system heap. + + @param[in] *ptr Pointer to the address of the memory to deallocate. + + @return + None. + + @dependencies + The memory item that the ptr value specifies must have been previously + allocated using one of the qurt_calloc(), + qurt_malloc(), or qurt_realloc() memory allocation functions. + Otherwise the behavior of QuRT is undefined. + + */ + /* ======================================================================*/ +void qurt_free( void *ptr); + + +void *qurt_memalign(unsigned int alignment, unsigned int size); + +/* +|| Macro to define a static heap for a QuRT program. +|| +|| Usage: +|| Declare at the top-level of any C source file that +|| is part of the build (and is guaranteed +|| to actually be pulled into the build). Place +|| it in the same function with main(): +|| +|| QURT_DECLARE_STATIC_HEAP(512000); +|| +|| The only argument is the size in bytes, and it is +|| rounded up to the nearest 64 bytes (size of an +|| L2 cache block). +|| +*/ + +#define QURT_DECLARE_STATIC_HEAP(sz) \ + static struct qurt_static_heap { \ + char space[(sz)] __attribute__((aligned(64))); \ + } static_heap[1]; \ + void * const override_heap_Base = &static_heap[0]; \ + void * const override_heap_Limit = &static_heap[1] + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLOC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_allsignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_allsignal.h new file mode 100755 index 0000000000000..5dc89e495130d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_allsignal.h @@ -0,0 +1,176 @@ + +#ifndef QURT_ALLSIGNAL_H +#define QURT_ALLSIGNAL_H + +/** + @file qurt_allsignal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup all_signal_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** +qurt_signal_t supersedes qurt_allsignal_t. This type definition was added for backwards compatibility. */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int waiting; /**< */ + unsigned int signals_in; /**< */ + unsigned int queue; /**< */ + unsigned int reserved; /**< */ + }X; + /** @endcond */ +} qurt_allsignal_t; +/** @} */ /* end_addtogroup all_signal_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_init + Initializes an all-signal object.\n + The all-signal object is initially cleared. + + @datatypes + #qurt_allsignal_t + + @param[out] signal Pointer to the all-signal object to initialize. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_init(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_destroy + Destroys the specified all-signal object.\n + @note1hang All-signal objects must be destroyed when they are no longer in use. + Failure to do this causes resource leaks in the QuRT kernel. \n + @note1cont All-signal objects must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_destroy(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_get + Gets signal values from the all-signal object. + + Returns the current signal values of the specified all-signal object. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to access. + + @return + Bitmask with current signal values. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_allsignal_get(qurt_allsignal_t *signal) +{ return signal->X.signals_in; } + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_wait + Waits on the all-signal object.\n + Suspends the current thread until all of the specified signals are set. + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 that it is not to be waited on. + + If a signal is set in an all-signal object, and a thread is waiting on the all-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + Unlike any-signals, all-signals do not need to explicitly clear any set signals in an all-signal + object before waiting on them again -- clearing is done automatically by the wait + operation. + + @note1hang At most, one thread can wait on an all-signal object at any given time. + Because signal clearing is done by the wait operation, no clear operation is + defined for all-signals. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to wait on. + @param[in] mask Signal mask value, which identifies the individual signals in the all-signal object + to wait on. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_wait(qurt_allsignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_set + Set signals in the specified all-signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit + value of 1 indicates that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the all-signal object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_set(qurt_allsignal_t *signal, unsigned int mask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLSIGNAL_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_anysignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_anysignal.h new file mode 100755 index 0000000000000..9619e2de562b4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_anysignal.h @@ -0,0 +1,225 @@ +#ifndef QURT_ANYSIGNAL_H +#define QURT_ANYSIGNAL_H +/** + @file qurt_anysignal.h + Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +Copyright (c) 2021 Qualcomm Technologies, Inc. +All rights reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== +Typedefs +======================================================================*/ + +/**@ingroup anysignals_types + qurt_signal_t supersedes qurt_anysignal_t. This type definition was added for backwards compatibility. */ +typedef qurt_signal_t qurt_anysignal_t; + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_init + Initializes an any-signal object.\n + The any-signal object is initially cleared. + + @datatypes + #qurt_anysignal_t + + @param[out] signal Pointer to the initialized any-signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_init(qurt_anysignal_t *signal) +{ + qurt_signal_init(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_destroy + Destroys the specified any-signal object. + + @note1hang Any-signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Any-signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_destroy(qurt_anysignal_t *signal) +{ + qurt_signal_destroy(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait + Wait on the any-signal object. \n + Suspends the current thread until any one of the specified signals is set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread is waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + + @return + Bitmask of current signal values. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_wait(qurt_anysignal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_set + Sets signals in the specified any-signal object. \n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be set, and 0 indicates not to set the sigmal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the any-signal object. + + @return + Bitmask of old signal values (before set). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_set(qurt_anysignal_t *signal, unsigned int mask); + + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_get + Gets signal values from the any-signal object.\n + Returns the current signal values of the specified any-signal object. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to access. + + @return + A bitmask with the current signal values of the specified any-signal object. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_get(qurt_anysignal_t *signal) +{ + return qurt_signal_get(signal); +} + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_clear + @xreflabel{sec:anysignal_clear} + Clears signals in the specified any-signal object.\n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object, which specifies the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + clear in the any-signal object. + + @return + Bitmask -- Old signal values (before clear). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_clear(qurt_anysignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait_timed + Waits on the any-signal object. \n + Suspends the current thread until any of the specified signals is set or timeout expires. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread was waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + @param[out] signals Bitmask of current signal values. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- timeout + #QURT_EINVALID -- Duration out of range + + @dependencies + None. + */ +/* ======================================================================*/ + +int qurt_anysignal_wait_timed(qurt_anysignal_t *signal, unsigned int mask, unsigned int *signals, unsigned long long int duration); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ANYSIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_api_version.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_api_version.h new file mode 100755 index 0000000000000..dfe53ae755054 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_api_version.h @@ -0,0 +1,77 @@ +#ifndef QURT_API_VERSION_H +#define QURT_API_VERSION_H +/*============================================================================== + +qurt_api_version.h + +GENERAL DESCRIPTION + API version file + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +/*============================================================================== + CONSTANTS AND DEFINITIONS +==============================================================================*/ +/** + * Each field of the QURT_API_VERSION definitions is an 8-bit unsigned integer. + * Main release has first 3 fields updated - Major, Minor and Release. + * - QURT_API_VERSION = Major, Minor, Release. + * Patch releases are supported by adding the extra field. + * - QURT_API_VERSION = Major, Minor, Release, Patch. + */ +// Major version is incremented for incompatible API changes. +#define QURT_API_VER_MAJOR 1 + +// Minor version is incremented for backward-compatible enhancements in the API +// set. +#define QURT_API_VER_MINOR 4 + +// RELEASE version is incremented for each release within a `MAJOR.MINOR` +// release. +#define QURT_API_VER_RELEASE 1 + +// Patch version is incremented when new API content is introduced on older LTS +// release. +#define QURT_API_VER_PATCH 0 + +/* Update the QURT_API_VERSION function macro. */ +#define QURT_API_VERSION_ENCODE(major, minor, release, patch) \ + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | \ + (((release) & 0xFF) << 8) | ((patch) & 0xFF)) + +/* Update the QURT_API_VERSION Macro. */ +#define QURT_API_VERSION \ + QURT_API_VERSION_ENCODE(QURT_API_VER_MAJOR, QURT_API_VER_MINOR, \ + QURT_API_VER_RELEASE, QURT_API_VER_PATCH) + +/** Usage: + * + * #if QURT_API_VERSION >= QURT_API_VERSION_ENCODE(1,4,0,0) + * qurt_func_2(a,b,c); + * #else + * qurt_func(a); + * #endif + * + */ +/* + Gets the QuRT API version. + + @return + QuRT API version. + + @dependencies + None. + */ +unsigned int qurt_api_version(void); + +#endif /* QURT_API_VERSION_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_assert.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_assert.h new file mode 100755 index 0000000000000..13cc2afd2e973 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_assert.h @@ -0,0 +1,51 @@ +#ifndef QURT_ASSERT_H +#define QURT_ASSERT_H +/** + @file qurt_assert.h + @brief Prototypes of qurt_assert API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@ingroup func_qurt_assert_error + Writes diagnostic information to the debug buffer, and raises an error to the QuRT kernel. + + @datatypes + None. + + @param[in] filename Pointer to the file name string. + @param[in] lineno Line number. + + @return + None. + + @dependencies + None. + */ +void qurt_assert_error(const char *filename, int lineno) __attribute__((noreturn)); + +#define qurt_assert(cond) ((cond)?(void)0:qurt_assert_error(__QURTFILENAME__,__LINE__)) + +/** @} */ /* end_ingroup func_qurt_assert */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ASSERT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_atomic_ops.h new file mode 100755 index 0000000000000..d9b2cff7d737c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_atomic_ops.h @@ -0,0 +1,1298 @@ +#ifndef QURT_ATOMIC_OPS_H +#define QURT_ATOMIC_OPS_H +/** + @file qurt_atomic_ops.h + @brief Prototypes of kernel atomic operations API. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * + * This file is only included by the main atomic_ops.h, so all of that + * file's definitions are available. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +///* Sanity check to ensure the smp flag is set in machines.py */ +//#if defined(__ATOMIC_OPS_IN_KERNEL__) && !defined(MACHINE_SMP) && CONFIG_NUM_UNITS > 1 +//#error CONFIG_NUM_UNITS > 1 but smp not defined in machines.py. +//#endif +#define QURT_INLINE __attribute__((always_inline)) + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_atomic_set + Sets the atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value Value to set. + + @return + Value successfuly set. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_set(unsigned int* target, unsigned int value) +{ + unsigned long tmp; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " memw_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic_and + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + None + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_and(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_and_return + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + AND result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_and_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_or + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_or(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_or_return + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + Returns the OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_or_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_xor + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_xor(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_xor_return + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_xor_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_set_bit + Sets a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_set_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_clear_bit + Clears a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_clear_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_change_bit + Toggles a bit in a atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_change_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1fU; + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_add(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add_return + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_add_unless + Adds the delta value to an atomic variable unless the current value in the target + matches the unless variable. + + @note1hang The function retries until load lock and store conditional + are successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] delta Value to add to the current value. + @param[in] unless Perform the addition only when the current value is not + equal to this unless value. + @return + TRUE -- 1 - Addition was performed. \n + FALSE -- 0 - Addition was not done. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_unless(unsigned int* target, + unsigned int delta, + unsigned int unless) +{ + unsigned int current_val; + unsigned int new_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%3)\n" + " p0 = cmp.eq(%0, %5)\n" + " if p0 jump 2f\n" + " %1 = add(%0, %4)\n" + " memw_locked(%3, p0) = %1\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"=&r" (new_val),"+m" (*target) + : "r" (target), "r" (delta), "r" (unless) + : "p0"); + + return (unsigned int)(current_val != unless); +} + +/**@ingroup func_qurt_atomic_sub + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_sub(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_sub_return + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_sub_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_inc + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_inc(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_inc_return + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_inc_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_dec + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_dec(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_dec_return + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_dec_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_compare_and_set + Compares the current value of the atomic variable with the + specified value and set to a new value when compare is successful. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val Old value to compare. + @param[in] new_val New value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE --Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_compare_and_set(unsigned int* target, + unsigned int old_val, + unsigned int new_val) +{ + unsigned int current_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memw_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (unsigned int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic_barrier + Allows the compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_barrier(void) +{ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); +} + + +/**@ingroup func_qurt_atomic64_set + Sets the 64-bit atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value 64-bit value to set. + + @return + Successfuly set value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_set(unsigned long long* target, unsigned long long value) +{ + unsigned long long tmp; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " memd_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic64_and_return + Bitwise AND operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise AND. + + @return + AND result of 64-bit atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_and_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_or + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_or(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_or_return + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_or_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_xor_return + Bitwise XOR operation of 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_xor_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_set_bit + Sets a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_set_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_clear_bit + Clears a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_clear_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_change_bit + Toggles a bit in a 64-bit atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_change_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_add(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add_return + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_add_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_sub_return + Subtracts a 64-bit integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_sub_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_inc + Increments a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_inc(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_inc_return + Increments a 64-bit atomic variable by one + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_inc_return(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_dec_return + Decrements a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_dec_return(unsigned long long *target) +{ + unsigned long long result; + long long minus1 = 0xFFFFFFFFFFFFFFFFLL; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (minus1) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_compare_and_set + Compares the current value of an 64-bit atomic variable with + the specified value and sets to a new value when compare is successful. + + @note1hang The function keep retrying until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val 64-bit old value to compare. + @param[in] new_val 64-bit new value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE -- Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE int +qurt_atomic64_compare_and_set(unsigned long long *target, + unsigned long long old_val, + unsigned long long new_val) +{ + unsigned long long current_val; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memd_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic64_barrier + Allows compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_barrier(void) +{ + /** @cond */ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); + /** @endcond */ +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_barrier.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_barrier.h new file mode 100755 index 0000000000000..7c6f787d43bc2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_barrier.h @@ -0,0 +1,140 @@ +#ifndef QURT_BARRIER_H +#define QURT_BARRIER_H + +/** + @file qurt_barrier.h + @brief Prototypes of Kernel barrier API functions. + + EXTERNALIZED FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup barrier_types +@{ */ +/*===================================================================== + Constants and macros +======================================================================*/ +#define QURT_BARRIER_SERIAL_THREAD 1 /**< Serial thread. */ +#define QURT_BARRIER_OTHER 0 /**< Other. */ + +#ifndef ASM +#include + +/*===================================================================== +Typedefs +======================================================================*/ + +/** QuRT barrier type. + */ +typedef union { + /** @cond */ + struct { + unsigned short threads_left; + unsigned short count; + unsigned int threads_total; + unsigned int queue; + unsigned int reserved; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_barrier_t; + +/** @} */ /* end_addtogroup barrier_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_init + Initializes a barrier object. + + @datatypes + #qurt_barrier_t + + @param[out] barrier Pointer to the barrier object to initialize. + @param[in] threads_total Total number of threads to synchronize on the barrier. + + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_init(qurt_barrier_t *barrier, unsigned int threads_total); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_destroy + Destroys the specified barrier. + + @note1hang Barriers must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Barriers must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to destroy. + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_destroy(qurt_barrier_t *barrier); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_wait + Waits on the barrier.\n + Suspends the current thread on the specified barrier. \n + The function return value indicates whether the thread was the last one to + synchronize on the barrier. + When a thread waits on a barrier, it is suspended on the barrier: \n + - If the total number of threads waiting on the barrier is less than the assigned value + of the barrier, no other action occurs. \n + - If the total number of threads waiting on the barrier equals the assigned value of the + barrier, all threads currently waiting on the barrier are awakened, allowing them to + execute past the barrier. + + @note1hang After its waiting threads are awakened, a barrier is automatically reset + and can be used again in the program without the need for re-initialization. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to wait on. + + @return + #QURT_BARRIER_OTHER -- Current thread awakened from barrier. \n + #QURT_BARRIER_SERIAL_THREAD -- Current thread is last caller of barrier. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_wait(qurt_barrier_t *barrier); + + +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BARRIER_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_busywait.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_busywait.h new file mode 100755 index 0000000000000..a4dab80a2520a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_busywait.h @@ -0,0 +1,62 @@ +#ifndef QURT_BUSYWAIT_H +#define QURT_BUSYWAIT_H + +/** + @file qurt_busywait.h + @brief Implementation of the busywait() function for + hardware based blocking waits that use the QTIMER as a reference. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ============================================================================*/ +/*============================================================================= + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Changes are listed in reverse chronological + * order. + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------------- + * 2018-03-20 pg Add Header file + ============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_busywait + Pauses the execution of a thread for a specified time.\n + Use for small microsecond delays. + + @note1hang The function does not return to the caller until + the time duration has expired. + + @param[in] pause_time_us Time to pause in microseconds. + + @return + None. + + @dependencies + None. + */ +void qurt_busywait (unsigned int pause_time_us); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BUSYWAIT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_callback.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_callback.h new file mode 100755 index 0000000000000..dc9b896c63454 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_callback.h @@ -0,0 +1,235 @@ +#ifndef QURT_CALLBACK_H +#define QURT_CALLBACK_H + +/** + @file qurt_callback.h + Definitions, macros, and prototypes for QuRT callback framework. + + QDI framework allows the development of root process drivers and services that + a user process client can interact with in a secure manner. QDI framework does + this by elevating the priviledge of user process thread, temporarily allowing + the thread execute in root context and letting it fall back to user context once + the QDI invocation is finished. + + The QuRT callback framework provides a safe mechanism for root process drivers + to execute callback functions in a user process. The framework hosts + dedicated worker threads in corresponding processes that handle the execution + of the callback function. This ensures that the callbacks occur in context of + the appropriate process thread, in result maintaining privilege boundaries. + + Prerequisites for use of this framework are: + 1. Driver is a QDI driver and client communicates with drivers using QDI + invocations. + 2. Appropriate callback configuration is specified in cust_config.xml for + the user process that intends to use this framework. + + qurt_cb_data_t is the public data structure that allows client to store all + the required information about the callback, including the callback function + and the arguments to pass to this function when it executes. + The client uses QDI interface to register this structure with root driver. + + Callback framework provides following APIs that a root driver can use to invoke callback. + These functions are described in qurt_qdi_driver.h header file. + + qurt_qdi_cb_invoke_async() triggers an asynchronous callback wherein the + invoking thread does not wait for the callback to finish executing. + + qurt_qdi_cb_invoke_sync() triggers a synchronous callback. Upon invocation + the invoking thread gets suspended till the callback function finishes execution. + + qurt_qdi_cb_invoke_sync_with_data() invokes a synchronous callback similar to + qurt_qdi_cb_invoke_sync(). It allows user to pass large data along with + the callback invocation to be utlized during the callback execution. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int qurt_cb_result_t; + +/* Callback framework error codes. + Callback framework returns a nonzero value if callback invocation is unsuccessful. + Following macros highlight cause of failure in more detail. +*/ +#define QURT_CB_ERROR -1 /* Callback registration failed.\n*/ +#define QURT_CB_OK 0 /* Success.\n*/ +#define QURT_CB_MALLOC_FAILED -2 /* QuRTOS malloc failure.\n*/ +#define QURT_CB_WAIT_CANCEL -3 /* Process exit cancelled wait operation.\n*/ +#define QURT_CB_CONFIG_NOT_FOUND -4 /* Callback configuration for process was not found.\n*/ +#define QURT_CB_QUEUE_FULL -5 /* Callback queue is serving at maximum capacity.*/ +/** @addtogroup cb_types +@{ */ +/** Callback registration data structure. + This data structure is used by a client attempting to register a callback with a QDI driver. + It holds the address of callback function and the argument supplied to the callback + function when it executes. +*/ +typedef struct { + /** @cond */ + void* cb_func; /*< Pointer to the callback function. */ + unsigned cb_arg; /*< Not interpreted by the framework.*/ + /** @endcond */ +} qurt_cb_data_t; + +/** @cond */ +/* Defines used as default if cust_config does not specify them. */ +#define CALLBACK_WORKER_STACK_SIZE 0x2000 +/** @endcond */ +/** @} */ /* end_addtogroup cb_typess */ +/**@ingroup func_qurt_cb_data_init + Initializes the callback data structure. + Entity registering a callback with the root process driver must call this function + to initialize callback registration data structure to the default value. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_init (qurt_cb_data_t* cb_data){ + cb_data->cb_func = NULL; + cb_data->cb_arg = 0; +} + +/**@ingroup func_qurt_cb_data_set_cbfunc + Sets up the callback function in the callback registration data structure. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_func Pointer to the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbfunc (qurt_cb_data_t* cb_data, void* cb_func){ + cb_data->cb_func = cb_func; +} + +/**@ingroup func_qurt_cb_data_set_cbarg + Sets up the callback argument. + This function sets up the argument passed to the callback function when it executes. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_arg Argument for the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbarg (qurt_cb_data_t* cb_data, unsigned cb_arg){ + cb_data->cb_arg = cb_arg; +} + +/** @cond */ +/**@ingroup driver_support_functions + Invokes an asynchronous callback for a specified process. + A driver that resides in the root process calls this API to launch a callback in + a process described by the client_handle. + After the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is not suspended during the callback execution period. + The API returns immediately with a success/failure error code. + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_async(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process. + A driver that resides in a root process calls this API to launch a sync callback in + a process described by the client_handle. + AFter the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is suspended during the callback execution period. + If the process in which to execute the callback exits or terminates, the caller is + woken up with error code #QURT_CB_WAIT_CANCEL (refer to qurt_callback.h). + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process, passing driver data to the user PD. + This function is similar to qurt_qdi_cb_invoke_sync() and allows the driver to pass arbitrary data to + the user process as part of the callback invocation. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @param data Driver arbitrary data to pass to the user process. Memory pointed to by data + must be accessible to the user PD. The root driver can allocate such memory by + using qurt_mem_mmap(). + @param data_len Driver arbitrary data length. + + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync_with_data( int client_handle, + qurt_cb_data_t* cb_data, + int prio, + void *data, + unsigned data_len + ); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_clade.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_clade.h new file mode 100755 index 0000000000000..d7442cf98dd94 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_clade.h @@ -0,0 +1,62 @@ +#ifndef QURT_CLADE_H +#define QURT_CLADE_H +/** + @file qurt_clade.h + @brief Prototypes of Cache Line Accelerated Decompression Engine (CLADE) API. + CLADE is a cache line level memory compression system that is used to + decrease DRAM usage. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_clade2_get + Reads the value of the clade2 register. + + @param[in] offset Offset from the clade2 cfg base. + @param[out] *value Pointer to the register value read from the offset. + + @return + #QURT_EOK - Successfully read the value from the register at offset \n + #QURT_EINVALID - Offset passed is incorrect + + @dependencies + None. + */ +int qurt_clade2_get(unsigned short offset, unsigned int *value); + +/**@ingroup func_qurt_clade2_set + Sets the PMU register; only PMU_SEL register can be set. + + @param[in] offset Offset from the QURTK_clade2_cfg_base. + @param[in] value Value to set at offset. + + @return + #QURT_EOK -- Successfully set the value at offset. \n + #QURT_ENOTALLOWED -- Set operation performed at an offset other than CLADE2_PMU_SELECTION_REG. + + @dependencies + None. + */ +int qurt_clade2_set(unsigned short offset, unsigned int value); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CLADE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cond.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cond.h new file mode 100755 index 0000000000000..6e65ed82a8393 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cond.h @@ -0,0 +1,219 @@ +#ifndef QURT_COND_H +#define QURT_COND_H +/** + @file qurt_cond.h + @brief Prototypes of kernel condition variable object API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup condition_variables_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** QuRT condition variable type. */ +typedef union { + /** @cond */ + unsigned long long raw; + struct { + unsigned int count; + unsigned int n_waiting; + unsigned int queue; + unsigned int reserved; + }X; + /** @endcond */ +} qurt_cond_t; + +/** @} */ /* end_addtogroup condition_variables_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_cond_init + Initializes a conditional variable object. + + @datatypes + #qurt_cond_t + + @param[out] cond Pointer to the initialized condition variable object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_init(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_destroy + Destroys the specified condition variable. + + @note1hang Conditions must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Conditions must not be destroyed while they are still in use. If this occurs, + the behavior of QuRT is undefined. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to destroy. + + @return + None. + + */ +/* ======================================================================*/ +void qurt_cond_destroy(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_signal + Signals a waiting thread that the specified condition is true. \n + + When a thread wishes to signal that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the signal condition operation. \n + -# Unlock the mutex. + + @note1hang Failure to properly lock and unlock a mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_signal(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_broadcast + Signals multiple waiting threads that the specified condition is true.\n + When a thread wishes to broadcast that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the broadcast condition operation. \n + -# Unlock the mutex.\n + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_broadcast(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable (suspends the thread and unlocks the mutex). + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t \n + #qurt_mutex_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait(qurt_cond_t *cond, qurt_mutex_t *mutex); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait2 + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable, which suspends the thread and unlocks the mutex. + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @note1cont This is the same API as qurt_cond_wait(), use this version + when using mutexes of type #qurt_rmutex2_t. + + @datatypes + #qurt_cond_t \n + #qurt_rmutex2_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with the condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait2(qurt_cond_t *cond, qurt_rmutex2_t *mutex); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_COND_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_consts.h new file mode 100755 index 0000000000000..b1e35998e73b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_consts.h @@ -0,0 +1,315 @@ +#ifndef QURT_CONSTS_H +#define QURT_CONSTS_H + +/** + @file qurt_consts.h + @brief QuRT constants and definitions + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* Definitions of system events. System events suspend + a thread and put it into suspending_list. + The system event number is saved in CONTEXT::error::cause field + of the suspended thread. An event handler thread such as + page fault handler or system error handler can wake up the suspended + thread. + */ +#define QURT_EVENT_PAGEFAULT 0x1 /* Page fault event. */ +#define QURT_EVENT_SYSTEM_ERR 0x2 /* System error event. */ +#define QURT_EVENT_SUSPEND 0x3 +#define QURT_EVENT_PROCESS_EXIT 0x4 /* Process termination event.*/ + +#define QURT_SYSENV_MAX_THREADS_TYPE 1 /* Maximum threads object. */ +#define QURT_SYSENV_PROCNAME_TYPE 2 /* Process name object. */ +#define QURT_SYSENV_MAX_PI_PRIO_TYPE 3 /* Maximum pi priority object. */ +#define QURT_SYSENV_ARCH_REV_TYPE 4 /* Architecture version object. */ +#define QURT_SYSENV_APP_HEAP_TYPE 5 /* Application heap object. */ +#define QURT_SYSENV_REGION_ATTR_DEFAULT 7 /* Default region attributes. */ +#define QURT_SYSENV_STACK_PROFILE_COUNT_TYPE 8 /* Stack profile count type. */ +#define QURT_SYSENV_ISLAND_CONFIG_TYPE 9 /*island configuration check*/ +#define QURT_SYSENV_HTHREADS_TYPE 10 /* Active threads objec */ +#define QURT_SYSENV_CONFIG_IMAGE_START_LO 11 /* Config image start address for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_START_HI 12 /* Config Image start address for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_LO 13 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_HI 14 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_PLATPARAMS 15 /* Platformparams for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_SIZE 16 /* Config image Size for DTB parsing */ +#define QURT_SYSENV_L2_CACHE_LINE_SIZE 17 /*L2 cache line size*/ + +/* Get q6 regs */ +#define QURT_GET_SSR 1 +#define QURT_GET_CCR 2 +#define QURT_GET_CFGBASE 3 +#define QURT_GET_SYSCFG 4 +#define QURT_GET_REV 5 + + +/** @cond rest_reg_dist */ +/** @addtogroup performance_monitor_macros +@{ */ + +/* PMU */ +#define QURT_PMUCNT0 0 /**< */ +#define QURT_PMUCNT1 1 /**< */ +#define QURT_PMUCNT2 2 /**< */ +#define QURT_PMUCNT3 3 /**< */ +#define QURT_PMUCFG 4 /**< */ +#define QURT_PMUEVTCFG 5 /**< */ + +/* new since V55 */ +#define QURT_PMUCNT4 6 /**< */ +#define QURT_PMUCNT5 7 /**< */ +#define QURT_PMUCNT6 8 /**< */ +#define QURT_PMUCNT7 9 /**< */ +#define QURT_PMUEVTCFG1 10 /**< */ + +/* new since V61 */ +#define QURT_PMUSTID0 11 /**< */ +#define QURT_PMUSTID1 12 /**< */ + +#define QURT_PMUCNTSTID0 13 /**< */ +#define QURT_PMUCNTSTID1 14 /**< */ +#define QURT_PMUCNTSTID2 15 /**< */ +#define QURT_PMUCNTSTID3 16 /**< */ +#define QURT_PMUCNTSTID4 17 /**< */ +#define QURT_PMUCNTSTID5 18 /**< */ +#define QURT_PMUCNTSTID6 19 /**< */ +#define QURT_PMUCNTSTID7 20 /**< */ + +/** @} */ /* end_addtogroup performance_monitor_macros */ +/** @endcond */ + +/* + Power collapse operation +*/ +#define QURT_POWER_SHUTDOWN 0 /**< */ +#define QURT_TCXO_SHUTDOWN 1 /**< */ +#define QURT_POWER_CMD_PREPARE 0 /**< */ +#define QURT_POWER_CMD_PERFORM 1 /**< */ +#define QURT_POWER_CMD_EXIT 2 /**< */ +#define QURT_POWER_CMD_FAIL_EXIT 3 /**< */ +#define QURT_POWER_CMD_PERFORM_L2_RETENTION 4 /**< */ +#define QURT_POWER_CMD_PERFORM_SAVE_TCM 5 /**< */ +#define QURT_POWER_CMD_DEEP_SLEEP 6 /**< */ + + +/** @addtogroup thread_macros +@{ */ +#define QURT_MAX_HTHREAD_LIMIT 8U /**< Limit on the maximum number of hardware threads supported by QuRT for any + Hexagon version. Use this definition to define arrays, and so on, in + target independent code. */ +/** @} */ /* end_addtogroup thread_macros */ + +/** @cond internal_only */ +/** @addtogroup power_management_macros +@{ */ +/** + L2 cache retention mode +*/ +#define QURT_POWER_SHUTDOWN_TYPE_L2NORET QURT_POWER_CMD_PERFORM /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_L2RET QURT_POWER_CMD_PERFORM_L2_RETENTION /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_SAVETCM QURT_POWER_CMD_PERFORM_SAVE_TCM /**< */ +/** @} */ /* end_addtogroup power_management_macros */ +/** @endcond */ + +/* + QURT_system_state + Use for debugging the shutdown/startup process. + + State transition for cold boot: + QURT_BOOT_SETUP_ISDB --> QURT_CBOOT_BSP_INIT --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT --> + QURT_CBOOT_KERNEL_INIT_DONE --> QURT_CBOOT_PLAT_CONFIG_DONE --> + QURT_CBOOT_ROOT_TASK_STARTED + + State transition for power collapse: + QURT_PREPARE_SINGLE_MODE --> QURT_PERFORM_IPEND --> + QURT_PERFORM_SAVE_TLB --> QURT_PERFORM_SWITCH_PC --> + cache flush states (dependent on L2 retention config) + + State transition for warm boot: + QURT_BOOT_SETUP_ISDB --> QURT_WBOOT_INIT_TLB --> + QURT_WBOOT_SET_1TO1_MAP --> QURT_WBOOT_REMOVE_1TO1_MAP --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT +*/ +#define QURT_PREPARE_SINGLE_MODE 1 /**< */ +#define QURT_PREPARE_END 2 /**< */ +#define QURT_PERFORM_IPEND 3 /**< */ +#define QURT_PERFORM_SAVE_ISDP 4 /**< */ +#define QURT_PERFORM_SAVE_PMU 5 /**< */ +#define QURT_PERFORM_SAVE_TLB 6 /**< */ +#define QURT_PERFORM_SWITCH_PC 7 /**< */ +#define QURT_PERFORM_EXIT 8 /**< */ +#define QURT_FLUSH_L1CACHE 9 /**< */ +#define QURT_FLUSH_L2CACHE 0xA /**< */ +#define QURT_FLUSH_CACHE_DONE 0xB /**< */ +#define QURT_SWITCH_PC_DONE 0xC /**< */ +#define QURT_BOOT_SETUP_ISDB 0xD /**< */ +#define QURT_WBOOT_INIT_TLB 0xE /**< */ +#define QURT_WBOOT_SET_1TO1_MAP 0xF /**< */ +#define QURT_WBOOT_CFG_ADV_SYSCFG 0x10 /**< */ +#define QURT_WBOOT_REMOVE_1TO1_MAP 0x11 /**< */ +#define QURT_CBOOT_BSP_INIT 0x12 /**< */ +#define QURT_CBOOT_END_CLEAN_L1CACHE 0x13 /**< */ +#define QURT_CBOOT_END_CLEAN_INIT 0x14 /**< */ +#define QURT_CBOOT_END_OS_INIT 0x15 /**< */ +#define QURT_CBOOT_TLB_DUMP_LOAD 0x16 /**< */ +#define QURT_CBOOT_TLB_STATIC_LOAD 0x17 /**< */ +#define QURT_CBOOT_KERNEL_INIT_DONE 0x18 /**< */ +#define QURT_CBOOT_PLAT_CONFIG_DONE 0x19 /**< */ +#define QURT_CBOOT_ROOT_TASK_STARTED 0x1A /**< */ +#define QURT_IMPRECISE_EXCEPTION 0x1B /**< */ +#define QURT_WBOOT_DEBUG_L2_START 0x1C /**< */ +#define QURT_WBOOT_DEBUG_L2_END 0x1D /**< */ +#define QURT_NMI_SAVE_L2VIC_COMPLETE 0x1E /**< */ +#define QURT_NMI_HANDLER_COMPLETE 0x1F /**< */ +#define QURT_NMI_AFTER_SAVE_GLOBAL 0x20 /**< */ +#define QURT_WBOOT_START 0x21 /**< */ +#define QURT_ENTER_ISLAND 0x22 /**< */ +#define QURT_EXIT_ISLAND 0x23 /**< */ +#define QURT_LOAD_NOTIFIER_TCB 0x24 /**< */ +#define QURT_ABNORMAL_RESET 0x25 /**< */ +/* + Thread attributes +*/ + +#define QURT_THREAD_ATTR_GP 0x00000002 /*< */ +#define QURT_THREAD_ATTR_UGP 0x00000003 /*< User general pointer (UGP)*/ +#define QURT_THREAD_ATTR_PREFETCH 0x00000004 /*< */ +#define QURT_THREAD_ATTR_TID 0x00000005 /*< */ +#define QURT_THREAD_ATTR_CACHE_PART 0x00000007 /*< */ +#define QURT_THREAD_ATTR_COPROCESSOR 0x00000008 /*< */ +#define QURT_THREAD_ATTR_GET_L2CACHE_PART 0x00000009 /*< */ +#define QURT_THREAD_ATTR_SET_FRML 0x0000000A /*< */ +#define QURT_THREAD_ATTR_STID_GET 0x0000000B /*< */ +#define QURT_THREAD_ATTR_STID_SET 0x0000000C /*< */ +#define QURT_THREAD_ATTR_AUTOSTACK 0x0000000D /*< */ +#define QURT_THREAD_ATTR_SYSTEM_THREAD 0x0000000E /*< */ +#define QURT_THREAD_ATTR_STID_SET2 0x0000000F /*< */ +#define QURT_THREAD_ATTR_STID_SET2_ACKNOWLEDGE 0x00000010 /*< */ +#define QURT_THREAD_ATTR_STID_GET2 0x00000011 /*< */ + +/** Cache operations*/ +#define QURT_DCCLEAN 0U /* Clean Dcache. */ +#define QURT_DCINV 1U /* Invalidate Dcache. */ +#define QURT_DCCLEANINV 2U /* Clean and invalidate Dcache. */ +#define QURT_ICINV 3U /* Invalidate Icache. */ +#define QURT_DUMP_DCTAGS 4U /* For testing purpose. */ +#define QURT_FLUSH_ALL 5U /* Flush entire L1 and L2 cache. */ +#define QURT_TABLE_FLUSH 6U /* Flush based on table of physical pages */ +#define QURT_CLEAN_INVALIDATE_ALL 7U /* Flush and invalidate entire L1 and L2 cache. */ +#define QURT_L2CACHE_LOCK_LINES 8U /* l2 cache lock lines */ +#define QURT_L2CACHE_UNLOCK_LINES 9U /* l2 cache unlock lines */ +#define QURT_CLEAN 10U /* Flush L1 and L2 cache */ +#define QURT_CLEAN_INVALIDATE 11U /* Flush and invalidate L1 and L2 cache. */ +#define QURT_CLEAN_INVALIDATE_L2 12U /* Flush and invalidate entire L2 cache. */ + +/**@ingroup chapter_prefined_symbols */ +/**@xreflabel{hdr:QURT_API_VERSION}*/ + + +/* Process state. */ +#define QURT_UPDATE_PROCESS_STATE 0 /**< */ +#define QURT_MP_INIT 1 /*< */ +#define QURT_MP_RUNNING 2 /*< */ +#define QURT_MP_STOPPED 3 /*< */ + +/* QuRT reset reason. */ +#define QURT_NORMAL_BOOT 0 /* Normal boot. */ +#define QURT_WARM_BOOT 1 /* Power collapse warm boot. */ +#define QURT_WARM_BOOT_L2_RETENTION 2 /* Power collapse with L2 retention warm boot. */ +#define QURT_WARM_BOOT_SAVE_TCM 3 /* Power collapse with saving TCM. */ +#define QURT_QUICK_BOOT 4 /* Deep sleep. */ + +/* QuRT Wait for Idle command */ +#define QURT_WAIT_FOR_IDLE_DISABLE 0 /*< */ +#define QURT_WAIT_FOR_IDLE_ENABLE 1 /*< */ +#define QURT_WAIT_FOR_IDLE 2 /*< */ +#define QURT_WAIT_FOR_IDLE_CANCEL 3 /*< */ + +/*QuRT island exit stages */ +#define QURT_ISLAND_EXIT_STAGE1 1 /*< */ +#define QURT_ISLAND_EXIT_STAGE2 2 /*< */ + +#define QURT_MAX_NAME_LEN 64 /*< */ + +#define MAX_POOL_RANGES 16 /*< */ + +/* key definitions for debug thread info */ +//#define MAX_TCB_KEY 40 //whatever is a good number or makes debug thread structure be 1K +#define KEY_SCHDULER_STATE 1 /*< */ +#define KEY_PRIORITY 2 /*< */ +#define KEY_PRIORITY_ORIG 3 /*< */ +#define KEY_STACK_BOTTOM 4 // Currently not populated +#define KEY_STACK_TOP 5 // Currently not populated +#define KEY_HVX_STATE 6 /*< */ +#define KEY_FUTEX_OBJECT 7 /*< */ +#define KEY_THREAD_ID 8 /*< */ +#define KEY_PROFILE_CYCLE_LO 9 // Currently not populated +#define KEY_PROFILE_CYCLE_HI 10 // Currently not populated +#define KEY_ERROR_ADDRESS 11 // This holds the BADVA +#define KEY_ERROR_CAUSE 12 // This is the same as QURT_error_info.cause +#define KEY_ERROR_CAUSE2 13 // This is the same as QURT_error_info.cause2 +#define KEY_ERROR_SSR 14 /*< Holds the SSR value */ +#define QURT_RESERVED -1 + +/* VTLB method IDs. */ +#define QURT_VTLB_ENTRY_CREATE 0U +#define QURT_VTLB_ENTRY_DELETE 1U +#define QURT_VTLB_ENTRY_READ 2U +#define QURT_VTLB_ENTRY_WRITE 3U +#define QURT_VTLB_ENTRY_PROBE 4U +#define QURT_VTLB_ENTRY_SPLIT 5U +#define QURT_VTLB_ENTRY_MERGE 6U +#define QURT_VTLB_ENTRY_STATISTICS 7U +#define QURT_VTLB_ENTRY_SET_SPECIAL 8U +#define QURT_VTLB_QUEUE_PPAGE 9U +#define QURT_VTLB_RECLAIM_STACK_PAGES 10U +#define QURT_VTLB_ASID_SET_STATE_FAST 11U +#define QURT_VTLB_ASID_SET_STATE 12U +#define QURT_VTLB_ENTRY_SET_EXTENSION 13U +#define QURT_VTLB_ENTRY_CLEAR_EXTENSION 14U + +/* VTCM window access control HWIO programming. */ +#define QURT_VTCM_WINDOW_ENABLE 1U +#define QURT_VTCM_WINDOW_DISABLE 0U +#define QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT 0xFFFU +#define QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT 0U + +/** @cond */ +/* ETM source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< Memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< Memory source of SAC* is data. */ + +/* ETM PID status flags */ +#define QURT_ETM_NO_PID 0xFFFFFFFF /**< No PID is selected. */ +/** @endcond */ + +/* execution context */ +#define QURT_CTX_USER 1 +#define QURT_CTX_GUEST 2 + +/* Profiling STID */ +#define QURT_STID_DEFAULT 0U + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cycles.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cycles.h new file mode 100755 index 0000000000000..b599493f5d563 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_cycles.h @@ -0,0 +1,301 @@ + +#ifndef QURT_CYCLES_H +#define QURT_CYCLES_H 1 +/** + @file qurt_cycles.h + Prototypes of kernel pcycle API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ + +/**@ingroup func_qurt_profile_reset_idle_pcycles + @xreflabel{hdr:qurt_profile_reset_idle_pcycles} + Sets the per-hardware-thread idle cycle counts to zero. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_idle_pcycles (void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_thread_pcycles + @xreflabel{hdr:qurt_profile_get_thread_pcycles} + Gets the count of the running processor cycles for the current thread.\n + Returns the current running processor cycle count for the current QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @return + Integer -- Running processor cycle count for current thread. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_profile_get_thread_pcycles(void); + + +/*======================================================================*/ +/**@ingroup func_qurt_get_core_pcycles + @xreflabel{hdr:qurt_get_core_pcycles} + Gets the count of core processor cycles executed.\n + Returns the current number of running processor cycles executed since the Hexagon + processor was last reset. + + This value is based on the hardware core clock, which varies in speed according to the + processor clock frequency. + + @note1hang Because the hardware core clock stops running when the processor shuts + down (due to all of the hardware threads being idle), treat the cycle values returned + by this operation as relative rather than absolute. + + @note1cont Thread cycle counts are valid only in the V4 Hexagon processor version. + + @return + Integer -- Current count of core processor cycles. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_get_core_pcycles(void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles + + @deprecated use #qurt_profile_get_idle_pcycles2 instead + + Gets the current idle processor cycle counts for a maximum of 6 hardware threads. Use + #qurt_profile_get_idle_pcycles2 for reading pcycles without limitation on maximum hardware threads. + + This operation accepts a pointer to a user-defined array, and writes to the array the current + idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling is enabled or not, + and resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be a minimum of the number of hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_idle_pcycles (unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles2 + Gets the current idle processor cycle counts for maximum available hardware threads. + + This operation accepts a pointer to a user-defined array with length in bytes, and writes + to the array the current idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling enable status, and + resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be equivalent to the number of hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, + it returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_idle_pcycles2 (unsigned long long *pcycles, unsigned int length_in_bytes); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles + + @deprecated use #qurt_profile_get_threadid_pcycles2 instead + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for a maximum of 6 hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Valid thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be a minimum of the number of + hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_threadid_pcycles (int thread_id, unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles2 + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for maximum available hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be equivalent to the number of + hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, it + returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + #QURT_ENOTHREAD -- Operation failed due to invalid #thread_id + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_threadid_pcycles2 (int thread_id, unsigned long long *pcycles, unsigned int length_in_bytes); + + +/*======================================================================*/ +/**@ingroup func_qurt_profile_reset_threadid_pcycles + @xreflabel{hdr:qurt_profile_reset_threadid_pcycles} + Sets the per-hardware-thread running cycle counts to zero for the specified QuRT thread. + + @param[in] thread_id Thread identifier. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_threadid_pcycles (int thread_id); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_enable + @xreflabel{hdr:qurt_profile_enable} + Enables profiling.\n + Enables or disables cycle counting of the running and idle processor cycles. + Profiling is disabled by default. \n + + @note1hang Enabling profiling does not automatically reset the cycle counts -- this must be + done explicitly by calling the reset operations before starting cycle counting. + Cycle counting starts from the instant of it was enabled using this API, and + halts on profiling disable. + + @param[in] enable Profiling. Values: \n + - 0 -- Disable profiling \n + - 1 -- Enable profiling @tablebulletend + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_enable (int enable); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_pcycles + @xreflabel{hdr:qurt_get_hthread_pcycles} + Reads the GCYCLE_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values are 1 through . + + + @return + Value read from GCYCLE_nT register. This value indicates the total number of pcycles that got executed + from reset to current point of execution when n threads are in run mode + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_pcycles(int n); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_commits + @xreflabel{hdr:qurt_get_hthread_commits} + Reads the GCOMMIT_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values: 1 through . + + @return + Value read from the GCOMMIT_nT register. This value indicates the total number of packets + committed from reset to current point of execution when n threads are in run mode. + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_commits(int n); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_devtree.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_devtree.h new file mode 100755 index 0000000000000..4adee45bb44a2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_devtree.h @@ -0,0 +1,161 @@ +#ifndef QURT_DEVTREE_H +#define QURT_DEVTREE_H +/** + @file qurt_devtree.h + @brief Prototypes and structures for device tree aware QuRT library function. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +*/ +/*qurt_callback is included by qurt_qdi_driver.h and depends on NULL being def. + callback is not used here, so define NULL here to avoid including the world*/ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "libfdt.h" +#include "DTBExtnLib.h" +#include "qurt_qdi_ext.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_BLOB_ID (-1) +#define DEFAULT_BLOB_ID 0 + +/** QURT Device Tree Mapping Macros */ +#define QURT_DT_MAPPING_FAILED (-1) +#define QURT_DT_FLAG_ISLAND 0x1 +#define QURT_DT_FLAG_PHYSADDR 0x2 + +/** Device Tree type for Root PD Device tree. +    Root PD Device Tree will typically describe the hardware in the subsystem. +    This is the /soc portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_ROOT 0 + +/** Device Tree type for Local Device tree. +    Local Device Tree will typically contain the software settings. +    This is the /sw portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_LOCAL 1 + +int qurt_devtree_init(void); + +/**@ingroup func_qurt_dt_mapping_create + Creates a memory mapping from the specified property of the specified device + tree node. Returns virtual addresses and sizes. + + @param[in] offset Device tree node offset. + @param[in] flags Flags to configure memory. Overloaded as property + index if reg_name is NULL. + @param[in] reg_name Identifies property to use for mapping, should + resemble a region. + @param[out] vaddr Return pointer for the virtual region address. + @param[out] size Return pointer for the virtual region size. + + @return + Result code indicating success or failure \n +*/ +int qurt_dt_mapping_create(fdt_node_handle *devtreeNode, int flags, char *regionName, int regionIdx, + unsigned long long *vaddr, unsigned long long *size); + +/**@ingroup func_qurt_dt_mapping_create2 + + Creates a memory mapping from the specified property of the specified device + tree node. + + Returns virtual addresses and sizes according to architecture (i.e either 32 bit or 64 bit). + + @param[in] devtreeNode Device Tree node + + @param[in] dt_map_flags Flags to configure memory mapping and are reserved for future purpose. + (0) - Default value assumes details from DT node are phys address, size. + QURT_DT_FLAG_ISLAND + + NOTE: The PA needs to be added to corresponding island spec to create an island mapping + + @param[in] regionName NULL or name of index in range to return, should + resemble a region. Ex.reg-names = "base", "rx", "tx"; + + @param[in] regionIdx Index of range to return. Ex reg = <0x1000 0x20>, <0x10000 0x100>, <0x18000 0x100 >; + + NOTE: If client specifies both re_name & regionIdx. The precedence of + region name is taken over and region index is ignored. + + @param[in] dt_map_perm Mapping access permissions(R/W), + QURT_PERM_READ + QURT_PERM_WRITE + + @param[in] cache_attr QuRT cache mode type's : + QURT_MEM_CACHE_DEVICE + QURT_MEM_CACHE_WRITEBACK + Other required cache type enums in qurt_types.h can also be passed. + + NOTE: No default value for cache & perm is present. + Client always needs to pass any of defined the flags. + + @param[out] vaddr Return pointer to the variable that holds the virtual address + @param[out] size Return pointer for the virtual region size. + + @return + #QURT_EOK Success indicating mapping created properly. + #QURT_DT_MAPPING_FAILED Failed to create mapping. + #QURT_EINVALID Mismatch in the architecture. + + else FdtLib or thirdparty error code. + +*/ +int qurt_dt_mapping_create2(fdt_node_handle *devtreeNode, unsigned int dt_map_flags, + char *regionName, int regionIdx, unsigned int dt_map_perm, int cache_attr, void **vaddr, size_t *size); + +/**@ingroup func_qurt_dt_isr_register + Device tree aware registration of an interrupt service routine (ISR) to an ISR thread. + The interrupt defined in the specified device tree node is enabled when this function returns success. + + @datatypes + #qurt_thread_t \n + #fdt_node_handle + + @param[in] dt_node Device tree node that specifies the interrupt property. + @param[in] dt_int_index Index of the specific interrupt to use within the device tree node structure. + Specify either this or int_name, use -1 if string is used. + @param[in] dt_int_name Name of the specific interrupt to use within the device tree node structure. + Either this or int_index should be specified, use NULL if index is used + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create(), defined by qurt_isr_register2(). + @param[in] prio Priority of the ISR, defined by qurt_isr_register2(). + @param[in] flags Defines ACK type. Values : \n + #QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the kernel. + #QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + Defined by qurt_isr_register2(). + @param[in] isr ISR with proto type void isr (void *arg, int int_num), defined by qurt_isr_register2(). + @param[in] arg First argument of the ISR when it is called to service the interrupt, defined by qurt_isr_register2(). + + @return + #QURT_EOK -- Successfully registered the ISR for the interrupt \n + #QURT_EINT -- Interrupt not configured \n + #QURT_EINVALID -- Invalid thread ID \n + #QURT_EDISABLED -- The feature is disabled \n + #QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Create the thread ID qurt_isr_create(). + ISR registration completed with qurt_isr_register2(). + */ +int qurt_dt_isr_register(fdt_node_handle *dt_node, int dt_int_index, char * dt_int_name, qurt_thread_t isr_thread_id, + unsigned short prio, unsigned short flags, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_dt_blob_id_get + Returns the Blob ID for the Blob type passed. + The value returned from this API can be passed as Blob ID parameter to DTBExtnLib APIs. + + @param[in] blob_type  Blob type to look up. + @return Blob ID for the passed Blob Type. +*/ +int qurt_dt_blob_id_get(unsigned int blob_type); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ecc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ecc.h new file mode 100755 index 0000000000000..09312684e99af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ecc.h @@ -0,0 +1,168 @@ +#ifndef QURT_ECC_H +#define QURT_ECC_H + + +/*===================================================================== + + @file qurt_ecc.h + @brief Prototypes of QuRT memory ECC API functions + + Copyright (c) 2018, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup exception_handling_types +@{ */ +// ECC memory definition +typedef enum { + QURT_ECC_MEM_L1_ICACHE = 0, /**< ECC memory L1 ICache. */ + QURT_ECC_MEM_L1_DCACHE = 1, /**< ECC memory L1 DCache.*/ + QURT_ECC_MEM_L2_CACHE = 2, /**< ECC memory L2 Cache.*/ + QURT_ECC_MEM_VTCM = 3 /**< ECC memory VTCM.*/ +} qurt_ecc_memory_t; +/** @} */ /* end_addtogroup exception_handling_types */ + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup exception_handling_macros +@{ */ + +#define QURT_ECC_ERR_DETECTED_STATUS 0 /**< ECC error detected. */ +#define QURT_ECC_ERR_TYPE 1 /**< ECC error type.*/ +// ECC status type + +#define QURT_ECC_CORRECTABLE_COUNT (1<<0) /**< ECC correctable count.*/ +#define QURT_ECC_UNCORRECTABLE_COUNT (1<<1) /**< ECC uncorrectable count.*/ +#define QURT_ECC_REGION_LOGGING (1<<2) /**< ECC region logging.*/ +// ECC enable/disable definition + +#define QURT_ECC_PROTECTION_DISABLE (0<<0) /**< Bit 0. */ +#define QURT_ECC_PROTECTION_ENABLE (1<<0) /**< Bit 0. */ +/** @} */ /* end_addtogroup exception_handling_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_ecc_enable + Enables or disables ECC protection on a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] enable Set to one of the following values: + - #QURT_ECC_PROTECTION_ENABLE + - #QURT_ECC_PROTECTION_DISABLE @tablebulletend + + @return + - #QURT_EOK -- ECC enabling or disabling setup is performed successfully + - Others -- Failure + + @dependencies + None. + */ +int qurt_ecc_enable( qurt_ecc_memory_t memory, unsigned int enable ); + + +/**@ingroup func_qurt_ecc_get_error_status + Gets ECC error status for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following: + - #QURT_ECC_ERR_DETECTED_STATUS + - #QURT_ECC_ERR_TYPE @tablebulletend + + @return + Returns the following when the type is #QURT_ECC_ERR_DETECTED_STATUS: + - 0 -- No error detected \n + - 1 -- At least one error detected \n + Returns the following when the type is #QURT_ECC_ERR_TYPE: \n + - 0 through 1 -- Correctable error \n + - 2 -- Uncorrectable error + + @dependencies + None. + */ +int qurt_ecc_get_error_status( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_get_error_count + Gets the ECC error count for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values:\n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT @tablebulletend + + @return + Error count for the specified error type. + + @dependencies + None. + */ +int qurt_ecc_get_error_count( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_clear_error_count + Clears ECC error count or region logging for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: \n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one or multiple OR'ed of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT \n + - #QURT_ECC_REGION_LOGGING @tablebulletend + + @return + #QURT_EOK -- Error count successfully cleared \n + Others -- Failure at clearing the error count + + @dependencies + None. + */ +int qurt_ecc_clear_error_count( qurt_ecc_memory_t memory, unsigned int type ); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ECC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_error.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_error.h new file mode 100755 index 0000000000000..f4666b396c378 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_error.h @@ -0,0 +1,149 @@ +#ifndef QURT_ERROR_H +#define QURT_ERROR_H + +/** + @file qurt_error.h + Error results- QURT defines a set of standard symbols for the error result values. This file lists the + symbols and their corresponding values. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021-2022 , 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ +#include "qurt_except.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup chapter_error +@{ */ + +/*===================================================================== +Constants and macros +======================================================================*/ +#define QURT_EOK 0 /**< Operation successfully performed. */ +#define QURT_EVAL 1 /**< Wrong values for the parameters. The specified page does not exist. */ +#define QURT_EMEM 2 /**< Not enough memory to perform the operation.*/ + +#define QURT_EINVALID 4 /**< Invalid argument value; invalid key. */ +/** @cond */ +#define QURT_EUNKNOWN 6 /**< Defined but never used in QuRT. */ +#define QURT_ENOMSGS 7 /**< Message queue is empty. */ +#define QURT_EBADF 9 /**< Bad message queue descriptor. */ +/** @endcond */ +#define QURT_EFAILED 12 /**< Operation failed. */ + +#define QURT_ENOTALLOWED 13 /**< Operation not allowed. */ + +/** @cond */ +#define QURT_EDUPCLSID 14 /*< Duplicate class ID. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOREGISTERED 20 /**< No registered interrupts.*/ +/** @endcond */ + + +/** @cond */ +#define QURT_EISDB 21 /*< Power collapse failed due to ISDB being enabled. */ +#define QURT_ESTM 22 /*< Power collapse failed in a Single-threaded mode check. */ +/** @endcond */ + + +/** @cond rest_reg_dist */ +#define QURT_ETLSAVAIL 23 /**< No free TLS key is available. */ +#define QURT_ETLSENTRY 24 /**< TLS key is not already free. */ +/** @endcond */ + +#define QURT_EINT 26 /**< Invalid interrupt number (not registered). */ +/** @cond rest_reg_dist */ +#define QURT_ESIG 27 /**< Invalid signal bitmask (cannot set more than one signal at a time). */ +/** @endcond */ + +/** @cond */ +#define QURT_EHEAP 28 /**< No heap space is available. */ +#define QURT_ENOSPC 28 /**< No space to create another queue in the system. */ +#define QURT_EMEMMAP 29 /**< Physical address layout is not supported by the kernel. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOTHREAD 30 /**< Thread no longer exists. */ +/** @endcond */ +/** @cond */ +#define QURT_EL2CACHE 31 /**< L2cachable is not supported in kernel invalidate/cleaninv. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_EALIGN 32 /**< Not aligned. */ +#define QURT_EDEREGISTERED 33 /**< Interrupt is already deregistered.*/ +/** @endcond */ + +/** @cond internal_only */ + +#define QURT_ETLBCREATESIZE 34 /**< TLB create error -- Incorrect size.*/ +#define QURT_ETLBCREATEUNALIGNED 35 /**< TLB create error -- Unaligned address.*/ +/** @endcond */ +/** @cond rest_reg_dist*/ +#define QURT_EEXISTS 35 /**< File or message queue already exists. */ +#define QURT_ENAMETOOLONG 36 /**< Name too long for message queue creation. */ +#define QURT_EPRIVILEGE 36 /**< Caller does not have privilege for this operation.*/ + +#define QURT_ECANCEL 37 /**< A cancellable request was canceled because the associated process was asked to exit.*/ +/** @endcond */ + +/** @cond */ +#define QURT_EISLANDTRAP 38 /*< Unsupported TRAP is called in Island mode.*/ + +#define QURT_ERMUTEXUNLOCKNONHOLDER 39 /*< Rmutex unlock by a non-holder.*/ +#define QURT_ERMUTEXUNLOCKFATAL 40 /*< Rmutex unlock error, all except the non-holder error.*/ +#define QURT_EMUTEXUNLOCKNONHOLDER 41 /*< Mutex unlock by a non-holder.*/ +#define QURT_EMUTEXUNLOCKFATAL 42 /*< Mutex unlock error, all except the non-holder error.*/ +#define QURT_EINVALIDPOWERCOLLAPSE 43 /*< Invalid power collapse mode requested. */ +/** @endcond */ +#define QURT_EISLANDUSEREXIT 44 /**< User call has resulted in island exit.*/ +#define QURT_ENOISLANDENTRY 45 /**< Island mode had not yet been entered.*/ +#define QURT_EISLANDINVALIDINT 46 /**< Exited Island mode due to an invalid island interrupt.*/ +/** @cond rest_reg_dist */ +#define QURT_ETIMEDOUT 47 /**< Operation timed-out. */ +#define QURT_EALREADY 48 /**< Operation already in progress. */ +/** @endcond */ + +#define QURT_ERETRY 49 /*< Retry the operation. */ +#define QURT_EDISABLED 50 /*< Resource disabled. */ +#define QURT_EDUPLICATE 51 /*< Duplicate resource. */ +#define QURT_EBADR 53 /*< Invalid request descriptor. */ +#define QURT_ETLB 54 /*< Exceeded maximum allowed TLBs. */ +#define QURT_ENOTSUPPORTED 55 /*< Operation not supported. */ +/** @cond rest_reg_dist */ +#define QURT_ENORESOURCE 56 /**< No resource. */ +/** @endcond */ + +#define QURT_EDTINIT 57 /**< Problem with device tree intialization. */ +#define QURT_EBUFLOCK 58 /*< Buffer lock failed because it was already locked many times. */ +#define QURT_ELOCKED 59 /**< Current operation failed as the buffer is locked. */ +#define QURT_EMSGSIZE 90 /*< Message queue msg_len is greater than mq_msgsize attribute of the message queue. */ + + +#define QURT_ENOTCONFIGURED 91 /*< Interrupt is NOT configured. */ + +#define QURT_EBANDWIDTHLIMIT 92 /*< Message queue send exceed the bandwidth limit. */ + +#define QURT_ECFIVIOLATION 93 /*< CFI violation detected. */ + +#define QURT_EDESTROY 94 /**< A destroy request was made to waiting threads.*/ + +#define QURT_EHMXNOTAVAIL 95 /**< HMX is not available to target thread.*/ +#define QURT_EHMXNOTDETACHABLE 96 /**< HMX is not detachable from target thread.*/ + +#define QURT_EFATAL -1 /**< Fatal error. */ + +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ERROR_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_event.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_event.h new file mode 100755 index 0000000000000..987f0fe79f227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_event.h @@ -0,0 +1,452 @@ +#ifndef QURT_EVENT_H +#define QURT_EVENT_H +/** + @file qurt_event.h + @brief Prototypes of kernel event API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "qurt_consts.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System environment object type. + */ +/**@addtogroup sys_env_types +@{ */ +/** QuRT swap pool information type. */ +typedef struct qurt_sysenv_swap_pools { + /** @cond */ + unsigned int spoolsize; /* Swap pool size.*/ + unsigned int spooladdr; /* Swap pool start address.*/ + /** @endcond */ +}qurt_sysenv_swap_pools_t; + +/**QuRT application heap information type. */ +typedef struct qurt_sysenv_app_heap { + /** @cond */ + unsigned int heap_base; /* Heap base address.*/ + unsigned int heap_limit; /* Heap end address.*/ + /** @endcond */ +} qurt_sysenv_app_heap_t ; + +/** QuRT architecture version information type. */ +typedef struct qurt_sysenv_arch_version { + /** @cond */ + unsigned int arch_version; /*Architecture version.*/ + /** @endcond */ +}qurt_arch_version_t; + +/** QuRT maximum hardware threads information type. */ +typedef struct qurt_sysenv_max_hthreads { + /** @cond */ + unsigned int max_hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_max_hthreads_t; + +/** QuRT active hardware threads information type. */ +typedef struct qurt_sysenv_hthreads { + /** @cond */ + unsigned int hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_hthreads_t; + +/** QuRT maximum pi priority information type. */ +typedef struct qurt_sysenv_max_pi_prio { + /** @cond */ + unsigned int max_pi_prio; /*Maximum pi priority.*/ + /** @endcond */ +}qurt_sysenv_max_pi_prio_t; + +/** QuRT process name information type. */ +typedef struct qurt_sysenv_procname { + /** @cond */ + union { + unsigned int asid; /*Address space ID.*/ + unsigned int pid; /*Process ID.*/ + }; + char name[QURT_MAX_NAME_LEN]; /* Process name.*/ + /** @endcond */ +}qurt_sysenv_procname_t; + +/** QuRT stack profile count information type. */ +typedef struct qurt_sysenv_stack_profile_count { + /** @cond */ + unsigned int count; /*Stack profile count for usage.*/ + unsigned int count_watermark; /*Stack profile count for watermark.*/ + /** @endcond */ +}qurt_sysenv_stack_profile_count_t; + +/** + QuRT system error event type. + */ +typedef struct _qurt_sysevent_error_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + } qurt_sysevent_error_t ; + +typedef struct _qurt_sysevent_error_1_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + unsigned int fkey; /**< Framekey.*/ + unsigned int reserved1; /**< Reserved.*/ + unsigned int reserved2; /**< Reserved.*/ + unsigned int reserved3; /**< Reserved.*/ + } qurt_sysevent_error_1_t ; + +/** QuRT page fault error event information type. */ +typedef struct qurt_sysevent_pagefault { + qurt_thread_t thread_id; /**< Thread ID of the page fault thread. */ + unsigned int fault_addr; /**< Accessed address that caused the page fault. */ + unsigned int ssr_cause; /**< SSR cause code for the page fault. */ +} qurt_sysevent_pagefault_t ; +/** @} */ /* @endaddtogroup sys_env_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/*======================================================================*/ +/** + Gets the environment swap pool 0 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool0 (qurt_sysenv_swap_pools_t *pools ); + +/* + Gets the environment swap pool 1 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool1(qurt_sysenv_swap_pools_t *pools ); + +/**@ingroup func_qurt_sysenv_get_app_heap + Gets information on the program heap from the kernel. + + @datatypes + #qurt_sysenv_app_heap_t + + @param[out] aheap Pointer to information on the program heap. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_app_heap(qurt_sysenv_app_heap_t *aheap ); + +/**@ingroup func_qurt_sysenv_get_arch_version + Gets the Hexagon processor architecture version from the kernel. + + @datatypes + #qurt_arch_version_t + + @param[out] vers Pointer to the Hexagon processor architecture version. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter + + @dependencies + None. +*/ +int qurt_sysenv_get_arch_version(qurt_arch_version_t *vers); + +/**@ingroup func_qurt_sysenv_get_max_hw_threads + Gets the maximum number of hardware threads supported in the Hexagon processor. + The API includes the disabled hardware threads to reflect the maximum + hardware thread count. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, only HW0 and HW2 are initialized by QuRT. + HW1 and HW3 are not used at all. Under such a scenario, + qurt_sysenv_get_max_hw_threads() still returns four. + + @datatypes + #qurt_sysenv_max_hthreads_t + + @param[out] mhwt Pointer to the maximum number of hardware threads supported in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_hw_threads(qurt_sysenv_max_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_hw_threads + Gets the number of hardware threads initialized by QuRT in Hexagon processor. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, QuRT only initializes HW0 and HW2. + HW1 and HW3 are not used. In this scenario, qurt_sysenv_get_hw_threads() returns 2. + + @datatypes + #qurt_sysenv_hthreads_t + + @param[out] mhwt Pointer to the number of hardware threads active in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_hw_threads(qurt_sysenv_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_max_pi_prio + Gets the maximum priority inheritance mutex priority from the kernel. + + @datatypes + #qurt_sysenv_max_pi_prio_t + + @param[out] mpip Pointer to the maximum priority inheritance mutex priority. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_pi_prio(qurt_sysenv_max_pi_prio_t *mpip ); + +/**@ingroup func_qurt_sysenv_get_process_name2 + Gets information on the system environment process names based on the client_handle argument. + + @datatypes + #qurt_sysenv_procname_t + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name2(int client_handle, qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_process_name + Gets information on the system environment process names from the kernel. + + @datatypes + #qurt_sysenv_procname_t + + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name(qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_stack_profile_count + Gets information on the stack profile count from the kernel. + + @datatypes + #qurt_sysenv_stack_profile_count_t + + @param[out] count Pointer to information on the stack profile count. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_stack_profile_count(qurt_sysenv_stack_profile_count_t *count ); + +/**@ingroup func_qurt_exception_wait + Registers the program exception handler. + This function assigns the current thread as the QuRT program exception handler and suspends the + thread until a program exception occurs. + + When a program exception occurs, the thread is awakened with error information + assigned to the parameters of this operation. + + @note1hang If no program exception handler is registered, or if the registered handler + calls exit, QuRT raises a kernel exception. + If a thread runs in Supervisor mode, any errors are treated as kernel + exceptions. + + @param[out] ip Pointer to the instruction memory address where the exception occurred. + @param[out] sp Stack pointer. + @param[out] badva Pointer to the virtual data address where the exception occurred. + @param[out] cause Pointer to the QuRT error result code. + + @return + Registry status: \n + Thread identifier -- Handler successfully registered. \n + #QURT_EFATAL -- Registration failed. + + @dependencies + None. +*/ +unsigned int qurt_exception_wait (unsigned int *ip, unsigned int *sp, + unsigned int *badva, unsigned int *cause); + +unsigned int qurt_exception_wait_ext (qurt_sysevent_error_t * sys_err); + +/**@ingroup func_qurt_exception_wait3 + Registers the current thread as the QuRT program exception handler, and suspends the thread until a + program exception occurs. + When a program exception occurs, the thread is awakened with error information assigned to the specified + error event record. + If a program exception is raised when no handler is registered (or when a handler is registered, but it calls + exit), the exception is treated as fatal.\n + @note1hang If a thread runs in Monitor mode, all exceptions are treated as kernel exceptions.\n + @note1cont This function differs from qurt_exception_wait() by returning the error information in a data + structure rather than as individual variables. It also returns additional information (for example, SSR, FP, and LR). + + @param[out] sys_err Pointer to the qurt_sysevent_error_1_t type structure. + @param[in] sys_err_size Size of the qurt_sysevent_error_1_t structure. + + @return + Registry status: \n + - #QURT_EFATAL -- Failure. \n + - Thread ID -- Success. + + @dependencies + None. +*/ + +unsigned int qurt_exception_wait3(void * sys_err, unsigned int sys_err_size); + +/**@ingroup func_qurt_exception_raise_nonfatal + Raises a nonfatal program exception in the QuRT program system. + + For more information on program exceptions, see Section @xref{dox:exception_handling}. + + This operation never returns -- the program exception handler is assumed to perform all + exception handling before terminating or reloading the QuRT program system. + + @note1hang The C library function abort() calls this operation to indicate software + errors. + + @param[in] error QuRT error result code (Section @xref{dox:error_results}). + + @return + Integer -- Unused. + + @dependencies + None. +*/ +int qurt_exception_raise_nonfatal (int error) __attribute__((noreturn)); + + +/**@ingroup func_qurt_exception_raise_fatal + Raises a fatal program exception in the QuRT system. + + Fatal program exceptions terminate the execution of the QuRT system without invoking + the program exception handler. + + For more information on fatal program exceptions, see Section @xref{dox:exception_handling}. + + This operation always returns, so the calling program can perform the necessary shutdown + operations (data logging, on so on). + + @note1hang Context switches do not work after this operation has been called. + + @return + None. + + @dependencies + None. +*/ +void qurt_exception_raise_fatal (void); + +unsigned int qurt_enable_floating_point_exception(unsigned int mask); + +/**@ingroup func_qurt_exception_enable_fp_exceptions + Enables the specified floating point exceptions as QuRT program exceptions. + + The exceptions are enabled by setting the corresponding bits in the Hexagon + control user status register (USR). + + The mask argument specifies a mask value identifying the individual floating + point exceptions to set. The exceptions are represented as defined symbols + that map into bits 0 through 31 of the 32-bit flag value. + Multiple floating point exceptions are specified by OR'ing together the individual + exception symbols.\n + @note1hang This function must be called before performing any floating point operations. + + @param[in] mask Floating point exception types. Values: \n + - #QURT_FP_EXCEPTION_ALL \n + - #QURT_FP_EXCEPTION_INEXACT \n + - #QURT_FP_EXCEPTION_UNDERFLOW \n + - #QURT_FP_EXCEPTION_OVERFLOW \n + - #QURT_FP_EXCEPTION_DIVIDE0 \n + - #QURT_FP_EXCEPTION_INVALID @tablebulletend + + @return + Updated contents of the USR. + + @dependencies + None. +*/ + +static inline unsigned int qurt_exception_enable_fp_exceptions(unsigned int mask) +{ + return qurt_enable_floating_point_exception(mask); +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EVENT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_except.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_except.h new file mode 100755 index 0000000000000..e1684c80e3d50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_except.h @@ -0,0 +1,185 @@ +#ifndef QURT_EXCEPT_H +#define QURT_EXCEPT_H + +/** + @file qurt_except.h + @brief Defines Cause and Cause2 codes for error-handling. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. + + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + QuRT supports error handling to handle CPU detected exceptions and software errors. + QuRT treats all errors as either fatal errors or nonfatal errors. + + @section sec1 Fatal errors + All supervisor mode exceptions are treated as fatal errors. + If a registered exception handler calls qurt_exit(), it is treated as a fatal error. + Fatal errors result in saving the context of primary hardware thread to QURT_error_info and the rest of the thread contexts to the corresponding TCBs. + All hardware threads are eventually stopped and the cache is flushed. + NMI exception is treated little differently from other fatal errors. QuRT saves the contexts of all the hardware threads into QURT_error_info.\n + + @subsection subsection1 Debugging fatal errors + - QURT_error_info.status.status -- Indicates that an error occured. + - QURT_error_info.status.cause -- Cause code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.cause2 -- Cause2 code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.fatal -- Indicates whether a fatal error occurred. A user error can result in a fatal error if the exceptional handler is not registered. + - QURT_error_info.status.hw_tnum -- Indicates the index of QURT_error_info.locregs[], where the context is saved when the error is fatal error. + - QURT_error_info.global_regs -- Contains the values of the global registers of Q6 + - QURT_error_info.local_regs[QURT_error_info.status.hw_tnum] -- Provides the CPU context when the error is a supervisor error. + + + + @subsection subsection2 Debugging nonfatal errors + - QURT_error_info.user_errors -- All user errors are logged here. + - QURT_error_info.user_errors.counter -- Index to last logged error. + - QURT_error_info.user_errors.entry[0...counter] -- Structure for logged error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb -- TCB for the user error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb.error -- Information about the error; Cause, Cause2, Badva and hardware thread ID. + - QURT_error_info.user_errors.entry[0...counter].error_code -- ((cause2 << 8) 'Logical Or' (cause) ); Cause and Cause 2 details are listed below. + - QURT_error_info.user_errors.entry[0...counter].hw_thread -- Hardware thread ID for error. + - QURT_error_info.user_errors.entry[0...counter].pcycle -- Pcycle for error. + +@note + Important usage note: + Cause and Cause2 are error codes to distinguish multiple errors. + SSR and BADAVA are inconclusive without the vector number. + All cause and cause2 can range from 1 to 255 and every cause can have 1 to 255 error code. + Hence the system can have up to 255 * 255 unique error codes. + The cominations is representated as ((cause2 << 8) 'Logical OR' (cause) ) + Some Cause2 codes are statically defined, whereas some are obtaned from SSR[7:0] cause codes. It depends on cause codes. + SSR cause codes are defined in Hexagon reference manual. + All possible combinations are listed below. +*/ +/** @addtogroup chapter_error +@{ */ +/* cause - error type - 8-bits*/ +#define QURT_EXCEPT_PRECISE 0x01U /**< Precise exception occurred. For this cause code, Cause2 is SSR[7:0].*/ +#define QURT_EXCEPT_NMI 0x02U /**< NMI occurred; Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS 0x03U /**< TLBMISS RW occurred; for this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_RSVD_VECTOR 0x04U /**< Interrupt raised on a reserved vector, which must never occur. Cause2 is not defined. */ +#define QURT_EXCEPT_ASSERT 0x05U /**< Kernel assert. Cause2 QURT_ABORT_* are listed below. */ +#define QURT_EXCEPT_BADTRAP 0x06U /**< trap0(num) called with unsupported num. Cause2 is 0. */ +#define QURT_EXCEPT_UNDEF_TRAP1 0x07U /**< Trap1 is not supported. Using Trap1 causes this error. Cause2 is not defined. */ +#define QURT_EXCEPT_EXIT 0x08U /**< Application called qurt_exit() or qurt_exception_raise_nonfatal(). Can be called from C library. Cause2 is "[Argument passed to qurt_exception_raise_nonfatal() & 0xFF]". */ +#define QURT_EXCEPT_TLBMISS_X 0x0AU /**< TLBMISS X (execution) occurred. Cause2 is not defined. */ +#define QURT_EXCEPT_STOPPED 0x0BU /**< Running thread stopped due to fatal error on other hardware thread. Cause2 is not defined. */ +#define QURT_EXCEPT_FATAL_EXIT 0x0CU /**< Application called qurt_fatal_exit(). Cause2 is not defined. */ +#define QURT_EXCEPT_INVALID_INT 0x0DU /**< Kernel received an invalid L1 interrupt. Cause2 is not defined. */ +#define QURT_EXCEPT_FLOATING_POINT 0x0EU /**< Kernel received an floating point error. Cause2 is not defined. */ +#define QURT_EXCEPT_DBG_SINGLE_STEP 0x0FU /**< Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS_RW_ISLAND 0x10U /**< Read write miss in Island mode. Cause2 QURT_TLB_MISS_RW_MEM* are listed below. */ +#define QURT_EXCEPT_TLBMISS_X_ISLAND 0x11U /**< Execute miss in Island mode. For this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_SYNTHETIC_FAULT 0x12U /**< Synthetic fault with user request that kernel detected. Cause2 QURT_SYNTH_* are listed below. */ +#define QURT_EXCEPT_INVALID_ISLAND_TRAP 0x13U /**< Invalid trap in Island mode. Cause2 is trap number. */ +#define QURT_EXCEPT_UNDEF_TRAP0 0x14U /**< trap0(num) was called with unsupported num. Cause2 is trap number. */ +#define QURT_EXCEPT_PRECISE_DMA_ERROR 0x28U /**< Precise DMA error. Cause2 is DM4[15:8]. Badva is DM5 register. */ + +#define QURT_ECODE_UPPER_LIBC (0U << 16) /**< Upper 16 bits is 0 for libc. */ +#define QURT_ECODE_UPPER_QURT (0U << 16) /**< Upper 16 bits is 0 for QuRT. */ +#define QURT_ECODE_UPPER_ERR_SERVICES (2U << 16) /**< Upper 16 bits is 2 for error service. */ +/** @cond */ +#define QURT_ECODE_ISLAND_INVALID_QDI 3U /**< Passing invalid QDI method in island. */ +/** @endcond */ + +/* Cause2 for QURT_EXCEPT_SYNTHETIC_FAULT cause- 8bits */ +#define QURT_SYNTH_ERR 0x01U /**< */ +#define QURT_SYNTH_INVALID_OP 0x02U /**< */ +#define QURT_SYNTH_DATA_ALIGNMENT_FAULT 0x03U /**< */ +#define QURT_SYNTH_FUTEX_INUSE 0x04U /**< */ +#define QURT_SYNTH_FUTEX_BOGUS 0x05U /**< */ +#define QURT_SYNTH_FUTEX_ISLAND 0x06U /**< */ +#define QURT_SYNTH_FUTEX_DESTROYED 0x07U /**< */ +#define QURT_SYNTH_PRIVILEGE_ERR 0x08U /**< */ + +/* Cause2 - Abort cause reason - 8 bits */ +/* ERR_ASSERT cause */ +#define QURT_ABORT_FUTEX_WAKE_MULTIPLE 0x01U /**< Abort cause - futex wake multiple. */ +#define QURT_ABORT_WAIT_WAKEUP_SINGLE_MODE 0x02U /**< Abort cause - thread waiting to wake up in Single Threaded mode. */ +#define QURT_ABORT_TCXO_SHUTDOWN_NOEXIT 0x03U /**< Abort cause - call TCXO shutdown without exit. */ +#define QURT_ABORT_FUTEX_ALLOC_QUEUE_FAIL 0x04U /**< Abort cause - futex allocation queue failure - QURTK_futexhash_lifo empty. */ +#define QURT_ABORT_INVALID_CALL_QURTK_WARM_INIT 0x05U /**< Abort cause - invalid call QURTK_warm_init() in NONE CONFIG_POWER_MGMT mode. */ +#define QURT_ABORT_THREAD_SCHEDULE_SANITY 0x06U /**< Abort cause - sanity schedule thread is not supposed to run on the current hardware thread. */ +#define QURT_ABORT_REMAP 0x07U /**< Remap in the page table; the correct behavior must remove mapping if necessary. */ +#define QURT_ABORT_NOMAP 0x08U /**< No mapping in page table when removing a user mapping. */ +#define QURT_ABORT_OUT_OF_SPACES 0x09U +#define QURT_ABORT_INVALID_MEM_MAPPING_TYPE 0x0AU /**< Invalid memory mapping type when creating qmemory. */ +#define QURT_ABORT_NOPOOL 0x0BU /**< No pool available to attach. */ +#define QURT_ABORT_LIFO_REMOVE_NON_EXIST_ITEM 0x0CU /**< Cannot allocate more futex waiting queue. */ +#define QURT_ABORT_ARG_ERROR 0x0DU +#define QURT_ABORT_ASSERT 0x0EU /**< Assert abort. */ +#define QURT_ABORT_FATAL 0x0FU /**< Fatal error; must never occur. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_QUEUE 0x10U /**< Abort cause - invalid queue ID in futex resume. */ +#define QURT_ABORT_FUTEX_WAIT_INVALID_QUEUE 0x11U /**< Abort cause - invalid queue ID in futex wait. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_FUTEX 0x12U /**< Abort cause - invalid futex object in hashtable. */ +#define QURT_ABORT_NO_ERHNDLR 0x13U /**< No registered error handler. */ +#define QURT_ABORT_ERR_REAPER 0x14U /**< Exception in the reaper thread. */ +#define QURT_ABORT_FREEZE_UNKNOWN_CAUSE 0x15U /**< Abort in thread freeze operation. */ +#define QURT_ABORT_FUTEX_WAIT_WRITE_FAILURE 0x16U /**< During futex wait processing, could not perform a necessary write operation to userland data; most likely due to a DLPager eviction. */ +#define QURT_ABORT_ERR_ISLAND_EXP_HANDLER 0x17U /**< Exception in Island exception handler task. */ +#define QURT_ABORT_L2_TAG_DATA_CHECK_FAIL 0x18U /**< Detected error in L2 tag/data during warm boot. The L2 tag/data check is done when CONFIG_DEBUG_L2_POWER_COLLAPSE is enabled. */ +#define QURT_ABORT_ERR_SECURE_PROCESS 0x19U /**< Abort error in secure process. */ +#define QURT_ABORT_ERR_EXP_HANDLER 0x20U /**< No exception handler, or the handler caused an exception. */ +#define QURT_ABORT_ERR_NO_PCB 0x21U /**< PCB of the thread context failed initialization, PCB was NULL. */ +#define QURT_ABORT_NO_PHYS_ADDR 0x22U /**< Unable to find the physical address for the virtual address. */ +#define QURT_ABORT_OUT_OF_FASTINT_CONTEXTS 0x23U /**< Fast interrupt contexts exhausted. */ +#define QURT_ABORT_CLADE_ERR 0x24U /**< Fatal error seen with CLADE interrupt. */ +#define QURT_ABORT_ETM_ERR 0x25U /**< Fatal error seen with ETM interrupt. */ +#define QURT_ABORT_ECC_DED_ASSERT 0x26U /**< ECC two-bit DED error. */ +#define QURT_ABORT_VTLB_ERR 0x27U /**< Fatal error in the VTLB layer. */ +#define QURT_ABORT_TLB_ENCODE_DECODE_FAILURE 0x28U /**< Failure during the TLB encode or decode operation. */ +#define QURT_ABORT_VTLB_WALKOBJS_BOUND_FAILURE 0x29U /**< Failure to lookup entry in the page table. */ +#define QURT_ABORT_PHY_MEMORY_OWNERSHIP_FAILURE 0x30U /**< Failure to claim phy memory ownership. */ +#define QURT_ABORT_JTLB_SIZE_CHECK_FAIL 0x31U /**< JTLB size configured is more than actual size in hardware */ +#define QURT_ABORT_AUTOSTACK_ASSERT 0x32U /**< Error while handling stack flimit exception. */ + +/* Cause2 - TLB-miss_X - 8bits */ +#define QURT_TLB_MISS_X_FETCH_PC_PAGE 0x60U /**< */ +#define QURT_TLB_MISS_X_2ND_PAGE 0x61U /**< */ +#define QURT_TLB_MISS_X_ICINVA 0x62U /**< */ + +/* Cause2 - TLB-miss_RW - 8bits */ +#define QURT_TLB_MISS_RW_MEM_READ 0x70U /**< */ +#define QURT_TLB_MISS_RW_MEM_WRITE 0x71U /**< */ + +/** @cond rest_reg_dist */ +/* Cause2 - Floating point exception - 8 bits */ +#define QURT_FLOATING_POINT_EXEC_ERR 0xBFU /**< Execute floating-point. */ +/** @endcond */ + +/** Cause2 - autostackv2 - 8 bits */ +#define QURT_AUTOSTACKV2_CANARY_NOT_MATCH 0xC1U +#define QURT_AUTOSTACKV2_POOL_IDX_OFF_RANGE 0xC2U + +/** Cause2 - CFI violation - 8 bits */ +#define QURT_CFI_VIOLATION 0xC3U + +/** @cond rest_reg_dist*/ +/* Enable floating point exceptions */ +#define QURT_FP_EXCEPTION_ALL 0x1FU << 25 /**< */ +#define QURT_FP_EXCEPTION_INEXACT 0x1U << 29 /**< */ +#define QURT_FP_EXCEPTION_UNDERFLOW 0x1U << 28 /**< */ +#define QURT_FP_EXCEPTION_OVERFLOW 0x1U << 27 /**< */ +#define QURT_FP_EXCEPTION_DIVIDE0 0x1U << 26 /**< */ +#define QURT_FP_EXCEPTION_INVALID 0x1U << 25 /**< */ + +/** @endcond */ +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EXCEPT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fastint.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fastint.h new file mode 100755 index 0000000000000..ea65dc0917fc0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fastint.h @@ -0,0 +1,71 @@ +#ifndef QURT_FASTINT_H +#define QURT_FASTINT_H + +/** + @file qurt_fastint.h + @brief QuRT fast interrupt functions + + Copyright (c) 2013-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_fastint_register + Register fast interrupt callback function + + Fast interrupt callback should be designed to perform the minimal necessary + actions for the interrupt, and/or perform some operations, such as signaling + another regular software thread to start any additional processing. + The callback should be a fast and short function. When a fast interrupt callback + is running, the corresponding interrupt cannot be re-enabled until the callback + returns. + + The fast interrupt callback must not use any system blocking calls, such as + mutex lock or signal wait. Otherwise, it results in errors. + + The fast interrupt callback function has a single integer argument and the + function ends with no return. The argument value passed in is the interrupt + number, and therefore a single callback function can handle + multiple fast interrupts. + + @param[in] intno Interrupt number to register. + @param[in] fn Interrupt callback function. + + @return + #QURT_EOK -- Fast interrupt registration is successful. \n + #QURT_EINVALID -- Interrupt is already registered. \n + #QURT_EINT -- Invalid interrupt number. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_register(int intno, void (*fn)(int)); + + +/*======================================================================*/ +/**@ingroup func_qurt_fastint_deregister + Deregisters the fast interrupt callback function. + + @param[in] intno Level-one interrupt number to deregister. Valid range is 1 and 10 through 31 + (simulator only). + + @return + #QURT_EOK -- Interrupt deregistration is successful. \n + #QURT_EINT -- Invalid interrupt number (not registered). \n + #QURT_EINVALID -- Invalid interrupt number (already deregistered). + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_deregister(int intno); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FASTINT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fs_hub.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fs_hub.h new file mode 100755 index 0000000000000..aaa050a6c838b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_fs_hub.h @@ -0,0 +1,58 @@ +#ifndef QURT_FS_HUB_H +#define QURT_FS_HUB_H + +/** + @file qurt_fs_hub.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver that provides file-system functionality. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + This structure tracks a file-designator for a FS-hub QDI driver. + File system's QDI interface should use this object to encapsulate + true file-descriptor and return back a QDI handle. This QDI handle + will be used as file-descriptor by File-systm-hub. + */ + +typedef struct qurt_qdi_fs_obj +{ + qurt_qdi_obj_t qdi_obj; + int client_handle; + int fd; +}qurt_qdi_fs_obj_t; + + +/**@ingroup fs_hub_support_functions + This function allows a file-system to register it's QDI interface with file-system-hub. + Once registered, all file open operations for any filenames containing the mountpoint will + be forwarded to the QDI inteface. + + Mountpoint string must be encased in two forward slashes e.g. "/mountpoint/" + + @param mtpoint mount point for the file-system being registered. + @param opener opener structure for the QDI driver interface + + @return + QURT_EOK -- Successfully registered QDI driver with file-system-hub. + Negative error code -- Failed to register with file-system-hub + */ +int qurt_fs_hub_mtpoint_register(const char *mtpoint, qurt_qdi_obj_t *opener); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_futex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_futex.h new file mode 100755 index 0000000000000..1fdcc79a43f01 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_futex.h @@ -0,0 +1,82 @@ +#ifndef QURT_FUTEX_H +#define QURT_FUTEX_H +/** + @file qurt_futex.h + + @brief Prototypes of QuRT futex API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Functions +======================================================================*/ + + +/**@ingroup func_qurt_futex_wait + Moves the caller thread into waiting state when a memory object address + contains a value that is the same as a specified value. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait(void *lock, int val); + + +/**@ingroup func_qurt_futex_wait_cancellable + If a memory object address contains a value that is same as a specified + value, move the caller thread into waiting state. + The kernal can cancel the waiting state when there is a special need. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait_cancellable(void *lock, int val); + + +/**@ingroup func_qurt_futex_wake + Wakes up a specified number of threads that have been waiting + for the object change with qurt_futex_wait(). + + @param[in] lock Pointer to the object memory. + @param[in] n_to_wake Maximum number of threads to wake up. + + @return + number of threads to be woken up by this function + + @dependencies + None. + */ +int qurt_futex_wake(void *lock, int n_to_wake); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hmx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hmx.h new file mode 100755 index 0000000000000..e4037dbeae514 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hmx.h @@ -0,0 +1,226 @@ +#ifndef QURT_HMX_H +#define QURT_HMX_H +/** + @file qurt_hmx.h + @brief Prototypes of Qurt HMX API. + +Copyright (c) 2019-2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + + +/** @addtogroup hmx_types +@{ */ +/* HMX locking type */ +#define QURT_HMX_NON_SHARED_LOCK 0U /**< HMX locking type.*/ +#define QURT_HMX_SHARED_LOCK 1U /**< HMX locking type.*/ + +/* HMX unlocking type */ +#define QURT_HMX_NON_SHARED_UNLOCK 0U /**< HMX unlocking type.*/ +#define QURT_HMX_SHARED_UNLOCK 1U /**< HMX unlocking type.*/ + +/* HMX hardware context */ +#define QURT_HMX_UNIT_0 0U /**< HMX hardware context #0 */ +#define QURT_HMX_UNIT_1 1U /**< HMX hardware context #1 */ + /** @} */ /* end_addtogroup hmx_types */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_hmx_lock2 + Locks a HMX unit with the specified locking type. + + #QURT_HMX_NON_SHARED_LOCK: + - If a HMX unit is available, lock the unit and return success of #QURT_EOK. + - If the HMX unit is already locked by another thread, the caller thread is suspended + until the HMX is available and gets locked by this function. + - If there is no HMX hardware supported, returns #QURT_EVAL; + + #QURT_HMX_SHARED_LOCK: + - If a HMX unit is available, enables HMX access for the caller thread, and returns + success of #QURT_EOK. + - If the HMX is enabled on the caller thread, return #QURT_EFAILED. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_SHARED_LOCK, enable HMX access for the caller + thread, and return success of #QURT_EOK. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_NON_SHARED_LOCK, return #QURT_EFAILED. + - If the HMX is locked by a thread from another user process different from the + user process of the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX lock successful.\n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_lock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_unlock2 + Unlocks a HMX unit with the unlocking type. + + #QURT_HMX_NON_SHARED_UNLOCK: + - If there is a HMX unit locked by the caller thread, unlock the HMX unit and clear the + HMX accumulators (assuming a fixed point type). + - If there is no HMX unit locked by the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + #QURT_HMX_SHARED_UNLOCK: + - If the caller thread has locked HMX with type #QURT_HMX_SHARED_LOCK, disable the + HMX access on the caller thread, and return success of #QURT_EOK. + Note: If the caller thread is the last thread that unlocks for #QURT_HMX_SHARED_LOCK + in its user process, the unlock function clears the HMX accumulators. + - If the caller thread has locked HMX with type #QURT_HMX_NON_SHARED_LOCK, return + failure of #QURT_EFAILED. + - If the caller thread has not locked HMX, return failure of #QURT_EFAILED. + - If there is no HMX hardware supported, returns #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX is unlocked successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_unlock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_lock + Locks a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away. + If there is no HMX unit available, the caller is blocked until a HMX is available + and is locked by the function. + + @return + #QURT_EOK -- HMX lock successful. \n + #QURT_EFAILED -- Failure due to wrong locking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_lock(void); + + +/**@ingroup func_qurt_hmx_unlock + Unlocks a HMX unit. + If a HMX unit is locked by the caller thread, unlock the HMX unit and clear its + accumulators(assuming fixed point type). + If there is no HMX unit locked by the caller thread, return failure. + + @return + #QURT_EOK -- HMX unlock successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_unlock(void); + + +/**@ingroup func_qurt_hmx_try_lock + Tries to lock a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away; + if there is no HMX unit available, the function returns failure without blocking the caller. + + @return + #QURT_EOK -- HMX lock successful \n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_try_lock(void); + + +/**@ingroup func_qurt_hmx_assign + Assign a HMX unit to a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + If the requested hmx_unit is already assigned to another thread with QURT_HMX_NON_SHARED_LOCK, + kernel will detach it from the thread, and re-assign it to the target thread. + If the target thread has HVX enabled, it cannot have HMX enabled. + + Locking type + #QURT_HMX_NON_SHARED_LOCK: + - If the HMX unit is available, lock the HMX unit and return success of #QURT_EOK. + - If the HMX unit is already enabled on the target thread, return #QURT_EOK. + - If the HMX unit is already locked by another thread, detach the HMX from the thread. + Re-assign the HMX unit to the target thread, and return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] type Locking type + #QURT_HMX_NON_SHARED_LOCK -- non-shared lock + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is assigned successfully. This includes the case that \n + the target thread already has HMX assigned. \n + #QURT_EFAILED -- Failure due to wrong assigning conditions. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_assign ( unsigned int thread_id, unsigned int type, unsigned int hmx_unit ); + + +/**@ingroup func_qurt_hmx_release + Release a HMX unit from a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + + Qurt detaches the specified HMX unit from the target thread, and return success of + #QURT_EOK. If the HMX unit is already released from the target thread, return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is released successfully. This includes the case that \n + the target thread already has the HMX released. \n + #QURT_EFAILED -- Failure due to wrong assigning condition. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_release ( unsigned int thread_id, unsigned int hmx_unit ); + + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HMX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hvx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hvx.h new file mode 100755 index 0000000000000..13c213d49ac84 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_hvx.h @@ -0,0 +1,421 @@ +#ifndef QURT_HVX_H +#define QURT_HVX_H +/** + @file qurt_hvx.h + @brief Prototypes of QuRT HVX API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @cond */ + +typedef enum { + QURT_HVX_MODE_64B = 0, /**< HVX mode of 64 bytes */ + QURT_HVX_MODE_128B = 1 /**< HVX mode of 128 bytes */ +} qurt_hvx_mode_t; +/** @endcond */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @cond internal_only*/ +/** @addtogroup hvx_macros +@{ */ +#define QURT_HVX_HW_UNITS_2X128B_4X64B 0x00000204 /**< Bits 15 through 8 are for the number of 128B units. */ + /**< Bits 7 through 0 are for the number of 64B units. */ +#define QURT_HVX_HW_UNITS_4X128B_0X64B 0x00000400 +#define QURT_HVX_HW_UNITS_6X128B_0X64B 0x00000600 + +/* HVX locking status */ + +#define QURT_HVX_UNLOCKED (0) /* Has not locked HVX unit */ +#define QURT_HVX_LOCKED (1) /* Has locked HVX unit */ +#define QURT_HVX_ERROR (-1) /* Error, no HVX support */ + +/* Input value for HVX reservation */ + +#define QURT_HVX_RESERVE_ALL (4) /* All the HVX units in terms of 64B_MODE are requested to be reserved */ +#define QURT_HVX_RESERVE_ALL_AVAILABLE (0xff) /* All remaining unlocked HVX units in terms of 64B_MODE are requested to be reserved */ + +/* Return values for HVX reservation */ + +#define QURT_HVX_RESERVE_NOT_SUPPORTED (-1) /* There is no HVX hardware, or less units in the hardware than requested */ +#define QURT_HVX_RESERVE_NOT_SUCCESSFUL (-2) /* Some HVX units are already locked/reserved by other PD, thus not enough units left for the reservation. */ +#define QURT_HVX_RESERVE_ALREADY_MADE (-3) /* There is already a HVX reservation made. */ +#define QURT_HVX_RESERVE_CANCEL_ERR (-4) /* The action of cancling the reservation fails because this protection domain has no reservation made before. */ + +// HVX set requests + +#define QURT_HVX_64B 0 /**< */ +#define QURT_HVX_128B 1 /**< */ +#define QURT_HVX_NO_USE 2 /**< */ +#define QURT_HVX_RELEASE_CONTEXT 3 /**< */ +#define QURT_HVX_IMMEDIATE_USE 4 /**< */ + +// HVX set masks + +#define QURT_HVX_64B_PREFERRED (1<<(QURT_HVX_64B + 8))/**< */ +#define QURT_HVX_128B_PREFERRED (1<<(QURT_HVX_128B + 8))/**< */ +#define QURT_HVX_64B_ACCEPTABLE (1<<(QURT_HVX_64B + 12))/**< */ +#define QURT_HVX_128B_ACCEPTABLE (1<<(QURT_HVX_128B + 12))/**< */ + +// HVX set return "result" + +#define QURT_EOK 0 /**< */ +#define QURT_HVX_SET_ERROR 0xFF /**< */ + +// hvx_mode_assigned for QURT_HVX_IMMEDIATE_USE +#define QURT_HVX_64B_ASSIGNED (1<<(QURT_HVX_64B + 8)) /**< */ +#define QURT_HVX_128B_ASSIGNED (1<<(QURT_HVX_128B + 8)) /**< */ + +// Sizes of HVX dump buffer + +#define QURT_HVX_V65_64B_VSIZE 2084U /**< 64 x 32 + 8 x 4 + 4 (version). */ +#define QURT_HVX_V65_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V66_128B_VSIZE 4420U /**< 128 x (32 +2) + 16 x 4 + 4 (version). */ +#define QURT_HVX_V68_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V79_128B_VSIZE 4740U /**< 128 x (32+4+1) + 4 (version). */ +#define QURT_HVX_VREG_BUF_SIZE QURT_HVX_V79_128B_VSIZE /**< */ + +// HVX dump versions + +#define QURT_HVX_DUMP_V65_64B 1U /**< */ +#define QURT_HVX_DUMP_V65_128B 2U /**< */ +#define QURT_HVX_DUMP_V66_128B 3U /**< */ +#define QURT_HVX_DUMP_V68_128B 4U /**< */ +#define QURT_HVX_DUMP_V79_128B 5U /**< */ +/** @} */ /* end_addtogroup hvx_macros */ +/** @endcond */ +/** @cond */ +// Qurt data struct for hvx_set input +typedef struct qurt_hvx_set_struct_ { + unsigned char set_req; // LSB + struct { + unsigned char preferred_mask:4; + unsigned char acceptable_mask:4; + }; + unsigned short resvd; // MSB +} qurt_hvx_set_struct_t; // 4 bytes + + +// Qurt data struct for hvx_set return +typedef struct qurt_hvx_set_return_str_ { + unsigned char result; // LSB + unsigned char hvx_mode_assigned; + unsigned short resvd; // MSB +} qurt_hvx_set_return_struct_t; // 4 bytes +/** @endcond */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_hvx_lock + Locks one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns right away. + If the current HVX mode is different from the requested mode, the current + thread is blocked. When all HVX units become idle, QuRT changes + the mode, locks the HVX unit, and returns. + + Starting from Q6v65 with HVX context switch support, qurt_hvx_lock() is + mapped as qurt_hvx_set(64_BYTE or 128_BYTE). + + @datatypes + #qurt_mode_t + + @param[in] lock_mode #QURT_HVX_MODE_64B or #QURT_HVX_MODE_128B. + + @return + #QURT_EOK -- Success \n + Other value -- Failure + + @dependencies + None. + + */ +int qurt_hvx_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_unlock + Unlocks the HVX unit held by this software thread. + + @note1hang Starting from Q6v65 with HVX context switch support, qurt_hvx_unlock() + maps as qurt_hvx_set(QURT_HVX_RELEASE_CONTEXT). + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_unlock(void); + +/**@ingroup func_qurt_hvx_try_lock + Tries to lock one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns #QURT_EOK; Otherwise, + the function returns a failure, but does not block the current software + thread to wait for the HVX unit. + Starting from Q6v65 with HVX context switch support, qurt_hvx_try_lock() + maps to qurt_hvx_set(FOR_IMMEDIATE_USE| preferred_mask | acceptable_mask); + + @datatypes + #qurt_mode_t + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_try_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_get_mode + Gets the current HVX mode configured by QuRT. + + @note1hang Returns #QURT_HVX_MODE_128B or #QURT_HVX_MODE_64B, based on + the current HVX configuration. + + @param[out] + None. + + @return + #QURT_HVX_MODE_128B \n + #QURT_HVX_MODE_64B \n + -1 -- Not available. + + @dependencies + None. + */ +int qurt_hvx_get_mode(void); + + +/**@ingroup func_qurt_hvx_get_units + Gets the HVX hardware configuration that the chipset supports. + + @note1hang The function returns the HVX hardware configuration supported by the chipset. + + @return + Bitmask of the units: 1X64, 2X64, 4X64, 1X128, 2X128, and so on.\n + - QURT_HVX_HW_UNITS_2X126B_4X64B -- V60, V62, or V65 HVX \n + - QURT_HVX_HW_UNITS_4X128B_0X64B -- V66 CDSP or newer \n + - 0 -- not available + + @dependencies + None. + + */ +int qurt_hvx_get_units(void); + + +/**@ingroup func_qurt_hvx_reserve + Reserves HVX units in terms of 64-byte mode for the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + If one HVX unit is already locked by the application in the same PD, the unit is + added to the returned count as one reserved unit for the PD. + Starting from Q6v65 with HVX context switch support, qurt_hvx_reserve() + only does basic sanity checks on HVX units. + + @datatypes + None. + + @param[in] num_units Number of HVX units in terms of 64B_MODE to reserve for the PD. + QURT_HVX_RESERVE_ALL to reserve all the HVX units. + QURT_HVX_RESERVE_ALL_AVAILABLE to reserve the remaining unlocked units. + + @return + Number of units successfully reserved, including the units already locked in the same PD. \n + #QURT_HVX_RESERVE_NOT_SUPPORTED \n + #QURT_HVX_RESERVE_NOT_SUCCESSFUL \n + #QURT_HVX_RESERVE_ALREADY_MADE + + + @dependencies + None. + + */ +int qurt_hvx_reserve(int num_units); + + +/**@ingroup func_qurt_hvx_cancel_reserve + Cancels the HVX reservation in the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + + @return + 0 -- Success \n + #QURT_HVX_RESERVE_CANCEL_ERR -- Failure + + @dependencies + None. + + */ +int qurt_hvx_cancel_reserve(void); + + +/**@ingroup func_qurt_hvx_get_lock_val + Gets the HVX locking status value of the thread of the caller. + + @note1hang Returns the status of whether the thread of the caller already locks a HVX unit or not. + + @datatypes + None. + + @return + #QURT_HVX_UNLOCKED \n + #QURT_HVX_LOCKED \n + #QURT_HVX_ERROR + + @dependencies + None. + */ +int qurt_hvx_get_lock_val(void); + +/** @cond internal_only*/ +/**@ingroup func_qurt_hvx_set + Sets the HVX configuration for the software thread of the caller. + + @datatypes + None. + + @param[in] input_arg Composed of set_request | hvx_preferred_mode_mask + | hvx_acceptable_mode_mask where set_request can be set to: \n + - #QURT_HVX_64B \n + - #QURT_HVX_128B \n + - #QURT_HVX_NO_USE \n + - #QURT_HVX_RELEASE_CONTEXT \n + - #QURT_HVX_IMMEDIATE_USE \n + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_preferred_mode_mask can be set to: \n + - #QURT_HVX_64B_PREFERRED \n + - #QURT_HVX_128B_PREFERRED + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_acceptable_mode_mask can be set to: \n + - #QURT_HVX_64B_ACCEPTABLE \n + - #QURT_HVX_128B_ACCEPTABLE @tablebulletend + + @return + Result of the HVX setting in the least significant 8 bits of the returned data. \n + #QURT_EOK -- 0 \n + #QURT_HVX_SET_ERROR -- 0xFF \n + When #QURT_HVX_IMMEDIATE_USE has a result of #QURT_EOK, + bit 8 to bit 15 of the returned data contain hvx_mode_assigned:\n + - #QURT_HVX_64B_ASSIGNED \n + - #QURT_HVX_128B_ASSIGNED + + @dependencies + None. + */ +unsigned int qurt_hvx_set(unsigned int input_arg); + + +/**@ingroup func_qurt_system_hvx_regs_get_maxsize + Returns the maximum buffer size for saving HVX registers. + + @datatypes + None. + + @return + 0 -- No HVX supported in the target. \n + #QURT_HVX_VREG_BUF_SIZE -- Maximum buffer size for saving HVX registers. + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get_maxsize(void); + + +/**@ingroup func_qurt_system_hvx_regs_get_size + Returns the buffer size for saving HVX registers for a specified thread. + + @param[in] thread_id Thread ID of the target thread. + + @return + 0 -- No HVX assgined to the thread. \n + size -- Size of the buffer in bytes for saving HVX registers for the specified thread: \n + - #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + - #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + - #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + + @dependencies + None. + + */ +unsigned int qurt_system_hvx_regs_get_size(unsigned int thread_id); + + + +/**@ingroup func_qurt_system_hvx_regs_get + Saves the HVX registers into the specified buffer. + Returns the size of the data saved into the buffer. + After calling this function for the first time on a specified thread_id, the QuRT kernel removes the internal HVX saving buffer + from the specified thread. When calling the function on the same thread_id for the second time, this function returns 0. + + @param[in] thread_id Thread ID of the target thread. + @param[in] pBuf Pointer to the buffer for HVX register saving. + The first four bytes of the buffer are for saving the HVX version. HVX registers are saved from + the fifth byte of the buffer. The address of the fifth byte should be 256 bytes aligned. + For example, a buffer can be declared at first as: \n + unsigned char vbuf[QURT_HVX_VREG_BUF_SIZE+256];\n + unsigned char *pBuf; \n + then align the buffer pointer to: \n + pBuf = vbuf; \n + pBuf += (256 - 4 - (unsigned)pBuf%256); + @param[in] size Size of the buffer provided, which is pointed by *pBuf. The buffer size should not be smaller than that + returned from qurt_system_hvx_regs_get_size(), and pBuf should be aligned as described above. + @param[out] pBuf Buffer returned with the saved HVx registers (unsigned char hvx_regs[];), which are saved from the fith + byte of the buffer, and the HVX version (unsigned int hvx_version;), which in the first four bytes + contain one of the HVX dump versions:\n + - #QURT_HVX_DUMP_V65_64B \n + - #QURT_HVX_DUMP_V65_128B \n + - #QURT_HVX_DUMP_V66_128B \n + - #QURT_HVX_DUMP_V68_128B \n + - #QURT_HVX_DUMP_V79_128B \n + @tablebulletend + + @return + Total bytes of the data saved in the provided buffer. \n + 0 -- No HVX assigned to the thread \n + #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get(unsigned int thread_id, void *pBuf, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HVX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_int.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_int.h new file mode 100755 index 0000000000000..386aeda1051eb --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_int.h @@ -0,0 +1,509 @@ +#ifndef QURT_INT_H +#define QURT_INT_H +/** + @file qurt_int.h + @brief QuRT interrupt functions. + + + + Copyright (c) 2013-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/** @cond rest_reg_dist */ +/** @addtogroup interrupts_constants +@{ */ +#define SIG_INT_ABORT 0x80000000 /**< */ +#define QURT_INT_NON_DELAYED_ACK 0 +#define QURT_INT_DELAYED_ACK 1 +#define QURT_INT_ACK_DEFAULT QURT_INT_NON_DELAYED_ACK +#define QURT_INT_DRV_DEFAULT 0 +#define QURT_INT_PRIORITY_DEFAULT 0xFF + +/** QuRT interrupt property. */ +#define QURT_INT_CONFIGID_POLARITY 0x1U /**< */ +#define QURT_INT_CONFIGID_LOCK 0x2U /**< */ + +/** QuRT interrupt lock.*/ +#define QURT_INT_LOCK_DEFAULT 0x0 /**< Default. */ +#define QURT_INT_LOCK_DISABLE 0x0 /**< Interrupt can be enabled or disabled or deregistered. */ +#define QURT_INT_LOCK_ENABLE 0x1 /**< Interrupt is locked and cannot be enabled, disabled, or deregistered.*/ +/** @} */ /* end_addtogroup interrupts_constants */ + +/** @addtogroup Qurt_interrupt_type +@{ */ +/** Trigger type bit fields for a PDC interrupt:\n + @verbatim + Polarity Edge Output\n + 0 00 Level sensitive active low + 0 01 Rising edge sensitive + 0 10 Falling edge sensitive + 0 11 Dual edge sensitive + 1 00 Level sensitive active high + 1 01 Falling edge sensitive + 1 10 Rising edge sensitive + 1 11 Dual edge sensitive + @endverbatim +*/ +#define QURT_INT_TRIGGER_TYPE_SET(pol, edge) ((((pol) & 0x01U) << 2) | ((edge) & 0x03U)) /**< */ + +#define QURT_INT_TRIGGER_LEVEL_LOW QURT_INT_TRIGGER_TYPE_SET(0U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_LEVEL_HIGH QURT_INT_TRIGGER_TYPE_SET(1U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_RISING_EDGE QURT_INT_TRIGGER_TYPE_SET(1U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_FALLING_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_DUAL_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x03U) /**< */ +#define QURT_INT_TRIGGER_USE_DEFAULT 0xffU /**< */ +/** @} */ /* end_addtogroup Qurt_interrupt_type */ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_interrupt_register + @xreflabel{sec:interrupt_register} + Registers the interrupt.\n + Enables the specified interrupt and associates it with the specified QuRT signal object and + signal mask. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register(int int_num, qurt_anysignal_t *int_signal, int signal_mask); + +/**@ingroup func_qurt_interrupt_register2 + @xreflabel{sec:interrupt_register2} + Registers the interrupt.\n + Enables the specified interrupt, associates it with the specified QuRT signal object and + signal mask, and sets interrupt flags. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals that the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value #QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value #QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + #QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + @param[in] flags Defines interrupt property, supported property is interrupt lock enable/disable. + Possible values for flags: \n + - #QURT_INT_LOCK_ENABLE + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register2(int int_num, qurt_anysignal_t *int_signal, int signal_mask, unsigned int flags); +/* + * Waits for registered interrupt signal + + * Suspend the current thread until one of its registered interrupts occurs. The second input mask, + * contains the interrupt signals the IST expects to receive. The interrupt signals are registered + * with interrupts via qurt_register_interrupt API. + * + * The signals returned in the signal variable indicate which interrupts occurred. Use function + * qurt_anysignal_get to read the signals. IST must locally maintain a table that maps a signal to + * a specific interrupt. IST also checks if signal #SIG_INT_ABORT is received. If so, the IST + * must quit from interrupt receiving loop. + * + * For detail information on this API, see QuRT User Manual Section 4.2.5 + * + * Prototype + * + * unsigned int qurt_anysignal_wait(qurt_anysignal_t *int_signal, unsigned int mask) + */ + +/**@ingroup func_qurt_interrupt_acknowledge + Acknowledges an interrupt after it has been processed.\n + Re-enables an interrupt and clears its pending status. This is done after an interrupt is + processed by an IST. + + Interrupts are automatically disabled after they occur. To re-enable an interrupt, an IST + performs the acknowledge operation after it has finished processing the interrupt and + just before suspending itself (such as by waiting on the interrupt signal). + + @note1hang To prevent losing or reprocessing subsequent occurrences of the interrupt, + an IST must clear the interrupt signal (Section @xref{sec:anysignal_clear}) before + acknowledging the interrupt. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Interrupt acknowledge was successful. \n + #QURT_EDEREGISTERED -- Interrupt is already de-registered. + + @dependencies + None. +*/ +int qurt_interrupt_acknowledge(int int_num); + +/**@ingroup func_qurt_interrupt_deregister + Disables the specified interrupt and disassociates it from a QuRT signal object. + If the specified interrupt was never registered (Section @xref{sec:interrupt_register}), the deregister operation + returns the status value #QURT_EINT. + + @note1hang If an interrupt is deregistered while an IST waits + to receive it, the IST might wait indefinitely for the interrupt to occur. To avoid + this problem, the QuRT kernel sends the signal #SIG_INT_ABORT to awaken an + IST after determining that it has no interrupts registered. + + @param[in] int_num L2VIC to deregister; valid range is 0 to 1023. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number (not registered). + + @dependencies + None. + +*/ +unsigned int qurt_interrupt_deregister(int int_num); +/** @endcond */ + +/**@ingroup func_qurt_interrupt_disable + Disables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + After qurt_interrupt_disable() returns, the Hexagon subsystem + can no longer send the corresponding interrupt to the Hexagon + core, until qurt_interrupt_enable() is called + for the same interrupt. + + Avoid calling qurt_interrupt_disable() and qurt_interrupt_enable() frequently within + a short period of time.\n + - A pending interrupt can already be in the Hexagon core when qurt_interrupt_disable() + is called. Therefore, some time later, the pending interrupt is received on a Hexagon + hardware thread.\n + - After the Hexagon subsystem sends an interrupt to the Hexagon core, the Hexagon + hardware automatically disables the interrupt until kernel software re-enables the interrupt + at the interrupt acknowledgement stage. If qurt_interrupt_enable() is called from a certain + thread at an ealier time, the interrupt is re-enabled earlier and can trigger + sending a new interrupt to the Hexagon core while kernel software is still processing + the previous interrupt. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully disabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_disable(int int_num); + + +/**@ingroup func_qurt_interrupt_enable + Enables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully enabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. + +*/ + unsigned int qurt_interrupt_enable(int int_num); + + +/**@ingroup func_qurt_interrupt_status + Returns a value that indicates the pending status of the specified interrupt. + + @param[in] int_num Interrupt number that is being checked. + @param[out] status Interrupt status; 1 indicates that an interrupt is + pending, 0 indicates that an interrupt is not pending. + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_status(int int_num, int *status); + + +/**@ingroup func_qurt_interrupt_get_status + Gets the status of the specified interrupt in L2VIC. + + @param[in] int_num Interrupt number that is being checked. + @param[in] status_type 0 -- interrupt pending status \n + 1 -- interrupt enabling status + @param[out] status 0 -- OFF \n + 1 -- ON + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_status(int int_num, int status_type, int *status); + +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_interrupt_clear + Clears the pending status of the specified interrupt. + + @note1hang This operation is intended for system-level use, and must be used with care. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_clear(int int_num); + + +/**@ingroup func_qurt_interrupt_get_config + Gets the L2VIC interrupt configuration. \n + This function returns the type and polarity of the specified L2VIC interrupt. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[out] int_type Pointer to an interrupt type. \n + 0 -- Level-triggered interrupt \n + 1 -- Eedge-triggered interrupt + @param[out] int_polarity Pointer to interrupt polarity.\n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt. + + @return + #QURT_EOK -- Configuration successfully returned.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_config(unsigned int int_num, unsigned int *int_type, unsigned int *int_polarity); + +/**@ingroup func_qurt_interrupt_set_config + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang Deregister L2VIC interrupts before reconfiguring them. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Interrupt type. \n + 0 -- Level-triggered interrupt\n + 1 -- Edge-triggered interrupt + @param[in] int_polarity Interrupt polarity. \n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config(unsigned int int_num, unsigned int int_type, unsigned int int_polarity); + +/**@ingroup func_qurt_interrupt_set_config2 + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Notified to the hardware configuration callback function and used to + modify the L2VIC type. Possible values: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config2(unsigned int int_num, unsigned int int_type); + +/**@ingroup func_ qurt_interrupt_set_config3 + Sets the specified configuration value for the specified property of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured for polarity. + + @param[in] int_num L2VIC interrupt to re-enable. + @param[in] config_id Property to configure: \n + - #QURT_INT_CONFIGID_POLARITY \n + - #QURT_INT_CONFIGID_LOCK @tablebulletend + @param[in] config_val Dependent on the second argument config_id, specifies the value to set. \n + Values for #QURT_INT_CONFIGID_POLARITY: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE \n + + Values for #QURT_INT_CONFIGID_LOCK: \n + - #QURT_INT_LOCK_ENABLE\n + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered or is locked for enable/disable.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. +*/ +unsigned int qurt_interrupt_set_config3(unsigned int int_num, unsigned int config_id, unsigned int config_val); + + +/**@ingroup func_qurt_interrupt_raise + Raises the interrupt. \n + This function triggers a level-triggered L2VIC + interrupt, and accepts interrupt numbers in the range of 0 to 1023. + + @param[in] interrupt_num Interrupt number. + + @return + #QURT_EOK -- Success \n + -1 -- Failure; the interrupt is not supported. + + @dependencies + None. + */ +int qurt_interrupt_raise(unsigned int interrupt_num); + +/**@ingroup func_qurt_interrupt_raise2 + Raises the interrupt and returns the current pcycle value. + + @param[in] interrupt_num Interrupt number. + + @return + 0xFFFFFFFFFFFFFFFF -- Failure; the interrupt is not supported.\n + Other value -- pcycle count at the time the interrupt is raised. + + @dependencies + None. + */ +unsigned long long qurt_interrupt_raise2(unsigned int interrupt_num); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_isr_subcall + Indicates whether the current function is called from a callback procedure (either short or long). + + @return + #QURT_EOK -- TRUE \n + #QURT_EVAL -- FALSE. + + @dependencies + None. + */ +int qurt_isr_subcall(void); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_INT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_island.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_island.h new file mode 100755 index 0000000000000..f0c8ee27cf8b0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_island.h @@ -0,0 +1,122 @@ +#ifndef QURT_ISLAND_H +#define QURT_ISLAND_H + +/** + @file qurt_island.h + @brief Prototypes of power API + The APIs allow entering and exiting island mode where the memory + accesses are limited to local memory. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_island_get_status + Gets Island mode status. + + Returns a value that indicates whether the QuRT system executes in Island mode. + + @return + 0 - Normal mode. \n + 1 - Island mode. + + @dependencies + None. +*/ +unsigned int qurt_island_get_status (void); + +/**@ingroup func_qurt_island_get_status2 + Gets Island mode status especially that differentiates between island partial exit and complete exit. + + Returns a value that indicates the current state. + + @note1hang Transition from NORMAL mode to ISLAND mode happens in single + threaded mode. Whereas transition from ISLAND mode to other modes + happen in multi-threaded mode. So, a thread that gets island mode + status as NORMAL can assume the same status till it continues to + run. A thread that gets island mode status as ISLAND should + assume that the status may change to EXITING or NORMAL while it + runs. A thread that gets island mode status as EXITING should + assume that the status may change to NORMAL while it runs. If + the thread goes to wait state in after reading the status, it should get + the island mode state again and not assume the previous state. + @note2hang This api returns more intrinsic states than qurt_island_get_status, + when qurt_island_get_status returns 0, this api could return + QURT_ISLAND_MODE_EXITING or QURT_ISLAND_MODE_ISLAND + + @param[in/out] data field is reserved for future use. If NULL pointer is passed, + the field will be ignored. If a valid pointer is passed, + QuRT will return back a bitmask which can be interpreted as follows: + data[31] - Valid bit. Set to 1 to indicate data[30:0] are valid. + Otherwise set to 0. + data[30:0] – Reserved for future definition. + + @return + QURT_ISLAND_MODE_NORMAL - Main mode \n + QURT_ISLAND_MODE_ISLAND - Island mode \n + QURT_ISLAND_MODE_EXITING - Exiting Island mode \n + + @dependencies + None. +*/ +unsigned int qurt_island_get_status2 (unsigned int *data); + + + +/**@ingroup func_qurt_island_get_exit_status + Gets the reason for the last Island mode exit status. + + @param[out] cause_code Pointer that returns the cause code of the last + island exit reason. \n + - #QURT_EISLANDUSEREXIT -- Island exit due to user call for island exit.\n + - #QURT_ENOISLANDENTRY -- API called before exiting island. \n + - #QURT_EISLANDINVALIDINT -- Island exit due to an invalid interrupt in Island mode. @tablebulletend + + @param[out] int_num Pointer that holds the invalid interrupt number that caused + island exit when the cause code is #QURT_EISLANDINVALIDINT. + For other cases, it is -1. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_exit_status(unsigned int *cause_code, int *int_num); + +/**@ingroup func_qurt_island_get_enter_timestamp + Gets the recent timestamp when the system exits STM during island enter. + + @param[out] island_enter_timestamp Returns a pointer to the recent timestamp + recorded after the system exits STM during island enter. If the system never + attempts to enter island, the island_enter_timestamp return pointer holds a value + of zero. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_enter_timestamp(unsigned long long *island_enter_timestamp); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISLAND_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_isr.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_isr.h new file mode 100755 index 0000000000000..db29ea2f265d7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_isr.h @@ -0,0 +1,177 @@ +#ifndef QURT_ISR_H +#define QURT_ISR_H + +/*===================================================================== + + @file qurt_isr.h + + @brief Prototypes of Qurt ISR API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2017, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + Functions +=============================================================================*/ + + +/**@ingroup func_qurt_isr_set_hw_config_callback + Set callback function for the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_config_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_enable_callback + Set callback function for enabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_enable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_disable_callback + Set callback function for disabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_disable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_create + Creates an ISR thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + + @return + #QURT_EVAL -- Invalid arguments + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_isr_create (qurt_thread_t *thread_id, qurt_thread_attr_t *pAttr); + +/**@ingroup func_qurt_isr_register2 + Registers an Interrupt Service Routine to an ISR thread. ISR callback with the specified attributes. + The interrupt is enabled when this function returns success. + + @datatypes + qurt_thread_t + + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create() + @param[in] int_num The interrupt number + @param[in] prio Priority of the ISR + @param[in] flags Defines ACK type. Values : \n + QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the Kernel. + QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + @param[in] int_type. Notifies it to registered function. Values: \n + - QURT_INT_TRIGGER_USE_DEFAULT + - QURT_INT_TRIGGER_LEVEL_HIGH + - QURT_INT_TRIGGER_LEVEL_LOW + - QURT_INT_TRIGGER_RISING_EDGE + - QURT_INT_TRIGGER_FALLING_EDGE + - QURT_INT_TRIGGER_DUAL_EDGE + @param[in] isr Interrupt Service Routine with proto type void isr (void *arg, int int_num) + @param[in] arg 1st argument of the ISR when it is called to service the interrupt + + @return + QURT_EOK -- Successfully registered the ISR for the interrupt + QURT_EINT -- Interrupt not configured + QURT_EINVALID -- Invalid Thread ID + QURT_EDISABLED -- The feature is disabled + QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_register2 (qurt_thread_t isr_thread_id, int int_num, unsigned short prio, unsigned short flags, unsigned int int_type, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_isr_deregister2 + De-registers the ISR for the specified interrupt. + The interrupt is disabled when this function returns success. + + @param[in] int_num The interrupt number + + @return + QURT_EOK -- ISR deregistered successfully + QURT_ENOREGISTERED -- Interrupt with int_num is not registered + + @dependencies + None. + */ +int qurt_isr_deregister2 (int int_num); + +/**@ingroup func_qurt_isr_delete + ISR thread will exit and releases Kernel resources + + @note1hang The ISR thread shouldn't be actively processing interrupts, + otherwise the call will fail and return an error. + + @param[in] thread-id of the ISR thread that needs to be deleted. + + @return + QURT_ENOTALLOWED -- ISR thread is processing an interrupt + QURT_EINVALID -- Invalid ISR thread ID + QURT_EOK -- Success + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_delete (qurt_thread_t isr_tid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISR_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_l2cfg.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_l2cfg.h new file mode 100755 index 0000000000000..7e26b30a580d9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_l2cfg.h @@ -0,0 +1,98 @@ +#ifndef QURT_L2CFG_H +#define QURT_L2CFG_H +/** + @file qurt_l2cfg.h + @brief QuRT APIs for L2 configuration and system configuration + +EXTERNAL FUNCTIONS + qurt_l2cfg_set + qurt_l2cfg_get + qurt_system_config_get + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +/* Definition for system configuration */ +/** @addtogroup l2cfg_macros +@{ */ +#define QURT_CORE_CFG_HMX_INT8_SPATIAL 0x78 /**< HMX fixed-point spatial size */ +#define QURT_CORE_CFG_HMX_INT8_DEPTH 0x7C /**< HMX fixed-point output depth */ +/** @} */ /* end_addtogroup l2cfg_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_l2cfg_set + Sets the value of a L2 configuration register. A register can be set *IFF* its + initial value is configured. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[in] value Value to set the register to. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; likely + a configuration problem. \n + #QURT_EINVALID -- Argument error. \n + #QURT_ENOTALLOWED -- Setting this register is prohibited. + + @dependencies + None. + */ +int qurt_l2cfg_set (unsigned short offset, unsigned int value); + +/**@ingroup func_qurt_l2cfg_get + Gets the value of a L2 configuration register. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[out] value Pointer to value of the register. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; + likely a configuration problem. \n + #QURT_EINVALID -- Argument error. + + @dependencies + None. + + */ +int qurt_l2cfg_get (unsigned short offset, unsigned int * value); + + +/**@ingroup func_qurt_system_config_get + Gets the system configuration information. + + @param[in] index Index to system configuration. Values:\n + - #QURT_CORE_CFG_HMX_INT8_SPATIAL \n + - #QURT_CORE_CFG_HMX_INT8_DEPTH @tablebulletend + + @param[out] data Pointer to a word for returned data. + + @return + #QURT_EOK -- Get the configuration data successful. \n + Other values -- Failure (no such configuration available). + + @dependencies + None. + + */ +int qurt_system_config_get(int index, unsigned int *data); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_L2CFG_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_lifo.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_lifo.h new file mode 100755 index 0000000000000..dc399fccc5f0f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_lifo.h @@ -0,0 +1,71 @@ +#ifndef QURT_LIFO_H +#define QURT_LIFO_H +/** + @file qurt_lifo.h + + @brief + Provide lock free LastInFirstOut algorithm, which can be used in a + variety of situations for allocation/free fixed size buffer + This implementation touches the first word of your FREED buffer. Even + though it does not matter how you use it when it is allocated, you might want + to be a bit careful not to put your MAGIC number as the first field. + Because it will not hold the magic value for "freed" + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ +/** + Pops an element out of the LIFO. + + @param[in] freelist Pointer to the head of your list. + + @return + Top object from the list + + @dependencies + None. +*/ +/* ======================================================================*/ +void * qurt_lifo_pop(void *freelist); + + +/*======================================================================*/ +/** + Pushes an element into the LIFO. + + @param[in] freelist Pointer to the head of your list. + @param[in] buf Pointer to your buffer to push into the list. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_lifo_push(void *freelist, void *buf); + +void qurt_lifo_remove(void *freelist, void *buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_LIFO_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mailbox.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mailbox.h new file mode 100755 index 0000000000000..a6cd91c611782 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mailbox.h @@ -0,0 +1,176 @@ +#ifndef QURT_MAILBOX_H +#define QURT_MAILBOX_H + +/** + @file qurt_mailbox.h + @brief Definitions, macros, and prototypes used for QuRT mailbox + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* Definitions on typedef and return values */ + +#define QURT_MAILBOX_ID_NULL 0 +#define QURT_MAILBOX_ERROR -1 +#define QURT_MAILBOX_ID_ERROR -2 +#define QURT_MAILBOX_NON_VALID_DATA -3 +#define QURT_MAILBOX_FULL -4 +#define QURT_MAILBOX_DELETED -5 +#define QURT_MAILBOX_RECEIVE_HALTED -6 +#define QURT_MAILBOX_BANDWIDTH_LIMIT -7 + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ + +#define QURT_MAILBOX_AT_QURTOS 0U // Receiver is QurtOS +#define QURT_MAILBOX_AT_ROOTPD 1U // Receiver is RootPD (ASID=0) +#define QURT_MAILBOX_AT_USERPD 2U // Receiver is User PD (ASID!=0) +#define QURT_MAILBOX_AT_SECUREPD 3U // Receiver is Secure PD + +typedef unsigned char qurt_mailbox_receiver_cfg_t; + +#define QURT_MAILBOX_SEND_OVERWRITE 0U // When there is already valid content, overwrite it +#define QURT_MAILBOX_SEND_NON_OVERWRITE 1U // When there is already valid content, return failure + +typedef unsigned char qurt_mailbox_send_option_t; + + +#define QURT_MAILBOX_RECV_WAITING 0U // When there is no valid content, wait for it +#define QURT_MAILBOX_RECV_NON_WAITING 1U // When there is no valid content, return failure immediately +#define QURT_MAILBOX_RECV_PEEK_NON_WAITING 2U // Read the content, but doesn't remove it from the mailbox. No waiting. + +typedef unsigned char qurt_mailbox_recv_option_t; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/* Function prototype */ + +/**@ingroup qurt_mailbox_create + Creates a QuRT mailbox. + + @param name Mailbox name up to 8 characters. + @param recv_opt Configuration on the receiver process. + + @return + Mailbox ID -- Mailbox Identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at creating mailbox + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_create(char *name, qurt_mailbox_receiver_cfg_t recv_opt); + + +/**@ingroup qurt_mailbox_get_id + Gets a QuRT mailbox identifier. + + @param name Mailbox name up to 8 characters. + + @return + Mailbox ID -- Mailbox identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at getting mailbox ID + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_get_id(char *name); + + +/**@ingroup qurt_mailbox_send + Sends data to a QuRT mailbox. + + @param mailbox_id Mailbox identifier. + @param send_opt Option for mailbox send. + @param data Data to send. + + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors.\n + #QURT_MAILBOX_FULL Valid data already exists, non-overwriting.\n + #QURT_MAILBOX_BANDWIDTH_LIMIT Reached the bandwidth limitation. + + @dependencies + None. +*/ +int qurt_mailbox_send(unsigned long long mailbox_id, qurt_mailbox_send_option_t send_opt, unsigned long long data); + + +/**@ingroup qurt_mailbox_receive + Receive data from QuRT mailbox + + @param mailbox_id Mailbox Identifier + @param send_opt Option for mailbox receiving + @param data Pointer to data buffer for receiving + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. \n + #QURT_MAILBOX_NON_VALID_DATA No current valid data, put the previous content in the buffer. \n + #QURT_MAILBOX_RECEIVE_HALTED Receive halted, the waiting thread is woken up. \n + #QURT_MAILBOX_DELETED Mailbox is deleted, and the waiting thread is woken up. + + @dependencies + None. +*/ +int qurt_mailbox_receive(unsigned long long mailbox_id, qurt_mailbox_recv_option_t recv_opt, unsigned long long *data); + + +/**@ingroup qurt_mailbox_delete + Deletes a QuRT mailbox. + + A mailbox can only be deleted from the process that created the mailbox. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_delete(unsigned long long mailbox_id); + + +/**@ingroup qurt_mailbox_receive_halt + Halts a QuRT mailbox receiving and wakes up waiting threads. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_receive_halt(unsigned long long mailbox_id); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_MAILBOX_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_memory.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_memory.h new file mode 100755 index 0000000000000..90ce2586fec50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_memory.h @@ -0,0 +1,1487 @@ +#ifndef QURT_MEMORY_H +#define QURT_MEMORY_H +/** + @file qurt_memory.h + @brief Prototypes of kernel memory API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup memory_management_macros +@{ */ +#define QURT_SYSTEM_ALLOC_VIRTUAL 1 /**< Allocates available virtual memory in the address space of all + processes.*/ +/** @} */ /* end_addtogroup memory_management_macros */ +/**@cond rest_reg_dist */ +/** @addtogroup memory_management_types +@{ */ +/** @xreflabel{hdr:qurt_mem_default_pool} */ +extern qurt_mem_pool_t qurt_mem_default_pool __attribute__((section(".data"))); /**< Memory pool object.*/ +/** @} */ /* end_addtogroup memory_management_types */ + +/** @cond rest_reg_dist */ +/** Mapping attribute information*/ +typedef struct{ + qurt_paddr_64_t paddr; + qurt_size_t size ; + qurt_mem_cache_mode_t cache_mode; + qurt_perm_t perms ; +}qurt_mapping_attr_t; +/** @endcond */ +/** @} */ /* end_addtogroup mapping_attribute_types*/ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_mem_cache_clean + Performs a cache clean operation on the data stored in the specified memory area. + Peforms a syncht on all the data cache operations when the Hexagon processor version is V60 or greater. + + @note1hang Perform the flush all operation only on the data cache. + + @note1cont This operation flushes and invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed and invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_ALL\n + @note1 #QURT_MEM_CACHE_FLUSH_ALL is valid only when the type is #QURT_MEM_DCACHE @tablebulletend + @param[in] type Cache type. Values: + - #QURT_MEM_ICACHE + - #QURT_MEM_DCACHE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type.\n + + @dependencies + None. +*/ +int qurt_mem_cache_clean(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_clean2 + Performs a data cache clean operation on the data stored in the specified memory area. + + This API only performs the following data cache operations:\n + - #QURT_MEM_CACHE_FLUSH\n + - #QURT_MEM_CACHE_INVALIDATE\n + - #QURT_MEM_CACHE_FLUSH_INVALIDATE -- flushes/invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed/invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values:\n #QURT_MEM_CACHE_FLUSH\n #QURT_MEM_CACHE_INVALIDATE\n + #QURT_MEM_CACHE_FLUSH_INVALIDATE + @param[in] type Cache type. Values: \n #QURT_MEM_DCACHE + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type. + + @dependencies + None. +*/ +int qurt_mem_cache_clean2(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_phys_clean + Performs a cache clean operation on the data stored in the specified memory area based on address match and mask. + Operate on a cache line when (LINE.PhysicalPageNumber & mask) == addrmatch. + + @note1hang The addrmatch value should be the upper 24-bit physical address to match against. + + @datatypes + #qurt_mem_cache_op_t \n + + @param[in] mask 24-bit address mask. + @param[in] addrmatch Physical page number (24 bits) of memory to use as an address match. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid operation + + @dependencies + None. +*/ + +int qurt_mem_cache_phys_clean(unsigned int mask, unsigned int addrmatch, qurt_mem_cache_op_t opcode); + +/**@ingroup func_qurt_mem_l2cache_line_lock + Performs an L2 cache line locking operation. This function locks selective lines in the L2 cache memory. + + @note1hang Perform the line lock operation only on the 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to lock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of L2 cache memory to line lock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success.\n + #QURT_EALIGN -- Data alignment or address failure. + #QURT_EINVALID -- Improper addr and size passed (e.g. integer overflow due to addr + size) + #QURT_EFAILED -- Failed to lock cache line as all the ways were locked for the corresponding set of an address + in the range of addr and addr+size or the address range is not L2 cacheable + @dependencies + None. +*/ +int qurt_mem_l2cache_line_lock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_l2cache_line_unlock + Performs an L2 cache line unlocking operation. This function unlocks selective lines in the L2 cache memory. + + @note1hang Perform the line unlock operation only on a 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to unlock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of the L2 cache memory line to unlock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success. \n + #QURT_EALIGN -- Aligning data or address failure. \n + #QURT_EFAILED -- Operation failed, cannot find the matching tag. + + @dependencies + None. +*/ +int qurt_mem_l2cache_line_unlock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_region_attr_init + @xreflabel{sec:qurt_mem_region_attr_init} + Initializes the specified memory region attribute structure with default attribute values: \n + - Mapping -- #QURT_MEM_MAPPING_VIRTUAL \n + - Cache mode -- #QURT_MEM_CACHE_WRITEBACK \n + - Physical address -- -1 \n + - Virtual address -- -1 \n + - Memory type -- #QURT_MEM_REGION_LOCAL \n + - Size -- -1 + + @note1hang The memory physical address attribute must be explicitly set by calling the + qurt_mem_region_attr_set_physaddr() function. The size and pool attributes are set directly + as parameters in the memory region create operation. + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the destination structure for the memory region attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attach + Initializes a memory pool object to attach to a pool predefined in the system + configuration file. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. They are specified in memory region create operations + (Section @xref{sec:mem_region_create}). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool attach + operation is necessary only when allocating memory regions in nonstandard + memory units such as TCM. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach(char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_attach2 + Gets the identifier that corresponds to a pool object created specifically for a client, for example, HLOS_PHYSPOOL. + The client_handle is used to look up the client specific pool. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. Memory pool objects are specified during mapping creation operations + (qurt_mem_mmap() and qurt_mem_region_create()). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool_attach2 + operation is necessary only when allocating memory regions in memory units specific to the client. + + @datatypes + #qurt_mem_pool_t + + @param[in] client_handle Client identifier used by the OS to lookup the identifier + for client specific pool + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach2(int client_handle, char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_create + @xreflabel{hdr:qurt_mem_pool_create} + Dynamically creates a memory pool object from a physical address range. + + The pool is assigned a single memory region with the specified base address and size. + + The base address and size values passed to this function must be aligned to 4K byte + boundaries, and must be expressed as the actual base address and size values divided by 4K. + + For example, the function call: + @code + qurt_mem_pool_create ("TCM_PHYSPOOL", 0xd8020, 0x20, &pool) + @endcode + ... is equivalent to the following static pool definition in the QuRT system configuration file: + @code + + + + @endcode + + @cond rest_dist For more information on the system configuration file, see @xhyperref{80VB41979,80-VB419-79}. @endcond + + @note1hang Dynamically created pools are not identical to static pools. In particular, + qurt_mem_pool_attr_get() is not valid with dynamically created pools. + + @note1cont Dynamic pool creation permanently consumes system resources, and cannot be undone. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[in] base Base address of the memory region (divided by 4K). + @param[in] size Size (in bytes) of the memory region (divided by 4K). + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_mem_pool_create(char *name, unsigned base, unsigned size, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_add_pages + Adds a physical address range to the specified memory pool object.\n + + @note1hang Call this operation only with root privileges (guest OS mode). + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_mem_pool_add_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages); + +/**@ingroup func_qurt_mem_pool_remove_pages + Removes a physical address range from the specified memory pool object. + + If any part of the address range is in use, this operation returns an + error without changing the state. + + @note1hang Call this operation only with root privileges (guest-OS mode). + + @note1cont In the future, this operation will support (via the flags parameter) the + removal of a physical address range when part of the range is in use. + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + @param[in] flags Remove options. Values: \n + - 0 -- Skip holes in the range that are not part of the pool (default) \n + - #QURT_POOL_REMOVE_ALL_OR_NONE -- Pages are removed only if the specified + physical address range is entirely contained (with no holes) in the + pool free space. @tablebulletend + @param[in] callback Callback procedure called when pages were successfully removed. + Not called if the operation failed. Passing 0 as the parameter + value causes the callback to not be called. + @param[in] arg Value passed as an argument to the callback procedure. + + @return + #QURT_EOK -- Pages successfully removed. + + @dependencies + None. +*/ +int qurt_mem_pool_remove_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages, + unsigned flags, + void (*callback)(void *), + void *arg); +/**@ingroup memory_management_types*/ +#define QURT_POOL_REMOVE_ALL_OR_NONE 1 /**< */ + +/**@ingroup func_qurt_mem_pool_attr_get + Gets the memory pool attributes. \n + Retrieves pool configurations based on the pool handle, and fills in + the attribute structure with configuration values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_attr_t + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[out] attr Pointer to the memory region attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_attr_get (qurt_mem_pool_t pool, qurt_mem_pool_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attr_get_size + Gets the size of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] size Pointer to the destination variable for the range size. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_size (qurt_mem_pool_attr_t *attr, int range_id, qurt_size_t *size){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*size) = 0; + return QURT_EINVALID; + } + else { + (*size) = attr->ranges[range_id].size; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr + Gets the start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_t *addr){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; + } + else { + (*addr) = (attr->ranges[range_id].start)<<12; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr_64 + Gets the 64 bit start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_64_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr_64 (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_64_t *addr){ +if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; +} +else { + (*addr) = ((qurt_addr_64_t)attr->ranges[range_id].start)<<12; + } + return QURT_EOK; + } + + +/**@ingroup func_qurt_mem_pool_status_get + Gets the memory pool status. \n + Based on the pool handle, retrieves largest contiguous free memory, + total free memory, and total memory declared for the pool in bytes. Fills in + the memory status structure with the values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_status_t + + @param[in] pool Pool handle. + @param[out] status Pointer to the memory pool status structure. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_status_get (qurt_mem_pool_t pool, qurt_mem_pool_status_t *status); + + +/**@ingroup func_qurt_mem_pool_is_available + Checks whether the number of pages that the page_count argument indicates + can be allocated from the specified pool. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_mem_mapping_t \n + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[in] page_count Number of 4K pages. + @param[in] mapping_type Variable of type qurt_mem_mapping_t. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Mapping_type is invalid. \n + #QURT_EMEM -- Specified pages cannot be allocated from the pool. + + @dependencies + None. +*/ +int qurt_mem_pool_is_available(qurt_mem_pool_t pool, int page_count, qurt_mem_mapping_t mapping_type); + + +/**@ingroup func_qurt_mem_region_create + @xreflabel{sec:mem_region_create} + Creates a memory region with the specified attributes. + + The application initializes the memory region attribute structure with + qurt_mem_region_attr_init() and qurt_mem_region_attr_set_bus_attr(). + + If the virtual address attribute is set to its default value + (Section @xref{sec:qurt_mem_region_attr_init}), the virtual address of the memory region is + automatically assigned any available virtual address value. + + If the memory mapping attribute is set to virtual mapping, the physical address of the memory region + is also automatically assigned.\n + + @note1hang The physical address attribute is explicitly set in the attribute structure only + for memory regions with physical-contiguous-mapped mapping. + + Memory regions are always assigned to memory pools. The pool value specifies the memory pool + that the memory region is assigned to. + + @note1hang If attr is specified as NULL, the memory region is created with default + attribute values (Section @xref{sec:qurt_mem_region_attr_init}). + QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}), which allocates memory regions in SMI memory. + + @datatypes + #qurt_mem_region_t \n + #qurt_size_t \n + #qurt_mem_pool_t \n + #qurt_mem_region_attr_t + + @param[out] region Pointer to the memory region object. + @param[in] size Memory region size (in bytes). If size is not an integral multiple of 4K, + it is rounded up to a 4K boundary. + @param[in] pool Memory pool of the region. + @param[in] attr Pointer to the memory region attribute structure. + + @return + #QURT_EOK -- Memory region successfully created.\n + #QURT_EMEM -- Not enough memory to create region. + #QURT_EINVALID -- Invalid cache attributes / permissions provided in attribute. + + @dependencies + None. +*/ +int qurt_mem_region_create(qurt_mem_region_t *region, qurt_size_t size, qurt_mem_pool_t pool, qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_region_delete + Deletes the specified memory region. + + If the caller application creates the memory region, it is removed and the system reclaims its + assigned memory. + + If a different application creates the memory region (and is shared with the caller + application), only the local memory mapping to the region is removed; the system does + not reclaim the memory. + + @datatypes + #qurt_mem_region_t + + @param[in] region Memory region object. + + @returns + #QURT_EOK -- Region successfully deleted. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. +*/ +int qurt_mem_region_delete(qurt_mem_region_t region); + + +/**@ingroup func_qurt_mem_region_attr_get + @xreflabel{sec:mem_region_attr_get} + Gets the memory attributes of the specified message region. + After a memory region is created, its attributes cannot be changed. + + @datatypes + #qurt_mem_region_t \n + #qurt_mem_region_attr_t + + @param[in] region Memory region object. + @param[out] attr Pointer to the destination structure for memory region attributes. + + @return + #QURT_EOK -- Operation successfully performed. \n + Error code -- Failure. + + @dependencies + None. +*/ +int qurt_mem_region_attr_get(qurt_mem_region_t region, qurt_mem_region_attr_t *attr); + + +/**@ingroup func_qurt_mem_region_attr_set_type + Sets the memory type in the specified memory region attribute structure. + + The type indicates whether the memory region is local to an application or shared between + applications. + @cond rest_dist For more information, see @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in,out] attr Pointer to memory region attribute structure. + @param[in] type Memory type. Values: \n + - #QURT_MEM_REGION_LOCAL \n + - #QURT_MEM_REGION_SHARED @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t type){ + attr->type = type; +} + +/**@ingroup func_qurt_mem_region_attr_get_size + Gets the memory region size from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] size Pointer to the destination variable for memory region size. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_size(qurt_mem_region_attr_t *attr, qurt_size_t *size){ + (*size) = attr->size; +} + +/**@ingroup func_qurt_mem_region_attr_get_type + Gets the memory type from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] type Pointer to the destination variable for the memory type. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t *type){ + (*type) = attr->type; +} + +/**@ingroup func_qurt_mem_region_attr_set_physaddr + Sets the memory region 32-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise QuRT automatically sets it + when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr(qurt_mem_region_attr_t *attr, qurt_paddr_t addr){ + attr->ppn = (unsigned)(((unsigned)(addr))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr + Gets the memory region physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for memory region physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned)(((unsigned) (attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_region_attr_set_virtaddr + Sets the memory region virtual address in the specified memory attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_addr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_virtaddr(qurt_mem_region_attr_t *attr, qurt_addr_t addr){ + attr->virtaddr = addr; +} + +/**@ingroup func_qurt_mem_region_attr_get_virtaddr + Gets the memory region virtual address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for the memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_virtaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned int)(attr->virtaddr); +} + +/**@ingroup func_qurt_mem_region_attr_set_mapping + Sets the memory mapping in the specified memory region attribute structure. + + The mapping value indicates how the memory region is mapped in virtual memory. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mapping Mapping. Values: + - #QURT_MEM_MAPPING_VIRTUAL + - #QURT_MEM_MAPPING_PHYS_CONTIGUOUS + - #QURT_MEM_MAPPING_IDEMPOTENT + - #QURT_MEM_MAPPING_VIRTUAL_FIXED + - #QURT_MEM_MAPPING_NONE + - #QURT_MEM_MAPPING_VIRTUAL_RANDOM + - #QURT_MEM_MAPPING_INVALID @tablebulletend + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t mapping){ + attr->mapping_type = mapping; +} + +/**@ingroup func_qurt_mem_region_attr_get_mapping + Gets the memory mapping from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mapping Pointer to the destination variable for memory mapping. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t *mapping){ + (*mapping) = attr->mapping_type; +} + +/**@ingroup func_qurt_mem_region_attr_set_cache_mode + Sets the cache operation mode in the specified memory region attribute structure. + + @cond rest_dist For more information on the cache, see @xhyperref{80VB41992,80-VB419-92}.@endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mode Cache mode. Values: \n + - #QURT_MEM_CACHE_WRITEBACK \n + - #QURT_MEM_CACHE_WRITETHROUGH\n + - #QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE\n + - #QURT_MEM_CACHE_NONE @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t mode){ + QURT_PGATTR_C_SET(attr->pga, (unsigned)mode); +} + +/**@ingroup func_qurt_mem_region_attr_get_cache_mode + Gets the cache operation mode from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t *mode){ + unsigned int mode_temp = QURT_PGATTR_C_GET(attr->pga); + (*mode) = (qurt_mem_cache_mode_t)mode_temp; +} + +/**@ingroup func_qurt_mem_region_attr_set_bus_attr + Sets the (A1, A0) bus attribute bits in the specified memory region attribute structure. + + @cond rest_dist For more information on the bus attribute bits, see the @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] abits The (A1, A0) bits to use with the memory region, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_bus_attr(qurt_mem_region_attr_t *attr, unsigned abits){ + QURT_PGATTR_A_SET(attr->pga, abits); +} + +/**@ingroup func_qurt_mem_region_attr_get_bus_attr + Gets the (A1, A0) bus attribute bits from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] pbits Pointer to an unsigned integer that is filled in with + the (A1, A0) bits from the memory region attribute structure, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_bus_attr(qurt_mem_region_attr_t *attr, unsigned *pbits){ + (*pbits) = QURT_PGATTR_A_GET(attr->pga); +} + +void qurt_mem_region_attr_set_owner(qurt_mem_region_attr_t *attr, int handle); +void qurt_mem_region_attr_get_owner(qurt_mem_region_attr_t *attr, int *p_handle); +void qurt_mem_region_attr_set_perms(qurt_mem_region_attr_t *attr, unsigned perms); +void qurt_mem_region_attr_get_perms(qurt_mem_region_attr_t *attr, unsigned *p_perms); + +/**@ingroup func_qurt_mem_map_static_query + Determines whether a memory page is statically mapped. + Pages are specified by the following attributes: physical address, page size, cache mode, + and memory permissions. \n + - If the specified page is statically mapped, vaddr returns the virtual + address of the page. \n + - If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + The system configuration file defines QuRT memory maps. + + @datatypes + #qurt_addr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr Physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped, vaddr returns the virtual address. \n + #QURT_EMEM -- Specified page is not statically mapped, vaddr returns -1. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query(qurt_addr_t *vaddr, qurt_addr_t paddr, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + + +/**@ingroup func_qurt_mem_region_query + Queries a memory region. \n + This function determines whether a dynamically-created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. + When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns #QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_paddr_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr Physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Query successfully performed. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_t paddr); + + +/**@ingroup func_qurt_mapping_create + @xreflabel{hdr:qurt_mapping_create} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Mapping created. \n + #QURT_EMEM -- Failed to create mapping. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove + @xreflabel{hdr:qurt_mapping_remove} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Mapping created. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr + Translates a virtual memory address to the physical memory address to which it maps. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the + physical address of another process. + + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- Physical address to which the virtual address is mapped.\n + 0 -- Virtual address not mapped. + + @dependencies + None. +*/ +qurt_paddr_t qurt_lookup_physaddr (qurt_addr_t vaddr); + +/**@ingroup func_qurt_mem_region_attr_set_physaddr_64 + Sets the memory region 64-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise it is automatically set by + QuRT when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr_64 Memory region 64-bit physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t addr_64){ + attr->ppn = (unsigned)(((unsigned long long)(addr_64))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr_64 + Gets the memory region 64-bit physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr_64 Pointer to the destination variable for the memory region 64-bit physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t *addr_64){ + (*addr_64) = (unsigned long long)(((unsigned long long)(attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_map_static_query_64 + Determines if a memory page is statically mapped. + The following attributes specify pages: 64-bit physical address, page size, cache mode, + and memory permissions. \n + If the specified page is statically mapped, vaddr returns the virtual + address of the page. + If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + QuRT memory maps are defined in the system configuration file. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr_64 64-bit physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped; a virtual address is returned in vaddr. \n + #QURT_EMEM -- Specified page is not statically mapped; -1 is returned in vaddr. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query_64(qurt_addr_t *vaddr, qurt_paddr_64_t paddr_64, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mem_region_query_64 + Determines whether a dynamically created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr_64 64-bit physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query_64(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64); + +/**@ingroup func_qurt_mapping_create_64 + @xreflabel{hdr:qurt_mapping_create_64} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Failure. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove_64 + @xreflabel{hdr:qurt_mapping_remove_64} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Success. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr_64 + Translates a virtual memory address to the 64-bit physical memory address it is mapped to. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the physical + address of another process. + + @datatypes + #qurt_paddr_64_t \n + #qurt_addr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address has not been mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr_64 (qurt_addr_t vaddr); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_mapping_reclaim + Deallocates all QuRT resources associated with the specified virtual + memory area, making it available for user memory management:\n + - The associated physical memory areas are freed and added to the + specified physical pool.\n + - The associated TLB entries are deleted and made available for TLB + management.\n + - The virtual memory area is not freed -- it is left in + place as allocated, but unmapped virtual memory. Access to this + memory area generates an exception.\n + + The virtual memory area must be statically allocated. + If no pool is specified, the freed physical memory is not added to any pool. + + @note1hang The virtual memory area is restricted to being filled with locked + TLB entries that are contiguous within the memory area, and contained by it. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_pool_t + + @param[in] vaddr Virtual address of the memory area to free. + @param[in] vsize Size (in bytes) of the memory area to free. + @param[in] pool Handle to the physical pool where freed physical memory is added. + If set to 0, freed physical memory is not added to any pool. + + @return + 0 -- Success. \n + Nonzero -- Failure that indicates a partial success, or that the request was malformed. \n @note1hang The expected behavior is that + QuRT logs messages related to the failure, and callers are free to ignore the return value. + + @dependencies + None. +*/ +int qurt_mapping_reclaim(qurt_addr_t vaddr, qurt_size_t vsize, qurt_mem_pool_t pool); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_mem_configure_cache_partition + Configures the Hexagon cache partition at the system level. + + A partition size value of #SEVEN_EIGHTHS_SIZE is applicable only to the L2 cache. + + The L1 cache partition is not supported in Hexagon processor version V60 or greater. + + @note1hang Call this operation only with QuRT OS privilege. + + @datatypes + #qurt_cache_type_t \n + #qurt_cache_partition_size_t + + @param[in] cache_type Cache type for partition configuration. Values: \n + - #HEXAGON_L1_I_CACHE \n + - #HEXAGON_L1_D_CACHE \n + - #HEXAGON_L2_CACHE @tablebulletend + + @param[in] partition_size Cache partition size. Values: \n + - #FULL_SIZE \n + - #HALF_SIZE \n + - #THREE_QUARTER_SIZE \n + - #SEVEN_EIGHTHS_SIZE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Error. + + @dependencies + None. + */ +int qurt_mem_configure_cache_partition(qurt_cache_type_t cache_type, qurt_cache_partition_size_t partition_size); + + +/**@ingroup func_qurt_mem_syncht + @xreflabel{hdr:qurt_mem_syncht} + Performs heavy-weight synchronization of memory transactions. + + This operation does not return until all previous memory transactions (cached and uncached load/store, + mem_locked, and so on) that originated from the current thread are complete and globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon syncht instruction. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_syncht(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" SYNCHT \n"); + #endif +} + +/**@ingroup func_qurt_mem_barrier + @xreflabel{hdr:qurt_mem_barrier} + Creates a barrier for memory transactions. + + This operation ensures that all previous memory transactions are globally observable before any + future memory transactions are globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon barrier instruction. + @return + None + + @dependencies + None. + */ +static inline void qurt_mem_barrier(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" BARRIER \n"); + #endif +} +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_system_mem_alloc + Requests that the kernel allocates memory from the kernel-owned pool. + + @param[in] size Size in bytes (aligned to 4K) to allocate. + @param[in] align Any alignment that must be considered for the allocation. + @param[in] flags Supports the #QURT_SYSTEM_ALLOC_VIRTUAL flag; allocates + available virtual memory in the address space of all processes. + + @return + #QURT_EFATAL -- Allocation failed \n + Start address of the successful allocation. + + @dependencies + None. +*/ +unsigned qurt_system_mem_alloc(unsigned size, unsigned align, unsigned flags); +/** @endcond */ +/** @cond rest_reg_dist*/ +/**@ingroup func_qurt_lookup_physaddr2 + Translates the virtual memory address of the specified process to the 64-bit + physical memory address to which it is mapped. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[in] vaddr Virtual address. + @param[in] pid PID. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address is not mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr2(qurt_addr_t vaddr, unsigned int pid); +/** @endcond */ + +/**@ingroup func_qurt_mapping_attr_get + Gets the mapping attributes for a given virtual address and PID + + @datatypes + #qurt_addr_t \n + #qurt_mapping_attr_t + + @param[in] vaddr virtual address for which the attributes are required. + @param[in] pid process id for the target process + @param[out] attr Pointer to the mapping attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Incorrect virtual address or pid +*/ +int qurt_mapping_attr_get(qurt_addr_t vaddr, unsigned int pid, qurt_mapping_attr_t *attr); + + +/**@ingroup func_qurt_mapping_attr_get_cache_mode + Gets the cache operation mode in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] cache_mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_cache_mode(qurt_mapping_attr_t *attr, qurt_mem_cache_mode_t *cache_mode) +{ + (*cache_mode) = attr->cache_mode; +} + +/**@ingroup func_qurt_mapping_attr_get_physaddr + Gets the physical memory address in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] physaddr Pointer to the destination variable for physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_physaddr(qurt_mapping_attr_t *attr, qurt_paddr_64_t *physaddr) +{ + (*physaddr) = attr->paddr; +} + +/**@ingroup func_qurt_mapping_attr_get_perms + Gets the permissions in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_perm_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] perms Pointer to the destination variable for permissions. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_perms(qurt_mapping_attr_t *attr, qurt_perm_t *perms) +{ + (*perms) = attr->perms; +} + +/**@ingroup func_qurt_mapping_attr_get_size + Gets the size in the specified memory mapping attribute structure.This represents size of the + TLB entry which covers the virtual address. + + + @datatypes + #qurt_mapping_attr_t \n + #unsigned int + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] size Pointer to the destination variable for size. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_mapping_attr_get_size(qurt_mapping_attr_t *attr, unsigned int *size) +{ + (*size) = attr->size; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MEMORY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mmap.h new file mode 100755 index 0000000000000..c3bd875910af7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mmap.h @@ -0,0 +1,359 @@ +#ifndef QURT_MMAP_H +#define QURT_MMAP_H +/** + @file qurt_mmap.h + @brief Prototypes of memory mapping/unmapping APIs. + The APIs allow the user to map, un-map, and change permissions + on memory regions. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2022, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_mem_mmap + Creates a memory mapping with the specified attributes. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that specifies a pool handle + if the user wants to allocate memory from a specific pool. + The default value for this argument is NULL. + @param[in] pRegion Map region. This argument is unused, and the default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + @param[in] flags Mapping modes.\n + - #QURT_MAP_NAMED_MEMSECTION + - #QURT_MAP_FIXED \n + - #QURT_MAP_NONPROCESS_VPOOL \n + - #QURT_MAP_TRYFIXED \n + - #QURT_MAP_ANON \n + - #QURT_MAP_PHYSADDR \n + - #QURT_MAP_VA_ONLY @tablebulletend + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap2 + Creates a memory mapping with the specified attributes. Returns a more descriptive + error code in case of failure. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that allows the user to specify a pool handle + when the user wants to allocate memory from a specific pool. + Default value for this argument is NULL. + @param[in] pRegion Map region (unused argument); default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode. + @param[in] flags Mapping modes; + Shared, Private, or Anonymous. + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_EMEM -- Physical address is not available. \n + #QURT_EFAILED -- VA is not available or mapping failed.\n + #QURT_EINVALID -- Invalid argument was passed (for example, an unaligned VA/PA). + */ +void *qurt_mem_mmap2(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap_by_name + Creates a memory mapping for a named-memsection using the specified attributes. + The named memsection should be specified in cust_config.xml. + + @note1hang If the specified attributes are not valid or the named memsection is not found, + an error result is returned. + + @param[in] name Name of the memsection in cust_config.xml that specifies + this mapping. Should be less than 25 characters. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode + @param[in] flags Mapping modes, such as + Shared, Private, or Anonymous. + @param[in] offset Offset relative to the physical address range specified in memsection. + If offset + length exceeds size of memsection, failure is + returned. + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap_by_name(const char* name, + void *addr, + size_t length, + int prot, + int flags, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mprotect2 + Changes access permissions and attributes on an existing mapping based on the client_handle argument. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned. + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping.\n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect2(int client_handle, const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_mprotect + Changes access permissions and attributes on an existing mapping. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned.\n + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect(const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_munmap + Removes an existing mapping. + + @note1hang If the specified mapping is not found in the context of the caller process + or invalid attributes are passed, an error code is returned. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap(void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap2 + Removes an existing mapping for a specified process. + + @note1hang This API allows a root process entity, such as a driver, to remove mapping + that was created for a user process. If the specified mapping is not found in the context + of client handle or invalid attributes are passed, an error code is returned. + + @param[out] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap2(int client_handle, + void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap3 + Removes an existing mapping or reservation for a specified process. + + @param[in] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Pointer to a virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] flags Specifies the flag. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap3(int client_handle, + void *addr, + size_t length, + int flags); + +/* +|| The macros here follow the style of the standard mmap() macros, but with +|| QURT_ prepended to avoid name conflicts, and to avoid having a dependency +|| on sys/mman.h. +|| +|| Wherever possible, any values here that are also present in sys/mman.h +|| should have the same value in both places so that we can accept "mmap" +|| calls without having to remap parameters to new values. +|| +|| In the future, it would be desirable to have a regression test that +|| checks, for instance, that these macros match. Example: +|| +|| assert(QURT_MAP_FAILED == MAP_FAILED); +|| ... repeat as needed ... +*/ + +/** @addtogroup memory_mapping_macros +@{ */ +/** @cond */ +#define QURT_PROT_NONE 0x00U /**< */ +#define QURT_PROT_READ 0x01U /**< */ +#define QURT_PROT_WRITE 0x02U /**< */ +#define QURT_PROT_EXEC 0x04U /**< */ +#define QURT_PROT_NODUMP 0x08U /**< Skip dumping the mapping. During PD dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and the DSP process + crashes before the mapping is removed.*/ +#define QURT_PROT_ISLAND 0x10U /**< Island mapping. */ + +#define QURT_MAP_SHARED 0x0001U /**< Shared. */ +#define QURT_MAP_PRIVATE 0x0002U /**< Private. */ +/** @endcond */ +#define QURT_MAP_NAMED_MEMSECTION 0x0004U /**< Named memsection. */ +#define QURT_MAP_FIXED 0x0010U /**< Fixed virtual address. */ +#define QURT_MAP_RENAME 0x0020U /**< Rename. */ +#define QURT_MAP_NORESERVE 0x0040U /**< No reserve. */ +#define QURT_MAP_INHERIT 0x0080U /**< Inherit. */ +#define QURT_MAP_NONPROCESS_VPOOL 0x0100U /**< Use a virtual address outside of the default range of the + processes. This option is only supported in the root process + and only when virtual memory split is enabled in the XML. + The root process can use this flag to create mapping for a + user process, for example, if the virtual address is configured + for a 3G/1G split, the root process can use this flag to create + mapping in the top 1 GB area for the user process or the + lower 3 GB area for the root process. This is useful for + shared buffer use cases. */ +#define QURT_MAP_HASSEMAPHORE 0x0200U /**< Has semaphore. */ +#define QURT_MAP_TRYFIXED 0x0400U /**< Try to create a mapping for a virtual address that was passed. + If the passed virtual address fails, use a random virtual address. */ +#define QURT_MAP_WIRED 0x0800U /**< Wired. */ +#define QURT_MAP_FILE 0x0000U /**< File. */ +#define QURT_MAP_ANON 0x1000U /**< Allocate physical memory from the pool that was passed. + By default, memory is allocated from the default physpool. */ +#define QURT_MAP_VA_ONLY 0X2000U /**< Reserve a virtual address without + mapping it. */ + +/** @cond */ +#define QURT_MAP_ALIGNED(n) ((n) << QURT_MAP_ALIGNMENT_SHIFT) +#define QURT_MAP_ALIGNMENT_SHIFT 24 + + +#define QURT_MAP_ALIGNMENT_MASK QURT_MAP_ALIGNED(0xff) /**< */ +#define QURT_MAP_ALIGNMENT_64KB QURT_MAP_ALIGNED(16) /**< */ +#define QURT_MAP_ALIGNMENT_16MB QURT_MAP_ALIGNED(24) /**< */ +#define QURT_MAP_ALIGNMENT_4GB QURT_MAP_ALIGNED(32) /**< */ +#define QURT_MAP_ALIGNMENT_1TB QURT_MAP_ALIGNED(40) /**< */ +#define QURT_MAP_ALIGNMENT_256TB QURT_MAP_ALIGNED(48) /**< */ +#define QURT_MAP_ALIGNMENT_64PB QURT_MAP_ALIGNED(56) /**< */ +/** @endcond */ +#define QURT_MAP_FAILED ((void *) -1) /**< Mapping creation failed. */ + +/* +|| The macros below are extensions beyond the standard mmap flags, but follow +|| the style of the mmap flags. +*/ +/** @cond */ +// Describe bitfields in (prot) +#define QURT_PROT_CACHE_BOUNDS 16U,19U,7U /**< Bits 16 through 19 are cache attribute, default is 0. */ +#define QURT_PROT_BUS_BOUNDS 20U,21U,0U /**< Bits 20 through 21 are bus attributes, default is 0. */ +#define QURT_PROT_USER_BOUNDS 22U,23U,3U /**< Bits 22 through 23 are user mode, default is 3; + default of 3 means to derive user mode setting from the + default mode of the client. */ + +// Describe bitfields in (flags) +#define QURT_MAP_PHYSADDR_BOUNDS 15U,15U,0U /**< Bits 15 through 15 are physaddr, default is 0. */ +#define QURT_MAP_TYPE_BOUNDS 16U,19U,0U /**< Bits 16 through 19 are mapping type, default is 0. */ +#define QURT_MAP_REGION_BOUNDS 20U,23U,0U /**< Bits 20 through 23 are region type, default is 0. */ +/** @endcond */ + +// These macros get OR'ed into (prot) +#define QURT_PROT_CACHE_MODE(n) QURT_MMAP_BUILD(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_BUS_ATTR(n) QURT_MMAP_BUILD(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_USER_MODE(n) QURT_MMAP_BUILD(QURT_PROT_USER_BOUNDS,(n)) /**< */ +// These macros get OR'ed into (flags) + +#define QURT_MAP_PHYSADDR QURT_MMAP_BUILD(QURT_MAP_PHYSADDR_BOUNDS,1U) /**< Use the physical address that was passed in offset field. + This is allowed only for root process. */ +#define QURT_MAP_TYPE(n) QURT_MMAP_BUILD(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_REGION(n) QURT_MMAP_BUILD(QURT_MAP_REGION_BOUNDS,(n)) /**< */ +/** @} */ /* end_addtogroup memory_mapping_macros */ +/** @cond */ +// These macros extract fields from (prot) +#define QURT_PROT_GET_CACHE_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_BUS_ATTR(n) QURT_MMAP_EXTRACT(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_USER_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_USER_BOUNDS,(n)) /**< */ + +// These macros extract fields from (flags) +#define QURT_MAP_GET_TYPE(n) QURT_MMAP_EXTRACT(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_GET_REGION(n) QURT_MMAP_EXTRACT(QURT_MAP_REGION_BOUNDS,(n)) /**< */ + +// Macros for bitfield insertion and extraction +#define QURT_MMAP_MASK(lo,hi) (~((~0u) << ((hi)-(lo)+1U))) /**< Mask of same size as [lo..hi]. */ +#define QURT_MMAP_BUILD_(lo,hi,def,n) ((((n)^(def))&QURT_MMAP_MASK((lo),(hi)))<<(lo)) /**< */ +#define QURT_MMAP_EXTRACT_(lo,hi,def,n) ((((n)>>(lo))&QURT_MMAP_MASK((lo),(hi)))^(def)) /**< */ +#define QURT_MMAP_BUILD(a,b) QURT_MMAP_BUILD_(a,b) /**< */ +#define QURT_MMAP_EXTRACT(a,b) QURT_MMAP_EXTRACT_(a,b) /**< */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mq.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mq.h new file mode 100755 index 0000000000000..580c83d3de41a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mq.h @@ -0,0 +1,458 @@ +#ifndef QURT_MQ_H +#define QURT_MQ_H +/** + @file qurt_mq.h + + @brief Prototypes of secure message queues API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2019-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +======================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_MQ_NAME_MAXLEN 16U /**< Maximum name length. */ + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/* This enum must be generated in accordance to process class class numbers. + For now it is made to match generated version, do not change this unless + there is a corresponding change in the process_class.py, indicies start from 0 + basically: QURT_MQ_SECURITY_SCOPE_ = (1 << QURTK_process_class_index_) +*/ +typedef enum { + QURT_MQ_SECURITY_SCOPE_KERNEL = ( 1U << 0 ), + QURT_MQ_SECURITY_SCOPE_SRM = ( 1U << 1 ), + QURT_MQ_SECURITY_SCOPE_SECURE = ( 1U << 2 ), + QURT_MQ_SECURITY_SCOPE_CPZ = ( 1U << 3 ), + QURT_MQ_SECURITY_SCOPE_ROOT = ( 1U << 4 ), + QURT_MQ_SECURITY_SCOPE_SIGNED = ( 1U << 5 ), + QURT_MQ_SECURITY_SCOPE_UNSIGNED = ( 1U << 6 ), + QURT_MQ_SECURITY_SCOPE_SECURE_ROOT = ( 1U << 7 ) +} qurt_mq_security_scope_t; + +typedef enum { + QURT_MQ_CARDINALITY_PTP = (1U << 0), + QURT_MQ_CARDINALITY_MTO = (1U << 1) +}qurt_mq_cardinality_t; + +typedef unsigned int qurt_mqd_t; + +typedef union{ + struct { + unsigned int perms:2; + unsigned int cardinality:1; + unsigned int blocking:1; + + qurt_mq_security_scope_t creator_scope: 8; + qurt_mq_security_scope_t allowed_scope: 8; //can be a bitmask in case of MTO + unsigned int queue_closed: 1; + unsigned int reserved: 11; + }; //try to do anonymous struct + unsigned int raw; +} qurt_mq_flags_t; + + +/* permissions are from qurt_types.h , block X though */ +#if 0 +/** Memory access permission. */ +typedef enum { + QURT_PERM_READ=0x1U, /**< */ + QURT_PERM_WRITE=0x2U, /**< */ + QURT_PERM_EXECUTE=0x4U, /**< */ + QURT_PERM_FULL=QURT_PERM_READ|QURT_PERM_WRITE|QURT_PERM_EXECUTE, /**< */ +} qurt_perm_t; +#endif + +struct qurt_mq_attr { + unsigned flags; /**< Configured flags. Only meaningful with get_attr(), only used for qurt_mq_flags_t.perms. */ + unsigned mq_maxmsg; /**< Maximum number of messages. Used with create() and get_attr. */ + unsigned short mq_send_msgsize; /**< Maximum size (bytes) of message in receiver facing queue, + from sender to receiver. */ + unsigned short mq_recv_msgsize; /**< Maximum size (bytes) of message in sender facing queue, + from receiver to sender. */ + unsigned client_pid; /**< Process ID of client that is allowed to open the message queue + that was created using qurt_mq_create(). */ + qurt_mq_cardinality_t cardinality; /**< Cardinality of message queue connection, see below. */ + qurt_mq_security_scope_t scope; /**< Security scope of the senders to the queue. */ +}; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mq_attr_init + Initializes attributes to default values used for creating the queue. + + The initialize operation sets the following default attribute values: \n + - flag - QURT_PERM_READ | QURT_PERM_WRITE \n + - maxmsg - 1 \n + - mq_send_msgsize - 8 \n + - mq_recv_msgsize - 8 \n + - sender_pid - -1 \n + - cardinality - QURT_MQ_CARDINALITY_PTP \n + - scope - QURT_MQ_SECURITY_SCOPE_SIGNED \n + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the initialized message queue object. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_init(struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_attr_set_send_msgsize + Sets the message size in bytes the sender can send. + Maximum message length is configurable using the XML configuration, however, limited to a maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_send_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_recv_msgsize + Sets the message size in bytes that the receiver can read. + Maximum message length is configurable using the XML configuration, however, limited to maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_recv_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_maxmsg + Sets the maximum message that can queue in the message queue. + Message depth is configurable using the XML configuration. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] depth Maximum message that can be queued. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_maxmsg (struct qurt_mq_attr *attr, unsigned int depth); + +/**@ingroup qurt_mq_attr_set_scope + Sets the scope of the message queue. A message queue created with a security + scope allows only a process class of that scope to open a message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mq_security_scope_t + + @param[in,out] attr Pointer to the message queue object. + @param[in] scope Scope of the message queue: \n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_scope (struct qurt_mq_attr *attr, qurt_mq_security_scope_t scope); + + +/**@ingroup qurt_mq_attr_set_client_pid + Sets the client_pid that can open this message queue. + If client_pid is set, allowed_scope to open MQ shall not be considered. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] client_pid Valid PID for client process. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_client_pid (struct qurt_mq_attr *attr, unsigned client_pid); + +/**@ingroup qurt_mq_attr_set_flags + Sets the properties of the message queues. + The current implementation is only used to set the permission for the message queue using the flag attribute. + Default is #QURT_PERM_READ | #QURT_PERM_WRITE, explicit permission is not implemented. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] flags Permission for message queue. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_flags (struct qurt_mq_attr *attr, unsigned int flags); + +/**@ingroup qurt_mq_create + Create a message queue with the provided name and attributes. + The calling process becomes the owner of the queue. + Name of the message queue is limited to 16 characters including the NULL terminator. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue identifier if + the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] attr Pointer to the initialized message queue attribute + structure that specifies the attributes of the created message queue. + + @return + #QURT_EOK Message queue created. \n + #QURT_EINVALID Invalid arguments. \n + #QURT_ENOSPC Maximum number of queues in the system is exceeded. + + @dependencies + None. +*/ +int qurt_mq_create(qurt_mqd_t *mqd, const char *name, struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_open + Opens a message queue connection between a process and a created message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue + identifier if the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] flags Flag that contains the properties that define the behavior of message queue connection. + Permissions:\n + #QURT_PERM_READ \n + #QURT_PERM_WRITE \n + #QURT_PERM_READ | QURT_PERM_WRITE @tablebulletend + Default is QURT_PERM_READ | QURT_PERM_WRITE, explicit permission is not implemented \n + Cardinality: \n + #QURT_MQ_CARDINALITY_PTP (default) \n + #QURT_MQ_CARDINALITY_MTO (not implemented) \n + Block suspend thread until the message queue with the apecified name is created. \n + Scope: security boundary to which the message queue and its users are constrained. + Block suspend thread until the message queue with the apecified name is created. \n + It is coupled with process privilege level/scope.\n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED @tablebulletend + + @return + QURT_EOK -- Message queue connection successfully opened \n + QURT_EFAILED -- Message queue connection failed , if non-blocking message queue \n + QURT_ENOTALLOWED -- Open failed due to security scope mismatch + + @dependencies + None. +*/ +int qurt_mq_open (qurt_mqd_t *mqd, const char *name, qurt_mq_flags_t flags); + +/**@ingroup qurt_mq_send + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send shall resume that thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] msg_len Length of the message buffer in bytes. + + @return + #QURT_EOK Message queue send was successful.\n + #QURT_EMSGSIZE Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED Send failed due to security scope mismatch. + + @dependencies + None. +*/ +int qurt_mq_send(qurt_mqd_t mqd, const char *msg_ptr, size_t msg_len); + +/**@ingroup qurt_mq_send_timed + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message or until timeout is reached. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_send_timed shall return #QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] duration Interval (in microseconds) that the duration value must be + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in] msg_len Length of message buffer in bytes. + + @return + #QURT_EOK -- Message queue send was successful. \n + #QURT_EMSGSIZE -- Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED -- Send failed due to security scope mismatch \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. +*/ +int qurt_mq_send_timed(qurt_mqd_t mqd, const char *msg_ptr, unsigned long long int duration, size_t msg_len); + + /**@ingroup qurt_mq_recv + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue. \n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv shall resume the thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in,out] msg_len Pointer to the length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID Message pointer or msg_len ptr are NULL. \n + #QURT_EBADR Message queue descriptior (mqd) is invalid. \n + #QURT_EBADF Sender closed the message queue. + + @dependencies + None. +*/ +int qurt_mq_recv(qurt_mqd_t mqd, unsigned char *msg_ptr, size_t *msg_len); + + /**@ingroup qurt_mq_recv_timed + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue or until timeout is reached.\n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_recv_timed shall return QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in] duration Interval (in microseconds) that the duration value must be; + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in,out] msg_len Pointer to length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID -- Message ptr or msg_len ptr are NULL. \n + #QURT_EBADR -- Message queue descriptior (mqd) is invalid.\n + #QURT_EBADF -- Sender closed the message queue. \n + #QURT_ETIMEDOUT -- Timeout. + + @dependencies + None. +*/ +int qurt_mq_recv_timed(qurt_mqd_t mqd, unsigned char *msg_ptr, unsigned long long int duration, size_t *msg_len); + + /**@ingroup qurt_mq_close + Closes the message queue and disassociates the calling process (client) from the message queue + under this descriptor. Marks the queue as closed for the receiver. + This function is expected to be called from the client side. If called + from the server side, the function reduces to no-op and returns success. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue close was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_close(qurt_mqd_t mqd); + + /**@ingroup qurt_mq_destroy + Destroys the message queue. This function ought to be + called from the process that called qurt_mq_create(). + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue destroy was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_destroy(qurt_mqd_t mqd); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif //QURT_MQ_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mutex.h new file mode 100755 index 0000000000000..4ad6b270cdde6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_mutex.h @@ -0,0 +1,211 @@ +#ifndef QURT_MUTEX_H +#define QURT_MUTEX_H +/** + @file qurt_mutex.h + @brief Prototypes of mutex API. + This is mostly a user space mutex, but calls the + kernel to block if the mutex is taken. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT mutex type. + + Both non-recursive mutex lock and unlock, and recursive + mutex lock and unlock can be applied to this type. + */ +typedef union qurt_mutex_aligned8{ + /** @cond */ + struct { + unsigned int holder; + unsigned int count; + unsigned int queue; + unsigned int wait_count; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_mutex_t; +/** @} */ /* end_addtogroup mutex_types */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* @addtogroup mutex_const_macros +@{ */ +#define MUTEX_MAGIC 0xfe /**< */ +#define QURTK_FUTEX_FREE_MAGIC 0x1F // 11111 /**< */ +#define QURT_MUTEX_INIT {{MUTEX_MAGIC, 0, QURTK_FUTEX_FREE_MAGIC,0}} /**< Suitable as an initializer for a + variable of type qurt_mutex_t. */ +/* @} */ /* end_addtogroup mutex_const_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mutex_init + Initializes a mutex object. + The mutex is initially unlocked. + + @note1hang Each mutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_mutex_destroy() + when this object is not used anymore + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the mutex object. Returns the initialized object. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_destroy + Destroys the specified mutex. + + @note1hang Mutexes must be destroyed when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Mutexes must not be destroyed while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_lock + Locks the specified mutex. + If a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. + + @note1hang A thread is suspended indefinitely if it locks a mutex that it has already + locked. Avoid this by using recursive mutexes (Section @xref{dox:recursive_mutexes}). + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_lock(qurt_mutex_t *lock); /* blocking */ + +/**@ingroup func_qurt_mutex_lock_timed + Locks the specified mutex. + When a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + When a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. If the duration of suspension exceeds the timeout duration, wait is + terminated and no access to mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object; specifies the mutex to lock. + @param[in] duration Interval (in microseconds) that the duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_mutex_lock_timed (qurt_mutex_t * lock, unsigned long long int duration); + +/**@ingroup func_qurt_mutex_unlock + Unlocks the specified mutex. \n + More than one thread can be suspended on a mutex. When the mutex is unlocked, only the + highest-priority thread waiting on the mutex is awakened. If the awakened thread has + higher priority than the current thread, a context switch occurs. + + @note1hang The behavior of QuRT is undefined if a thread unlocks a mutex it did not first + lock. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to unlock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_unlock(qurt_mutex_t *lock); /* unlock */ + +/**@ingroup func_qurt_mutex_try_lock + @xreflabel{hdr:qurt_mutex_try_lock} + Attempts to lock the specified mutex. + If a thread performs a try_lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + @note1hang If a thread performs a try_lock operation on a mutex that it has already locked + or is in use by another thread, qurt_mutex_try_lock immediately returns with a + nonzero result value. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_mutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_os_services.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_os_services.h new file mode 100755 index 0000000000000..cbc4c239e9620 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_os_services.h @@ -0,0 +1,24 @@ +/*============================================================================= + + qurt_os_services.c + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ + +#define QURT_OS_SERVICE_THREAD "/os/thread" /**< Thread service */ +#define QURT_OS_SERVICE_FS_HUB "/os/fs_hub" /**< file-system hub */ +#define QURT_OS_SERVICE_CALLBACK "/os/callback" /**< QDI callback service */ +#define QURT_OS_SERVICE_INTERRUPTS "/os/interrupt" /**< Interrupt service */ +#define QURT_OS_SERVICE_PROXY "/os/proxy" /**< QDI proxy serice */ +#define QURT_OS_SERVICE_MEMORY "/os/memory" /**< Memory management service */ +#define QURT_OS_SERVICE_MEMPOOL "/os/mempool" /**< Pool management service */ +#define QURT_OS_SERVICE_PROCESS "/os/process" /**< Process management service */ +#define QURT_OS_SERVICE_MMAP "/os/mem_mapper" /**< mmapper service */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex.h new file mode 100755 index 0000000000000..61aee5cba7ce8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_PIMUTEX_H +#define QURT_PIMUTEX_H 1 +/** + @file qurt_pimutex.h + @brief Prototypes of qurt_pimutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pimutex_init + Initializes a priority inheritance mutex object. + The priority inheritance mutex is initially unlocked. + + This function works the same as qurt_mutex_init(). + + @note1hang Each pimutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_pimutex_destroy() + when this object is not used anymore + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the priority inheritance mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_destroy + Destroys the specified priority inheritance mutex. + + @note1hang Priority inheritance mutexes must be destroyed when they are no longer in + use. Failure to do this causes resource leaks in the QuRT kernel.\n + @note1cont Priority inheritance mutexes must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_lock + Requests access to a shared resources. If a thread performs a lock operation on a mutex + that is not in use, the thread gains access to the shared resource that the mutex protects, + and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + If a thread is suspended on a priority inheritance mutex, and the priority of the suspended + thread is higher than the priority of the thread that has locked the mutex, the thread + with the mutex acquires the higher priority of the suspended thread. The locker thread blocks + until the lock is available. + + @note1hang A thread is not suspended if it locks a priority inheritance mutex that it has + already locked . However, the mutex does not become available to other + threads until the thread performs a balanced number of unlocks on the mutex.\n + @note1cont When multiple threads compete for a mutex, the lock operation for a priority + inheritance mutex is slower than it is for a recursive mutex. + In particular, it is about 10 times slower when the mutex is available for locking, + and slower (with greatly varying times) when the mutex is already locked. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_lock(qurt_mutex_t *lock); + + +/**@ingroup func_qurt_pimutex_lock_timed + Locks a priority inheritance mutex with timeout. + + A thread can lock a priority inheritance mutex for multiple times. The mutex is not + available to other threads until the thread performs the same number of mutex unlock + operations. + + If a thread performs a lock operation on a mutex that is already locked by another thread, + the thread is moved to waiting state. When the mutex becomes available again (because the + other thread has unlocked the mutex), the thread is awakened and tries to lock the mutex. + + If a thread is waiting on a priority inheritance mutex, and the priority of the waiting thread + is higher than the priority of the thread that has locked the mutex, the priority of the thread + that has locked the mutex is raised to the same priority of the waiting thread. + + If the duration of waiting exceeds the timeout duration, the waiting is terminated, and + the function returns QURT_ETIMEDOUT as a failure of the mutex lock. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to lock. + @param[in] duration Duration (in microseconds) to wait. The duration value must be between + #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + #QURT_EINVALID -- Duration is out of range + + @dependencies + None. + + */ +int qurt_pimutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + + +/**@ingroup func_qurt_pimutex_unlock + Releases access to a shared resource; unlocks the specified priority inheritance mutex. \n + More than one thread can be suspended on a priority inheritance mutex. When the mutex + is unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + When a thread unlocks a priority inheritance mutex, its thread priority is restored to its + original value from any higher priority value that it acquired from another thread + suspended on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_try_lock + Request access to a shared resource (without suspend). Attempts to lock the specified priority inheritance mutex.\n + If a thread performs a try_lock operation on a priority inheritance mutex that is not in + use, the thread gains access to the shared resource that is protected by the mutex, and + continues executing. + If a thread performs a try_lock operation on a priority inheritance mutex that is already + in use by another thread, qurt_pimutex_try_lock immediately returns with a + nonzero result value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_pimutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex2.h new file mode 100755 index 0000000000000..b809f163cbfd2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pimutex2.h @@ -0,0 +1,162 @@ +#ifndef QURT_PIMUTEX2_H +#define QURT_PIMUTEX2_H +/** + @file qurt_pimutex2.h + @brief Prototypes of pimutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_pimutex2_init + Initializes a recursive mutex object. + + @deprecated use #qurt_pimutex_init instead. + + The recursive mutex is initially unlocked. + + Objects of type pimutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_destroy + + @deprecated use #qurt_pimutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1cont Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code should destroy an pimutex2 object prior to + deallocating it; calling qurt_pimutex2_destroy() before deallocating it ensures + that all qurt_pimutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_lock + + @deprecated use #qurt_pimutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not being used, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing. + + If a thread performs a lock operation on a recursive mutex that is already being used by + another thread, the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_unlock + + @deprecated use #qurt_pimutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_pimutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_pimutex2_lock(). If a call to qurt_pimutex2_lock() would + succeed immediately, this function behaves similarly, and returns 0 for success. + If a call to qurt_pimutex2_lock() would not succeed immediately, this function has + no effect and returns non-zero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_pimutex2_try_lock(qurt_rmutex2_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pipe.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pipe.h new file mode 100755 index 0000000000000..6bdaa044f8640 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pipe.h @@ -0,0 +1,479 @@ +#ifndef QURT_PIPE_H +#define QURT_PIPE_H +/** + @file qurt_pipe.h + @brief Prototypes of the pipe interface API + This is a pipe or message queue + It blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup pipe_types +@{ */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_PIPE_MAGIC 0xF1FEF1FE /**< Magic. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_RAM 0 /**< RAM. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_TCM 1 /**< TCM. */ + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** QuRT pipe data values type. */ +typedef unsigned long long int qurt_pipe_data_t; + +/** QuRT pipe type.*/ +typedef struct { + /** @cond */ + qurt_mutex_t pipe_lock; + qurt_sem_t senders; + qurt_sem_t receiver; + unsigned int size; + unsigned int sendidx; + unsigned int recvidx; + void (*lock_func)(qurt_mutex_t *); + void (*unlock_func)(qurt_mutex_t *); + int (*try_lock_func)(qurt_mutex_t *); + void (*destroy_lock_func)(qurt_mutex_t *); + unsigned int magic; + qurt_pipe_data_t *data; + /** @endcond */ +} qurt_pipe_t; + +/** QuRT pipe attributes type. */ +typedef struct { + /** @cond */ + qurt_pipe_data_t *buffer; + unsigned int elements; + unsigned char mem_partition; + /** @endcond */ +} qurt_pipe_attr_t; + +/** @} */ /* end_addtogroup pipe_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pipe_attr_init + @xreflabel{hdr:qurt_pipe_attr_init} + Initializes the structure that sets the pipe attributes when a pipe is created. + + After an attribute structure is initialized, the individual attributes in the structure are + explicitly set using the pipe attribute operations. + + The attribute structure is assigned the following default values: \n + - buffer -- 0 \n + - elements -- 0 \n + - mem_partition -- #QURT_PIPE_ATTR_MEM_PARTITION_RAM + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_init(qurt_pipe_attr_t *attr) +{ + attr->buffer = NULL; + attr->elements = 0; + attr->mem_partition = QURT_PIPE_ATTR_MEM_PARTITION_RAM; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer + @xreflabel{sec:qurt_pipe_attr_set_buffer} + Sets the pipe buffer address attribute.\n + Specifies the base address of the memory area to use for the data buffer of a pipe. + + The base address and size (Section @xref{sec:qurt_pipe_attr_set_elements}) specify the + memory area used as a pipe data buffer. The user is responsible for allocating the + memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t \n + #qurt_pipe_data_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] buffer Pointer to the buffer base address. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer(qurt_pipe_attr_t *attr, qurt_pipe_data_t *buffer) +{ + attr->buffer = buffer; +} + +/**@ingroup func_qurt_pipe_attr_set_elements + @xreflabel{sec:qurt_pipe_attr_set_elements} + Specifies the length of the memory area to use for the data buffer of a pipe. + + The length is expressed in terms of the number of 64-bit data elements that + can be stored in the buffer. + + The base address (Section @xref{sec:qurt_pipe_attr_set_buffer}) and size specify + the memory area used as a pipe data buffer. The user is responsible for + allocating the memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] elements Pipe length (64-bit elements). + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_elements(qurt_pipe_attr_t *attr, unsigned int elements) +{ + attr->elements = elements; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer_partition + @xreflabel{sec:qurt_pipe_attr_set_buffer_partition} + Specifies the memory type where a pipe's buffer is allocated. + Allocate pipes in RAM or TCM/LPM. + + @note1hang If a pipe is specified as allocated in TCM/LPM, it must be created + with the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] mem_partition Pipe memory partition. Values: \n + - #QURT_PIPE_ATTR_MEM_PARTITION_RAM -- Pipe resides in RAM \n + - #QURT_PIPE_ATTR_MEM_PARTITION_TCM -- Pipe resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer_partition(qurt_pipe_attr_t *attr, unsigned char mem_partition) +{ + attr->mem_partition = mem_partition; +} + +/**@ingroup func_qurt_pipe_create + Creates a pipe.\n + Allocates a pipe object and its associated data buffer, and initializes the pipe object. + + @note1hang The buffer address and size stored in the attribute structure specify how the + pipe data buffer is allocated. + + @note1cont If a pipe is specified as allocated in TCM/LPM, it must be created + using the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the created pipe object. + @param[in] attr Pointer to the attribute structure used to create the pipe. + + @return + #QURT_EOK -- Pipe created. \n + #QURT_EFAILED -- Pipe not created. \n + #QURT_ENOTALLOWED -- Pipe cannot be created in TCM/LPM. + + @dependencies + None. + */ +int qurt_pipe_create(qurt_pipe_t **pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_init + Initializes a pipe object using an existing data buffer. + + @note1hang The buffer address and size stored in the attribute structure must + specify a data buffer that the user has already allocated. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the pipe object to initialize. + @param[in] attr Pointer to the pipe attribute structure used to initialize the pipe. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Failure. + + @dependencies + None. + */ +int qurt_pipe_init(qurt_pipe_t *pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_destroy + @xreflabel{sec:qurt_pipe_destroy} + Destroys the specified pipe. + + @note1hang Pipes must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel. + Pipes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_destroy(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_delete + Deletes the pipe.\n + Destroys the specified pipe (Section @xref{sec:qurt_pipe_destroy}) and deallocates the pipe object and its + associated data buffer. + + @note1hang Delete pipes only if they were created using qurt_pipe_create + (and not qurt_pipe_init). Otherwise the behavior of QuRT is undefined. \n + @note1cont Pipes must be deleted when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Pipes must not be deleted while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_delete(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_send + Writes a data item to the specified pipe. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + None. + + @dependencies + None. +*/ +void qurt_pipe_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_receive + Reads a data item from the specified pipe. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + Integer containing the 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_receive(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_try_send + Writes a data item to the specified pipe (without suspending the thread if the pipe is full).\n + + If a thread writes to a full pipe, the operation returns immediately with success set to -1. + Otherwise, success is always set to 0 to indicate a successful write operation. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + 0 -- Success. \n + -1 -- Failure (pipe full). + + @dependencies + None. +*/ +int qurt_pipe_try_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_try_receive + Reads a data item from the specified pipe (without suspending the thread if the pipe is + empty).\n + If a thread reads from an empty pipe, the operation returns immediately with success set + to -1. Otherwise, success is always set to 0 to indicate a successful read operation.\n + + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[out] success Pointer to the operation status result. + + @return + Integer containing a 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_try_receive(qurt_pipe_t *pipe, int *success); + +/**@ingroup func_qurt_pipe_receive_cancellable + Reads a data item from the specified pipe (with suspend), cancellable. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + The operation is cancelled if the user process of the calling thread is killed, + or if the calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] result Pointer to the integer containing the 64-bit data item from pipe. + + @return + #QURT_EOK -- Receive completed. \n + #QURT_ECANCEL -- Receive canceled. \n + #QURT_EDESTROY -- Receive destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_receive_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t *result); + +/**@ingroup func_qurt_pipe_send_cancellable + @xreflabel{hdr:qurt_pipe_send_cancellable} + Writes a data item to the specified pipe (with suspend), cancellable. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + The operation is canceled if the user process of the calling thread is killed, or if the + calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] data Data item to write. + + @return + #QURT_EOK -- Send completed. \n + #QURT_ECANCEL -- Send canceled. \n + #QURT_EDESTROY -- Send destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_send_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_is_empty + Returns a value indicating whether the specified pipe contains any data. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + 1 -- Pipe contains no data. \n + 0 -- Pipe contains data. + + @dependencies + None. +*/ +int qurt_pipe_is_empty(qurt_pipe_t *pipe); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIPE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmem_manager.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmem_manager.h new file mode 100755 index 0000000000000..8c8da985228b9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmem_manager.h @@ -0,0 +1,82 @@ +#ifndef QURT_PMEM_MANAGER_H +#define QURT_PMEM_MANAGER_H +/** + @file qurt_pmem_manager.h + Prototypes of kernel physical memory manager APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* physical memory API return error code */ +#define QURT_PMEM_SUCCESS 0 +#define QURT_PMEM_NO_PRIV 1 +#define QURT_PMEM_RETRY 2 +#define QURT_PMEM_OVERLAP 3 +#define QURT_PMEM_NOT_EXIST 4 +#define QURT_PMEM_INIT_FAILURE 5 +#define QURT_PMEM_OUTSTANDING_MAPPING 6 +#define QURT_PMEM_GENERIC_FAILURE 7 +#define QURT_PMEM_ENTRY_FOUND 8 +#define QURT_PMEM_REACH_END 9 +#define QURT_PMEM_UNCLAIMED 10 +#define QURT_PMEM_ALREADY_CLAIMED 11 + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_pmem_acquire + Acquire the ownership of a specific physical memory region. + + @note1hang The ownership will be the caller + + @param[in] ppage Starting physical page number + @param[in] pnum Number of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_OVERLAP -- The whole or part of the range has been owned \n + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. +*/ +int qurt_pmem_acquire(unsigned int ppage, unsigned int pnum); + +/**@ingroup func_qurt_pmem_release + Release the ownership of a specific physical memory region. + + @param[in] ppage The start of physical page number + @param[in] pnum The numbers of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_NOT_EXIST -- The physical memory range is not usable. \n + #QURT_PMEM_OUTSTANDING_MAPPING -- There is outstanding mapping in this range + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. + */ +int qurt_pmem_release(unsigned int ppage, unsigned int pnum); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMEM_MANAGER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmu.h new file mode 100755 index 0000000000000..73ea8eba04abf --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_pmu.h @@ -0,0 +1,121 @@ +#ifndef QURT_PMU_H +#define QURT_PMU_H +/** + @file qurt_pmu.h + Prototypes of pipe interface API. + A pipe or message queue blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_pmu_set + Sets the value of the specified PMU register. + + @note1hang Setting PMUEVTCFG automatically clears the PMU registers PMUCNT0 + through PMUCNT3. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @param[in] reg_value Register value. + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_set (int reg_id, unsigned int reg_value); + +/**@ingroup func_qurt_pmu_get + Gets the PMU register.\n + Returns the current value of the specified PMU register. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @return + Integer -- Current value of the specified PMU register. + + @dependencies + None. + */ +unsigned int qurt_pmu_get (int reg_id); + +/**@ingroup func_qurt_pmu_enable + Enables or disables the Hexagon processor PMU. + Profiling is disabled by default. + + @note1hang Enabling profiling does not automatically reset the count registers -- this must + be done explicitly before starting event counting. + + @param[in] enable Performance monitor. Values: \n + - 0 -- Disable performance monitor \n + - 1 -- Enable performance monitor @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_enable (int enable); + +/**@ingroup func_qurt_pmu_get_pmucnt + Reads PMU counters in a single trap. + + @param[out] buf Pointer to a buffer to save values read from PMU counters. + buffer size should be at least 32 bytes to read all eight PMU counters. + + @return + #QURT_EOK -- Successful read.\n + #QURT_EFATAL -- Failure. + + @dependencies + None. + */ +int qurt_pmu_get_pmucnt (void * buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMU_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_power.h new file mode 100755 index 0000000000000..2ee4d29a73976 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_power.h @@ -0,0 +1,140 @@ +#ifndef QURT_POWER_H +#define QURT_POWER_H +/** + @file qurt_power.h + @brief Prototypes of power API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/*============================================================================= + + EDIT HISTORY FOR MODULE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + +when who what, where, why +-------- --- ------------------------------------------------------------ +03/03/11 op Add header file +12/12/12 cm (Tech Pubs) Edited/added Doxygen comments and markup. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +/**@ingroup func_qurt_power_shutdown_fail_exit + Returns from Power Collapse mode when power collapse cannot proceed. + + This function unmasks the global interrupt. This operation is used only when the thread is + recovering from a failed power collapse operation (Section @xref{sec:powerShutdownEnter}). + + @return + #QURT_EOK -- Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_fail_exit qurt_power_exit + +/**@ingroup func_qurt_power_shutdown_exit + Undoes state changes made preparing for power collapse.\n + This function unmasks the global interrupts. + + @return + #QURT_EOK --Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_exit qurt_power_exit +/**@endcond */ + +/**@ingroup func_qurt_system_ipend_get + Gets the IPEND register.\n + + @note1hang Returns the current value of the Hexagon processor IPEND register. The return value + is a mask value that identifies the individual interrupts that are pending. \n + + @note1hang The bit order of the mask value is identical to the order defined for the IPEND register. A + mask bit value of 1 indicates that the corresponding interrupt is pending, and 0 indicates that the + corresponding interrupt is not pending. \n + + @return + Return the IPEND register value. + + @dependencies + None. + */ +unsigned int qurt_system_ipend_get (void); + + +/**@ingroup func_qurt_system_vid_get + Gets the VID register. \n + + @note1hang Returns the current value of the Hexagon processor VID register. The return value is + the vector number of a second-level interrupt that has been accepted by the Hexagon + processor core.\n + + @return + Return the VID register value that is the L2 VIC interrupt number accepted by the processor. + Valid range is 0 to 1023. + + @dependencies + None. + */ +unsigned int qurt_system_vid_get(void); + +/**@ingroup func_qurt_power_shutdown_get_pcycles + Gets the number of power collapses and processor cycles for entering and exiting most recent + power collapse. + + @note1hang If no power collapse has occured yet, processor cycle numbers are zero. + + @param[out] enter_pcycles Number of processor cycles for entering most + recent power collapse. + @param[out] exit_pcycles Number of processor cycles for exiting most + recent power collapse. + @return + Zero -- No power collapses have occurred. \n + Nonzero -- Number of power collapses that have occurred since + the processor was reset. + + @dependencies + None. + */ +int qurt_power_shutdown_get_pcycles( unsigned long long *enter_pcycles, unsigned long long *exit_pcycles ); + +/**@ingroup func_qurt_system_tcm_set_size + Set size of TCM to save during full power collapse. + + @note1hang The size aligns to 32 bytes. If size passed is greater than the maximum size defined in + XML, the size is truncated to the size defined in XML. + + @param[in] new_size Size of TCM to save. + + @return + Zero -- Size successfully set \n + -1 -- Size of 0 passed + + @dependencies + None. + */ +int qurt_system_tcm_set_size(unsigned int new_size); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_POWER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_printf.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_printf.h new file mode 100755 index 0000000000000..a775d8a815918 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_printf.h @@ -0,0 +1,44 @@ +#ifndef QURT_PRINTF_H +#define QURT_PRINTF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file qurt_printf.h + Prototypes of printf API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup chapter_function_tracing +@{ */ + +int qurt_printf(const char* format, ...); + +int qurt_vprintf(const char* format, va_list args); + +/** @} */ /* end_addtogroup chapter_function_tracing */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PRINTF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_process.h new file mode 100755 index 0000000000000..0df9ddc2d4a70 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_process.h @@ -0,0 +1,995 @@ +#ifndef QURT_PROCESS_H +#define QURT_PROCESS_H +/** + @file qurt_process.h + @brief Prototypes of QuRT process control APIs. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2009-2013, 2021-2023 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_callback.h" +#include "qurt_consts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup process_types +@{ */ +#define QURT_PROCESS_ATTR_NAME_MAXLEN QURT_MAX_NAME_LEN /**< Maximum length of the process name. */ +#define QURT_PROCESS_ATTR_BIN_PATH_MAXLEN 128 /**< Maximum length of the path of binary/ELF for this process. */ +#define QURT_PROCESS_ATTR_CAP_MAXLEN 128 /**< Maximum length for a resource name. */ + +/** QuRT process capability wildcard strings */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_ALL "ALLOW_ALL" /**< Capability wild-card for full access */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_NONE "ALLOW_NONE" /**< Capability wild-card for no access */ + +/** QuRT process capability states */ +#define QURT_PROCESS_ATTR_CAP_ENABLED 0x1 /**< Capability enabled*/ +#define QURT_PROCESS_ATTR_CAP_DISABLED 0x0 /**< Capability disabled*/ + +/* QuRT process thread attributes. */ +#define QURT_PROCESS_DEFAULT_CEILING_PRIO 0 /**< Default ceiling priority of the threads in the new process. */ +#define QURT_PROCESS_DEFAULT_MAX_THREADS -1 /**< Default number of threads in the new process. + -1 indicates that the limit is set to the maximum supported by the system. */ + +/* QuRT process flags. */ +#define QURT_PROCESS_SUSPEND_ON_STARTUP (1U) /**< Suspend the new processes just before calling main(). */ +#define QURT_PROCESS_NON_SYSTEM_CRITICAL (1u << 1) /**< Starts the new process as non system-critical. */ +#define QURT_PROCESS_ISLAND_RESIDENT (1u << 2) /**< Process is island resident. */ +#define QURT_PROCESS_RESTARTABLE (1u << 3) /**< Indicates that the process is restartable */ +#define QURT_PROCESS_UNTRUSTED (1u << 7) /**< Starts the new process as unsigned process. */ + +/* QuRT process debugging session status.*/ +#define QURT_DEBUG_NOT_START 0 /**< Debug is not started. */ +#define QURT_DEBUG_START 1 /**< Debug has started. */ + +/** Process Suspend Options */ +#define QURT_PROCESS_SUSPEND_DEFAULT 0 + +/** Process Resume Options */ +#define QURT_PROCESS_RESUME_DEFAULT 0 + + +/* QuRT process types. */ +typedef enum { + QURT_PROCESS_TYPE_RESERVED, /**< Process type is reserved. \n */ + QURT_PROCESS_TYPE_KERNEL, /**< Kernel process. \n*/ + QURT_PROCESS_TYPE_SRM, /**< SRM process. \n*/ + QURT_PROCESS_TYPE_SECURE, /**< Secure process. \n*/ + QURT_PROCESS_TYPE_ROOT, /**< Root process. \n*/ + QURT_PROCESS_TYPE_USER, /**< User process. */ +}qurt_process_type_t; + +/** QuRT process callback types. */ +typedef enum { + QURT_PROCESS_DUMP_CB_ROOT, /**< Register the callback that executes in the + root process context. \n */ + QURT_PROCESS_DUMP_CB_ERROR, /**< Register the user process callback that is + called after threads in the process are frozen. \n */ + QURT_PROCESS_DUMP_CB_PRESTM, /**< Register the user process callback that is + called before threads in the process are frozen. \n*/ + QURT_PROCESS_DUMP_CB_MAX /**< Reserved for error checking. */ +}qurt_process_dump_cb_type_t; + +/** QuRT process dump attributes. */ +typedef struct _qurt_pd_dump_attr{ + /** @cond */ + unsigned int enabled; /**< Process dump is enabled. */ + const char *path; /**< Process dump path. */ + unsigned int path_len; /**< Length of process dump path. */ + /** @endcond */ +}qurt_pd_dump_attr_t; + +/** QuRT process capability resource type */ +enum qurt_process_cap_type_t { + QURT_PROCESS_CAP_TYPE_NUM_ENTRIES=0, /**< Number of entries in the capability structure*/ + QURT_PROCESS_CAP_TYPE_DRIVER=1, /**< Driver resource */ + QURT_PROCESS_CAP_TYPE_MAX /**< Maximum identifier */ +}; + +/** QuRT process capability structure */ +typedef struct _qurt_capability { + enum qurt_process_cap_type_t type; /**< Resource type */ + char name[QURT_PROCESS_ATTR_CAP_MAXLEN]; /**< Resource name*/ + unsigned long long cap; /**< Capabilities allowed for this resource */ +}qurt_capability_t; + +/** QuRT process attributes. */ +typedef struct _qurt_process_attr { + /** @cond */ + char name[QURT_PROCESS_ATTR_NAME_MAXLEN]; /**< Name of the new process. */ + char path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the binary for the new process. */ + char dtb_path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the DTB ELF for the new process. */ + int flags; /**< Flags as indicated by QuRT process flags. */ + unsigned int sw_id; /**< Software ID of the process be load. */ + unsigned sid; /**< Stream ID of the process being spawned. */ + unsigned max_threads; /**< Maximum number of threads that the new process can create. */ + unsigned short ceiling_prio; /**< Maximum priority at which threads can be + created by new process. */ + qurt_process_type_t type; /**< Process type as indicated by + #qurt_process_type_t. */ + qurt_pd_dump_attr_t dump_attr; /**< Process dump attributes for the new process + as indicated by #qurt_pd_dump_attr_t. */ + qurt_capability_t *capabilities; /**< Pointer to array of structure of type + qurt_capability_t */ + /** @endcond */ +} qurt_process_attr_t; + +/** @} */ /* end_addtogroup process_types */ + +/*============================================================================= +FUNCTIONS +=============================================================================*/ + /** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_create + Creates a process with the specified attributes, and starts the process. + + The process executes the code in the specified executable ELF file. + + @datatypes + #qurt_process_attr_t + + @param[out] attr Accepts an initialized process attribute structure, which specifies + the attributes of the created process. + + @return + Postive return value Indicates Process ID. + Negative return value Indicates any of follwoing error, + #-QURT_EPRIVILEGE -- Caller does not have privilege for this operation \n + #-QURT_EMEM -- Not enough memory to perform the operation \n + #-QURT_EFAILED -- Operation failed \n + #-QURT_ENOTALLOWED -- Operation not allowed \n + #-QURT_ENOREGISTERED -- Not registered \n + #-QURT_ENORESOURCE -- Resource exhaustion \n + #-QURT_EINVALID -- Invalid argument value + #QURT_EFATAL -- attr is NULL + + @dependencies + None. +*/ +int qurt_process_create (qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_get_id + Returns the process identifier for the current thread. + + @return + None. + + @dependencies + Process identifier for the current thread. +*/ +int qurt_process_get_id (void); +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_get_uid + Returns the user identifier for the current thread. + + @return + None. + + @dependencies + User identifier for the current thread. +*/ +int qurt_process_get_uid (void); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_init + Initializes the structure that sets the process attributes when a thread is created. + + After an attribute structure is initialized, the individual attributes in the structure can + be explicitly set using the process attribute operations. + + Table @xref{tbl:processAttrDefaults} lists the default attribute values set by the initialize + operation. + + @inputov{table_process_attribute_defaults} + + @datatypes + #qurt_process_attr_t + + @param[out] attr Pointer to the structure to initialize. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_process_attr_init (qurt_process_attr_t *attr) +{ + attr->name[0] = '\0'; + attr->path[0] = '\0'; + attr->dtb_path[0] = '\0'; + attr->flags = 0; + attr->sw_id = 0; + attr->sid = 0; + attr->max_threads = (unsigned)QURT_PROCESS_DEFAULT_MAX_THREADS; + attr->ceiling_prio = QURT_PROCESS_DEFAULT_CEILING_PRIO; + attr->type = QURT_PROCESS_TYPE_RESERVED; + attr->dump_attr.enabled = 0; + attr->dump_attr.path = NULL; + attr->dump_attr.path_len = 0; + attr->capabilities = NULL; +} + +/**@ingroup func_qurt_process_attr_set_executable + Sets the process name in the specified process attribute structure. + + Process names identify process objects that are already + loaded in memory as part of the QuRT system. + + @note1hang Process objects are incorporated into the QuRT system at build time. + + @note1hang Maximum length of name string is limited to QURT_PROCESS_ATTR_NAME_MAXLEN - 1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] name Pointer to the process name. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_executable (qurt_process_attr_t *attr, const char *name); + +/**@ingroup func_qurt_process_attr_set_binary_path + Sets the binary path for the process loading in the specified process attribute structure. + + Path specifies the binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_binary_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_dtb_path + Sets the DTB binary path for the process loading in the specified process attribute structure. + + Path specifies the DTB binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_dtb_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_flags +Sets the process properties in the specified process attribute structure. +Process properties are represented as defined symbols that map into bits +0 through 31 of the 32-bit flag value. Multiple properties are specified by OR'ing +together the individual property symbols. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] flags QURT_PROCESS_NON_SYSTEM_CRITICAL Process is considered as non system-critical. + This attribute will be used by error services, + to decide whether to kill user pd or whole subsystem. + QURT_PROCESS_ISLAND_RESIDENT Process will be marked as island resident. + QURT_PROCESS_RESTARTABLE Process will be marked as restartable. + QURT_PROCESS_UNTRUSTED Process will be marked as unsigned process. +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_flags (qurt_process_attr_t *attr, int flags) +{ + attr->flags = flags; +} +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_sid +Sets the process streamID in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sid streamID to set for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sid (qurt_process_attr_t *attr, unsigned sid) +{ + attr->sid = sid; +} +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_set_max_threads +Sets the maximum number of threads allowed in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] max_threads Maximum number of threads allowed for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_max_threads (qurt_process_attr_t *attr, unsigned max_threads) +{ + attr->max_threads = max_threads; +} + +/**@ingroup func_qurt_process_attr_set_sw_id +Sets the software ID of the process to load in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sw_id Software ID of the process, used in authentication. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sw_id(qurt_process_attr_t *attr, unsigned int sw_id) +{ + attr->sw_id = sw_id; +} + +/**@ingroup func_qurt_process_attr_set_ceiling_prio +Sets the highest thread priority allowed in the specified process attribute structure. +Refer qurt_thread.h for priority ranges. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] prio Priority. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_ceiling_prio (qurt_process_attr_t *attr, unsigned short prio) +{ + attr->ceiling_prio = prio; +} +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_dump_status +Sets the process domain dump-enabled field in the process domain dump attributes. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] enabled 1 -- Process domain dump is collected \n + 0 -- Process domain dump is not collected + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_status(qurt_process_attr_t *attr, unsigned int enabled) +{ + attr->dump_attr.enabled = enabled; +} + +/**@ingroup func_qurt_process_attr_set_dump_path +Sets the process domain dump path and type. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] path Path where the process domain dumps must be saved. +@param[in] path_len Length of the path string. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_path(qurt_process_attr_t *attr, const char *path, int path_len) +{ + attr->dump_attr.path = path; + attr->dump_attr.path_len = (unsigned int)path_len; +} + +/**@ingroup func_qurt_process_attr_set_capabilities +Sets list of capabilities available to this process. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] capabilities Pointer to array of structures of type qurt_capability_t defining + resources and capabilites + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_capabilities(qurt_process_attr_t *attr, qurt_capability_t *capabilities) +{ + attr->capabilities = capabilities; +} + +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_cmdline_get +Gets the command line string associated with the current process. +The Hexagon simulator command line arguments are retrieved using +this function as long as the call is made +in the process of the QuRT installation, and with the +requirement that the program runs in a simulation environment. + +If the function modifies the provided buffer, it zero-terminates +the string. It is possible that the function does not modify the +provided buffer, so the caller must set buf[0] to a NULL +byte before making the call. A truncated command line is returned when +the command line is longer than the provided buffer. + +@param[in] buf Pointer to a character buffer that must be filled in. +@param[in] buf_siz Size (in bytes) of the buffer pointed to by the buf argument. + +@return +None. + +@dependencies +None. +*/ +void qurt_process_cmdline_get(char *buf, unsigned buf_siz); + +/**@ingroup func_qurt_process_get_thread_count +Gets the number of threads present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of threads in the process indicated by PID, if positive value is obtained +Negative error code if failed include: + QURT_EFATAL - Invalid PID + -QURT_ENOTALLOWED - Current process doesnt have access to target process indicated by PID + +@dependencies +None. +*/ +int qurt_process_get_thread_count(unsigned int pid); + +/**@ingroup func_qurt_process_get_thread_ids +Gets the thread IDs for a process indicated by PID. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a user passed buffer that must be filled in with thread IDs. +@param[in] thread_num Number of thread IDs requested. + +@return +#QURT_EOK - Success +#QURT_EFATAL - Failed, ptr is NULL + +@dependencies +None. + */ +int qurt_process_get_thread_ids(unsigned int pid, unsigned int *ptr, unsigned thread_num); +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_dump_get_mem_mappings_count +Gets the number of mappings present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of mappings for the process indicated by the PID. + +@dependencies +None. +*/ +int qurt_process_dump_get_mem_mappings_count(unsigned int pid); + +/**@ingroup func_qurt_process_dump_get_mappings +Gets the mappings for a specified PID. + +@note1hang This API skips device type mappings or mappings created by setting the #QURT_PERM_NODUMP attribute. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a buffer that must be filled in with mappings. +@param[in] count Count of mappings requested. + +@return +Number of mappings filled in the buffer passed by the user. + +@dependencies +None. +*/ +int qurt_process_dump_get_mappings(unsigned int pid, unsigned int *ptr, unsigned count); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_get +Gets the attributes of the process with which it was created. + +@datatypes +#qurt_process_attr_t + +@param[in] pid PID of the process for which the information is required. +@param[in,out] attr Pointer to the user allocated attribute structure. + +@return +#QURT_EOK - Success +#QURT_INVALID - Invalid PID +#QURT_EFATAL - attr is NULL + +@dependencies +None. +*/ +int qurt_process_attr_get(unsigned int pid, qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_dump_register_cb +Registers the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information. +@param[in] type Callback type; these callbacks are called in the context of the user process domain: \n + #QURT_PROCESS_DUMP_CB_PRESTM -- Before threads of the exiting process are frozen. \n + #QURT_PROCESS_DUMP_CB_ERROR -- After threads are frozen and captured. \n + #QURT_PROCESS_DUMP_CB_ROOT -- After threads are frozen and captured, and CB_ERROR type of callbacks + are called. +@param[in] priority Priority. + +@return +#QURT_EOK -- Success \n +Other values -- Failure + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_register_cb(qurt_cb_data_t *cb_data, qurt_process_dump_cb_type_t type, unsigned short priority); + +/**@ingroup func_qurt_process_dump_deregister_cb +Deregisters the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information to deregister. +@param[in] type Callback type. + +@return +#QURT_EOK -- Success.\n +Other values -- Failure. + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_deregister_cb(qurt_cb_data_t *cb_data,qurt_process_dump_cb_type_t type); + +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_set_rtld_debug +Sets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in] address rtld_debug address. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_set_rtld_debug(unsigned int pid,unsigned int address); + +/**@ingroup func_qurt_process_get_rtld_debug +Gets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in,out] address Pointer to the user passed address in which the rtld_debug address must be returned. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_get_rtld_debug(unsigned int pid,unsigned int *address); +/** @endcond */ +/**@ingroup func_qurt_process_exit +Exits the current user process with an exit code. + +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exit(int exitcode); + +/**@ingroup func_qurt_process_kill +Kills the process represented by the PID with the exit code. + +@param[in] pid PID of the process to kill. +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_kill(int pid, int exitcode); + + +/**@ingroup func_qurt_debugger_register_process +Registers the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. +@param[in] adr Address. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_register_process(int pid, unsigned int adr); + + +/**@ingroup func_qurt_debugger_deregister_process +Deregister the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_deregister_process(int pid); + +/**@ingroup func_qurt_process_exec_callback +Executes callbacks in the user process as indicated by the client_handle argument. + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] callback_fn Callback function to execute. +@param[in] stack_base Stack address to use. +@param[in] stack_size Stack size. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exec_callback(int client_handle, + unsigned callback_fn, + unsigned stack_base, + unsigned stack_size); + +/**@ingroup func_qurt_process_get_pid +Gets the process ID of the process that the client_handle argument represents. + +@note1hang This API is not supported for unsigned PD, For unsigned PD use qurt_process_get_id() + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] pid Pointer to the address to store the PID. + +@return +#QURT_EOK -- Success +#QURT_EFATAL -- pid pointer passed as NULL + +@dependencies +None. +*/ +int qurt_process_get_pid(int client_handle, int * pid); + +/**@ingroup func_qurt_process_get_dm_status +Gets the debugging session status on the process represented by the pid argument. + +@param[in] pid Process ID +@param[in,out] status Address to store the status: \n + #QURT_DEBUG_NOT_START \n + #QURT_DEBUG_START + +@return +#QURT_EOK - Success \n +#QURT_EINVALID - Error + +@dependencies +None. +*/ +int qurt_process_get_dm_status( unsigned int pid, unsigned int *status); + + +/**@ingroup func_qurt_process_suspend_threads + Suspends user threads in a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in GuestOS/root process. + After the user threads in the target user process are suspended, they cannot be scheduled to run by the kernel + until they resume later. + + This function has one optional argument with one default option. + #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + This function call is a synchronous call, the function returns after the relevant threads are + completely suspended. + + If some user threads in the target user process are set as non-suspendable, this function call does + not suspend these threads. + + If the target user process is already suspended, this function call returns success as the + confirmation on the user process suspending. + + QuRT debugger monitor threads in the target user process are non-suspendable, this function call does + not suspend the threads. + + If the target user process is a secure user process, or a CPZ process, this function call returns error + without suspending the target user process. + + If a user thread in the target user process runs in the guest OS/root process via a QDI call, this function call + does not suspend the thread in the guest OS, but instead marks the thread as pending-suspend. The thread is suspended + when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success while the user thread can be running in GuestOS, and is suspended + when exiting the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Dfault option #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid process_id input \n + #QURT_ENOTALLOWED -- Failure because the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_suspend_threads (unsigned int process_id, unsigned int option); + + +/**@ingroup func_qurt_process_resume_threads + Resumes a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in the guest OS/root process. + After the user threads in the target user process resume, the kernel scheduler + can schedule the user threads to run based on their thread priorities. + + This function has an optional argument, #QURT_PROCESS_RESUME_DEFAULT, which + resumes user threads in the target user process. + + This is an asynchronous function, it returns after the kernel moves the user thread from + suspended state to runnable state. The threads are scheduled to run based on their thread priorities. + + This function call does not resume threads in the target user process that have been set as non-resumable. + + If the target user process have already resumed, this function call confirms that the user process resumes + by returning success. + + If the target user process is a secure user process or a CPZ process, this function call returns an error without + resuming operation. + + If user threads in the target user process run in the guest OS/root process via QDI call, this function + call clears the mark of suspend-pending on these threads, so that the threads are be suspended when it exits + the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Default option #QURT_PROCESS_RESUME_DEFAULT resumes user threads in the target user process. + + @return + #QURT_EOK -- Success + #QURT_EINVALID -- Failure because of invalid process_id input. + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_resume_threads (unsigned int process_id, unsigned int option); + +/**@ingroup func_qurt_process_vtcm_window_set + Set a VTCM access window for a process. + The caller thread needs to be in SRM process. + + This is an synchronous function, it ensures all running threads of the process have the requested + window in effect.The requested view for all non-running thread will take in effect when they get + scheduled. + + @param[in] pid Process identifier. + @param[in] enable QURT_VTCM_WINDOW_ENABLE enforces VTCM access window defined by high and low offset. + QURT_VTCM_WINDOW_DISABLE high and low offset is ignored and VTCM access is fully + disabled for the process. + @param[in] high_offset Specifies the high window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT restore high offset to reset value. + @param[in] low_offset Specifies the low window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT restore low offset to reset value. + + @note1hang + when high_offset is set to QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT and low offset is set as + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT full VTCM range is accessible. Access to VTCM is controlled + via MMU mapping for the process. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_set(int pid, unsigned int enable, unsigned int high_offset, unsigned int low_offset); + +/**@ingroup func_qurt_process_vtcm_window_get + Get the VTCM window for a process. + The caller thread needs to be in SRM process. + + + @param[in] pid Process identifier. + @param[out] enable address to store enable status if set + @param[out] high_offset address to return high window offset, in 4K increments, from the base address of the VTCM + @param[out] low_offset address to return low window offset, in 4K increments, from the base address of the VTCM. + + @note1hang + User must first check the value of enable returned before checking high and low offset. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_get(int pid, unsigned int *enable, unsigned int *high_offset, unsigned int *low_offset); + +/**@ingroup func_qurt_process_set_group_config + Enable thread groups in the process with the ceiling priorities setup + + @param[in] process_id Process identifier. + @param[in] group_bitmask 64-bit mask of active thread groups + @param[in] ceiling_priorities array of ceiling priorities for thread group + + @note1hang + This API can only be called by root PD and can only be called once for each process, otherwise it will be + rejected. Group 0 must be enabled in group_bitmask, otherwise QuRT will return error. After this API, all + exisiting threads will be moved to group 0, and if there is any thread's priority higher than ceiling + priority of group 0, it will be lowered to the ceiling value. + Examples 1: + group_bitmask = 0xD7; //'b11010111 + ceiling_priorities[] = {100, 128, 200, 0, 196, 0, 240, 20}; // 0 - does not care + Exmaples 2: + group_mask = 0x5; //'b101 + ceiling_priorities[] = {240, 0, 20}; // 0 - does not care + + + @return + #QURT_EOK -- Success. + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_ENOTALLOWED -- The group has been configured already. + + @dependencies + None. + */ +int qurt_process_set_group_config(unsigned int process_id, unsigned long long group_bitmask, + unsigned char *ceiling_priorities); + + +/**@ingroup func_qurt_process_stid_set + Set the specified stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[in] stid stid to be set + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) if stid needs to set at a process level. + All threads within a process that has default stid (QURT_STID_DEFAULT) will inherit the stid set for a process. + When a non-default group_id is specified, the stid is set only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_set(unsigned int pid, unsigned int group_id , unsigned int stid); + +/**@ingroup func_qurt_process_stid_get + Get the stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[out] Pointer to a variable to return stid + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) to return process-level stid. + When a non-default group_id is specified, the stid is returned only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_get(unsigned int pid, unsigned int group_id , unsigned int *stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_profile.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_profile.h new file mode 100755 index 0000000000000..2a50c461440f6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_profile.h @@ -0,0 +1,98 @@ +#ifndef QURT_PROFILE_H +#define QURT_PROFILE_H +/** + @file qurt_profile.h + QuRT profiling support. + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup profiling_macros +@{ */ +#define QURT_PROFILE_DISABLE 0 /**< Disable profiling. */ +#define QURT_PROFILE_ENABLE 1 /**< Enable profiling. */ + +typedef unsigned int qurt_profile_param_t; + +#define QURT_PROFILE_PARAM_THREAD_READY_TIME 0U /**< Profile thread ready time. */ + +/** @} */ /* end_addtogroup profiling_macros */ + +/** @addtogroup profiling_types + @{ */ +/** Profiling results. */ +typedef union +{ + /** Result associated with #QURT_PROFILE_PARAM_THREAD_READY_TIME. */ + struct + { + unsigned int ticks; /**< Cumulative ticks the thread was ready. */ + } thread_ready_time; + +} qurt_profile_result_t; +/** @} */ /* end_addtogroup profiling_types */ + +/**@ingroup func_qurt_profile_enable2 + * Starts profiling of a specific parameter on a specific thread (as applicable). + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of the thread (if applicable) for which the specified + * paramter must be profiled. + * @param[in] enable #QURT_PROFILE_DISABLE -- disable \n #QURT_PROFILE_ENABLE -- + * enable + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EALREADY -- Measurement already in progress or already stopped \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_enable2 ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + int enable +); + +/**@ingroup func_qurt_profile_get + * Gets the value of the profiling parameter that was previously enabled. + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of thread (if applicable) for which the specified + * profiling paramter must be retrieved. + * @param [out] result Profiling result associated with the parameter for the specified + * thread (if applicable). + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EFAILED -- Operation failed; profiling was not enabled \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_get ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + qurt_profile_result_t * result +); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ptrace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ptrace.h new file mode 100755 index 0000000000000..622304dd92865 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_ptrace.h @@ -0,0 +1,37 @@ +/*============================================================================= + + qurt_ptrace.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SYS_PTRACE_H__ +#define __SYS_PTRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum __ptrace_request +{ + /** + Indicates that the process making this request is requesting to be traced. + */ + PTRACE_TRACEME = 0, + PTRACE_EXT_IS_DEBUG_PERMITTED = 500 +}; + +long ptrace(enum __ptrace_request request, unsigned int pid, void*addr, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_PTRACE_H__ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi.h new file mode 100755 index 0000000000000..705408e5cfc6f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi.h @@ -0,0 +1,185 @@ +#ifndef QDI_H +#define QDI_H + +/** + @file qurt_qdi.h + @brief Prototypes of QuRT Driver Invocation API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_qdi_open + Opens the specified driver for subsequent operations. + qurt_qdi_open() is the primary mechanism by which a driver user can + obtain a QDI handle. The user provides the name of the driver to the + qurt_qdi_open call, and gets back a handle referencing + the named driver. \n + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_open function prototype is not actually defined as a varargs. + + + @param[in] p Driver name. + @param[in] ... Up to nine additional device-specific arguments can be passed as parameters, + and should follow the POSIX open() convention. \n + - flags -- Optional second parameter (POSIX flags), the handle + access requested (read-only, write-only, or read-write, + for instance) and other flags such as whether the call + should create a new device or only open an existing + device. \n + - mode -- Optional third parameter (POSIX mode); permissions to + configure when a new device is created. @tablebulletend + + @return + Negative value -- Error. \n + Non-negative value -- Success, this result value serves as a handle to the + opened driver. + @dependencies + None. + */ +// int qurt_qdi_open(); +#define qurt_qdi_open(p,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN,(p),##__VA_ARGS__) + +#define qurt_qdi_open_dt(p,q,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN_FROM_DT,(p),(q),##__VA_ARGS__) + +/**@ingroup func_qurt_qdi_handle_invoke + Performs a generic driver operation, which (depending on the specified operation) can be + either be one of the predefined operations listed in @xhyperref{tbl:functionMapping,QDI function mapping} + or a driver-specific operation. + The user provides a QDI handle and an integer + method number, along with 0 to 8 optional 32-bit arguments. + The device driver invocation function is invoked with the + same method number and 0 to 8 optional arguments. The + return value from the invocation function is passed back to + the user as the return value of qurt_qdi_handle_invoke. + + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_handle_invoke() function prototype is not actually defined as a + varargs function (and would break if it were defined this way). + + @param[in] h Driver handle. + @param[in] m Integer number for the operation to perform. + @param[in] ... Up to eight optional arguments can be passed to the device driver as operation-specific parameters: \n + arg1 -- First parameter \n + arg2 -- Second parameter \n + arg3 -- Third parameter \n + arg4 -- Fourth parameter \n + arg5 -- Fifth parameter \n + arg6 -- Sixth parameter \n + arg7 -- Seventh parameter \n + arg8 -- Eighth parameter + + @return + Integer value defined by the device driver. \n + -1 -- Error. + + @dependencies + None. + */ +// int qurt_qdi_handle_invoke(); +#define qurt_qdi_handle_invoke(h,m,...) \ + _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__) +#define _QDMHI3(a,b,c) qurt_qdi_qhi3(0,b,c) +#define _QDMHI4(a,b,c,d) qurt_qdi_qhi4(0,b,c,(int)(d)) +#define _QDMHI5(a,b,c,d,e) qurt_qdi_qhi5(0,b,c,(int)(d),(int)(e)) +#define _QDMHI6(a,b,c,d,e,f) qurt_qdi_qhi6(0,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMHI7(a,b,c,d,e,f,g) qurt_qdi_qhi7(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMHI8(a,b,c,d,e,f,g,h) qurt_qdi_qhi8(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMHI9(a,b,c,d,e,f,g,h,i) qurt_qdi_qhi9(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMHI10(a,b,c,d,e,f,g,h,i,j) qurt_qdi_qhi10(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMHI11(a,b,c,d,e,f,g,h,i,j,k) qurt_qdi_qhi11(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMHI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_qdi_qhi12(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) +int qurt_qdi_qhi3(int,int,int); +int qurt_qdi_qhi4(int,int,int,int); +int qurt_qdi_qhi5(int,int,int,int,int); +int qurt_qdi_qhi6(int,int,int,int,int,int); +int qurt_qdi_qhi7(int,int,int,int,int,int,int); +int qurt_qdi_qhi8(int,int,int,int,int,int,int,int); +int qurt_qdi_qhi9(int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi10(int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi11(int,int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi12(int,int,int,int,int,int,int,int,int,int,int,int); + +/**@ingroup func_qurt_qdi_write + Writes data to the specified driver. + A predefined invocation routine for drivers that + support a POSIX-like write functionality. + qqurt_qdi_write(handle, buf, len) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_WRITE, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data to write is stored. + @param[in] len Number of bytes of data to write. + + @return + Non-negative integer -- Number of bytes written. \n + Negative error code -- Write could not take place. + + @dependencies + None. + */ +int qurt_qdi_write(int handle, const void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_read + User-visible API to read data from a QDI handle. + A predefined invocation routine for drivers that + support a POSIX-like read functionality. + qurt_qdi_read(handle, buf, len) is equivalent to: + qurt_qdi_handle_invoke(handle, QDI_READ, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data read is stored. + @param[in] len Number of bytes of data to read. + + @return + Non-negative integer number -- Bytes read. \n + Negative error code -- Read could not take place. + + @dependencies + None. + */ +int qurt_qdi_read(int handle, void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_close + Closes the specified driver, releasing any resources associated with the open driver. + User-visible API to close a QDI handle. + + This API should be called when the user is done using a + QDI-based handle. When this function is called, the driver can release + any resources held and perform other necessary cleanup + operations. qurt_qdi_close(handle) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_CLOSE, handle) + + @param[in] handle Driver handle. + + @return + 0 -- Success.\n + Negative error code -- Failure. + + @dependencies + None. + */ +int qurt_qdi_close(int handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_constants.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_constants.h new file mode 100755 index 0000000000000..4866fada067f0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_constants.h @@ -0,0 +1,193 @@ +#ifndef QDI_CONSTANTS_H +#define QDI_CONSTANTS_H + +/** + @file qurt_qdi_constants.h + @brief Predefined invocation methods for drivers. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Method numbers used for QDI. +|| +|| Intended grouping of method numbers for QDI +|| including future usage: +|| +|| Method 0 should always be unused and not responded to by +|| any driver. +|| Methods 1 and 2 are reserved for name registration and +|| name lookup. +|| Methods 3 through 31 are reserved for POSIX-type operations +|| on open handles. +|| Methods 32 through 127 are reserved for the QDI infrastructure +|| and may be extended in the future to provide standard +|| driver debug services, management services, and system +|| notifications. +|| Methods 128 through 255 are reserved for the use of automatically +|| generated methods such as might be generated by an IDL (interface +|| definition language). The infrastructure may be extended to +|| perform services on these methods based on information provided +|| by the IDL, such as automatic buffer validation, etc. These +|| method numbers should not be used for any "ad hoc" methods. +|| Methods with number >= 256 are "private" method numbers that are +|| outside the scope of the QDI infrastructure. Drivers that want +|| to generate and consume their own "ad hoc" methods are free to +|| use these method numbers as they wish. The infrastructure does +|| not generate these method numbers or respond to them, but +|| passes them on unmolested. +|| +|| All driver implementations *should* return a value of +|| -1 when called with an unsupported method. The standard error +|| return value for POSIX APIs is -1, so we emulate that behavior +|| here. +*/ +/** @cond */ +#define QDI_UNUSED 0 +#define QDI_DEVNAME_REGISTER 1 +#define QDI_OPEN 2 +#define QDI_CLOSE 3 +#define QDI_READ 4 +#define QDI_WRITE 5 +#define QDI_IOCTL 6 +#define QDI_MMAP 7 +#define QDI_OS_FILEOPEN 8 +#define QDI_FLEN 9 +#define QDI_UNLINK 10 +#define QDI_FTELL 22 +#define QDI_SEEK 23 +#define QDI_FSTAT 24 + +#define QDI_FSNAME_REGISTER 150 +#define QDI_FS_OPEN 151 +#define QDI_MMAP2 153 +#define QDI_MPROTECT2 154 +#define QDI_MUNMAP2 155 + +#define QDI_CLIENT_HANDLE_OBJREF_GET 10 + +#define QDI_OS_PROCESS_LOAD 12 +#define QDI_OS_PROCESS_CHOOSE_ASID 13 + +#define QDI_OS_SET_GP 26 +#define QDI_CLIENT_HANDLE_CALLBACK 27 + +#define QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T 19 //reused +#define QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T 80 +#define QDI_CLIENT_HANDLE_HANDLE_RELEASE 81 +#define QDI_CLIENT_HANDLE_COPY_FROM_USER 82 +#define QDI_CLIENT_HANDLE_COPY_TO_USER 83 +#define QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE 86 +#define QDI_CLIENT_HANDLE_SAFE_CACHE_OPS 87 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK 41 +#define QDI_CLIENT_HLOSPOOL_INFO_GET 90 +#define QDI_CLIENT_HLOSPOOL2_INFO_GET 96 + +#define QDI_CLIENT_PID 44 +#define QDI_CLIENT_ASID QDI_CLIENT_PID + +#define QDI_OS_CLIENT_INFO_GET 48 + +#define QDI_OS_MEM_LOOKUP_PHYSADDR 57 + +#define QDI_OS_THREAD_ITERATOR_CREATE 68 +#define QDI_OS_THREAD_ITERATOR_NEXT 69 + +#define QDI_OS_SYSENV 78 + +#define QDI_REGION_USERMALLOC_INIT 180 // This method is for generic handle + + +#define QDI_CLIENT_HANDLE_USER_MALLOC 84 +#define QDI_CLIENT_HANDLE_USER_FREE 85 + +#define QDI_SIGNAL_GROUP_SIGNAL_CREATE 96 +#define QDI_SIGNAL_GROUP_WAIT 98 +#define QDI_SIGNAL_GROUP_POLL 99 +#define QDI_SIGNAL_SET 96 +#define QDI_SIGNAL_CLEAR 97 +#define QDI_SIGNAL_WAIT 98 +#define QDI_SIGNAL_POLL 99 + +#define QDI_OS_WAIT_FOR_MAIN_REAPER 104 + +#define QDI_CLIENT_HANDLE_REFPROXY_INSTALL 105 +#define QDI_CLIENT_HANDLE_REFPROXY_ADD 106 +#define QDI_CLIENT_HANDLE_REFPROXY_REMOVE 107 + +#define QDI_CLIENT_HANDLE_DETACH 116 + +#define QDI_OS_RESERVED1 139 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK2 142 + +#define QDI_DT_REGISTER 158 +#define QDI_OPEN_DEVICE 159 +#define QDI_OPEN_FROM_DT 160 + +#define QDI_PRIVATE 256 /* Method numbers beginning at 256 + are private method numbers, which + are device-specific and available + for use by device implementors. */ +/* +|| Permission bitmasks for use with qurt_qdi_lock_buffer(). +|| +|| Make sure these match with permission values from qurt_perm_t. +*/ +/** @endcond */ + +/** @addtogroup driver_support_constants +@{ */ +#define QDI_PERM_W 2 /**< Write access. */ +#define QDI_PERM_R 1 /**< Read access. */ +#define QDI_PERM_RW (QDI_PERM_R | QDI_PERM_W) /**< Read/write access. */ + +#define QDI_HANDLE_LOCAL_CLIENT 3 /**< Local client. */ +#define QDI_HANDLE_GENERIC 4 /**< Generic. */ + +#define QDI_REFCNT_BASE 0x510000 /**< */ +#define QDI_REFCNT_MAXED 0x51FFFD /**< */ +#define QDI_REFCNT_INIT 0x51FFFE /**< Driver object is temporary and is eventually deleted.*/ +#define QDI_REFCNT_PERM 0x51FFFF /**< Driver object is permanent and is never deleted. */ +/** @} */ /* end_addtogroup driver_support_constants */ + +/** @cond */ +/* +|| Flags used by process loaders. +*/ + +#define QDI_OS_PROCESS_FLAGS_ISLAND_RESIDENT 0x1 /* Set this flag to request the loaded process + to have island residency. */ +#define QDI_OS_PROCESS_FLAGS_ROOT_RESIDENT 0x2 /* Set this flag to request the loaded process + to have root residency, for example, DL Pager. */ +/* +|| Constants used for qurt_event register API, type field. +*/ + +#define QURT_PROCESS_EXIT 1 + +/* +|| Constants used by QDI extensions. +*/ + +#define QURT_QDI_SINGLETON_TYPE_TRUE 0 +#define QURT_QDI_SINGLETON_TYPE_FALSE 1 +#define QURT_QDI_SINGLETON_TYPE_PER_PROCESS 2 +/** @endcond */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QDI_CONSTANTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_driver.h new file mode 100755 index 0000000000000..e044e25f1bb72 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_driver.h @@ -0,0 +1,868 @@ +#ifndef QURT_QDI_DRIVER_H +#define QURT_QDI_DRIVER_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2018, 2019-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "stddef.h" +#include "qurt_qdi.h" +#include "qurt_types.h" +#include "qurt_callback.h" +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" +#include "qurt_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| This gives the canonical form for the arguments to a QDI +|| driver invocation function. The arguments are as follows: +|| +|| int client_handle (R0) QDI handle that represents the client +|| that made this QDI request. If the +|| client is remote, this is a +|| variable handle; if the client is local +|| (same thread and process), this is +|| set to QDI_HANDLE_LOCAL_CLIENT. +|| +|| qurt_qdi_obj_t *obj (R1) Points at the qdi_object_t structure +|| on which this QDI request is being made. +|| The qdi_object_t structure is usually +|| the first element of a larger structure +|| that contains state associated with the +|| object; because it is usually the first +|| element, the object pointers can be freely +|| interchanged through casts. +|| +|| int method (R2) Integer QDI method that represents +|| the request type. +|| +|| qurt_qdi_arg_t arg1 (R3) First three general purpose arguments +|| qurt_qdi_arg_t arg2 (R4) to the invocation function are passed in +|| qurt_qdi_arg_t arg3 (R5) these slots. +|| +|| qurt_qdi_arg_t arg4 (SP+0) Arguments beyond the first three are +|| qurt_qdi_arg_t arg5 (SP+4) passed on the stack. +|| qurt_qdi_arg_t arg6 (SP+8) +|| qurt_qdi_arg_t arg7 (SP+12) +|| qurt_qdi_arg_t arg8 (SP+16) +|| qurt_qdi_arg_t arg9 (SP+20) +|| +|| The canonical form of the invocation function takes a +|| total of 12 arguments, but not all of them are used. In general, +|| the QDI infrastructure only passes those arguments provided by +|| the caller; if the invocation function accesses additional +|| arguments beyond those provided by the caller, the values are not +|| useful. +*/ +/** @cond */ +#define QDI_INVOKE_ARGS \ + int, struct qdiobj *, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define QDI_EXT_INVOKE_ARGS \ + int, qurt_qdi_man_obj_t*, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define BUFFER_LOCK 1 +#define BUFFER_UNLOCK 0 + +struct qdiobj; +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef union { + void *ptr; /**< Pointer to the driver handle. */ + int num; /**< Method number. */ +} qurt_qdi_arg_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI driver version */ +typedef union { + int num; + struct { + short major; /** Driver major version number. */ + short minor; /** Driver minor version number. */ + }; +} qurt_qdi_version_t; + +typedef int (*qurt_qdi_pfn_invoke_t)(QDI_INVOKE_ARGS); +typedef void (*qurt_qdi_pfn_release_t)(struct qdiobj *); +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef struct qdiobj { + qurt_qdi_pfn_invoke_t invoke; /**< Invocation function that implements the driver methods.*/ + int refcnt; /**< Reference count, an integer value maintained by the QDI infrastructure that tracks the number of + references to a driver instance. */ + qurt_qdi_pfn_release_t release; /**< Release function that performs details associated with deleting an instance + of the driver object.*/ +} qurt_qdi_obj_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI managed object */ +typedef struct qurt_qdi_man_obj +{ + qurt_qdi_obj_t qdi_obj; + union + { + struct qurt_qdi_ext_driver * opener_obj; + struct qurt_qdi_ext_device * device_obj; + }; +}qurt_qdi_man_obj_t; + +typedef int (*qurt_qdi_ext_pfn_create_t)(int client_id, const char *name, qurt_qdi_version_t version, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_create_device_t)(int client_id, const char *name, qurt_qdi_version_t version, struct qurt_qdi_ext_device * device, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_invoke_t)(QDI_EXT_INVOKE_ARGS); +typedef void (*qurt_qdi_ext_pfn_destroy_t)(qurt_qdi_man_obj_t *qdi_obj); +typedef int (*qurt_qdi_ext_pfn_probe_t)(void *handle, struct qurt_qdi_ext_device **device); + +typedef struct qurt_qdi_ext_obj_info{ + qurt_qdi_man_obj_t *obj; + int qdi_client_id; + struct qurt_qdi_ext_obj_info *next; +}qurt_qdi_ext_obj_info_t; +typedef struct qurt_qdi_ext_obj_info *qurt_qdi_ext_obj_info_ptr; + +/** QuRT QDI device */ +//temporarily add this back while there are still drivers who statically define this structure +struct qurt_qdi_device { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; +}; +typedef struct qurt_qdi_device qurt_qdi_man_device; + +struct qurt_qdi_ext_driver { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + qurt_qdi_ext_pfn_create_device_t create_device; + qurt_qdi_version_t version; + qurt_qdi_ext_pfn_probe_t probe; + const char* compatible; + struct qurt_qdi_ext_device * device_list; + //qurt_qdi_ext_device_ptr device_list; +}; +typedef struct qurt_qdi_ext_driver qurt_qdi_ext_driver_t; +//above replaces qurt_qdi_man_device + +extern int qurt_qdi_obj_ref_inc(qurt_qdi_obj_t *); +extern int qurt_qdi_obj_ref_dec(qurt_qdi_obj_t *); + +extern int qurt_qdi_ext_opener (QDI_INVOKE_ARGS); +/** @endcond */ +/**@ingroup func_qurt_qdi_method_default + Processes a method that is unrecognized or unsupported in the driver invocation function. + All arguments passed to the current invocation function (Section @xref{sec:invocationFunction}) must be forwarded + to this function. + + @note1hang Invocation functions must process all unrecognized or unsupported methods + by calling this function. + + @return + None. + + @dependencies + None. +*/ +extern int qurt_qdi_method_default(QDI_INVOKE_ARGS); + +/**@ingroup func_qurt_qdi_handle_create_from_obj_t + Allocates a new device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[out] obj Pointer to the driver object. + + @return + Non-negative integer -- Success; this value is the new handle. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_invoke + Allocates a new island device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). + @param[in] obj Pointer. + + @return + Non-negative integer value that is the new handle -- Success. \n + Negative return value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_island_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_release + Deallocates the specified device handle. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] handle_to_release Handle to release. + + @return + 0 -- Success. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_release(int client_handle, int handle_to_release) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_RELEASE, + handle_to_release); +} + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_handle(int client_handle, int object_handle) +{ + qurt_qdi_obj_t *ret; + + ret = NULL; + + qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_OBJREF_GET, + object_handle, + &ret); + + return ret; +} + +/**@ingroup func_qurt_client_add_memory + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory(int client_handle, qurt_addr_t phys_addr, qurt_size_t size); + +/**@ingroup func_qurt_client_add_memory2 + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting 36-bit address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory2(int user_client_handle, qurt_paddr_64_t phys_addr, qurt_size_t size); + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_pointer(qurt_qdi_obj_t *objptr) +{ + qurt_qdi_obj_t * ret = NULL; + + if (qurt_qdi_obj_ref_inc(objptr) < 0) { + ret = NULL; + } else { + ret = objptr; + } + + return ret; +} + +static __inline void +qurt_qdi_objref_release(qurt_qdi_obj_t *objptr) +{ + if (qurt_qdi_obj_ref_dec(objptr) == 1) { + (*objptr->release)(objptr); + } +} + +/**@ingroup func_qurt_qdi_copy_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the driver buffer. + @param[in] src Base address of the user buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_from_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_FROM_USER, + dest, src, len); +} + +/**@ingroup qurt_qdi_copy_string_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param dest Base address of the driver buffer. + @param src Base address of the user buffer. + @param len Number of bytes to copy. NOTE: This is the destination buffer length. + + @return + Negative error result -- privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +int qurt_qdi_copy_string_from_user(int client_handle, char *dest, const char *src, unsigned len); + +/**@ingroup func_qurt_qdi_copy_to_user + Copies the contents of a driver memory buffer to user memory. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the user buffer. + @param[in] src Base address of the driver buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_to_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_TO_USER, + dest, src, len); +} + +/**@ingroup func_qurt_qdi_safe_cache_ops + Do cache operations on user memory + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] addr Base address of the user memory. + @param[in] size Size of the user memory. + @param[in] opcode Cache operations (QURT_MEM_CACHE_FLUSH, QURT_MEM_CACHE_INVALIDATE...) + @param[in] type Cache type (QURT_MEM_ICACHE, QURT_MEM_DCACHE) + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_safe_cache_ops(int client_handle, qurt_addr_t addr, qurt_size_t size, + qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SAFE_CACHE_OPS, + addr, size, opcode, type); +} + + +/**@ingroup func_qurt_qdi_buffer_lock + Prepares for the direct manipulation of a potentially untrusted buffer provided by a QDI + client. + + This function is used to permit a trusted driver to safely access memory that is + provided by a potentially untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + + This function performs the following security checks: \n + - Verifies that the entire buffer is accessible to the client. \n + - Ensures that the pointer remains valid for the remainder of the QDI driver + operation. \n + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] buf Pointer to the base address of the client buffer address. + @param[in] len Buffer length (in bytes). + @param[in] perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + - #QDI_PERM_R -- Read access \n + - #QDI_PERM_W -- Write access \n + - #QDI_PERM_RW -- Read/write access @tablebulletend + @param[out] obuf Pointer to the buffer address that the driver must use to access the buffer. + + @return + Negative value -- Error; the operation crosses a privilege boundary, indicating a privilege or security violation. \n + Nonzero value -- User passed a buffer that does not fulfill the requested read/write access permission. + In this case the QDI driver call must be terminated cleanly, with an appropriate error code + returned to the client. \n + Zero -- Success; when this occurs the QDI driver must use the pointer at *obuf to access memory, and not the + pointer passed in as buf -- even if the user process changes the mapping of memory at buf, + the mapping of memory at *obuf remains valid until the driver invocation completes. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK, + buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_lock2 + Prepares for the direct manipulation of a possibly-untrusted buffer provided by a QDI + client. + This API permits a trusted driver to safely access memory + provided by a possibly-untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + This function performs the following security checks: \n + -- Entire buffer is accessible to the client. \n + -- Entire buffer is mapped with permissions passed in perms field \n + -- Entire buffer is physically contiguous \n + In addition to the security checks, the API also locks the client mapping such that the client + cannot remove the mapping while the physical memory is used by the trusted + driver. \n + + @note1 Drivers are responsible for calling qurt_qdi_buffer_unlock() at appropriate time. Not + pairing qurt_qdi_buffer_unlock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client. If the client exits abruptly, the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Safe buffer + unmapping or user buffer unlock is not supported in Island mode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + -- #QDI_PERM_R -- Read access \n + -- #QDI_PERM_W -- Write access \n + -- #QDI_PERM_RW -- Read/write access \n + @param obuf Optional parameter that returns a pointer to the buffer address that + the driver must use to access the buffer. If NULL is passed, the API + only performs security checks and does not create a mapping to access the user buffer in + a safe way. + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EPRIVILEGE -- One of the security checks on the user buffer failed. \n + QURT_EFAILED -- Mapping cannot be created for the trusted driver. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock2(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_LOCK, buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_unlock + This API is paired with qurt_qdi_buffer_lock2(). A temporary overlapping mapping + created for the driver is removed. Client mapping for the user buffer is + unlocked. + + @note1 Drivers are responsible for pairing this with qurt_qdi_buffer_lock(). Not + pairing qurt_qdi_buffer_lock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client, and if the client exits abruptly, all the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Actual + unmapping of driver accessible memory or unlocking of the buffer is not + supported in Island bode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param obuf Safe buffer address that was returned in the obuf field after calling + qurt_qdi_buffer_lock2(). + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. \n + other results -- Safe buffer unmapping failed or unlocking of user buffer failed \n. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_unlock(int client_handle, void *buf, unsigned len, + void *obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_UNLOCK, buf, len, obuf); +} + +/**@ingroup func_qurt_qdi_user_malloc + Allocates memory area in the QDI heap that is read/write accessible to both the driver and + the client. \n + @note1hang The QDI heap has a limited amount of memory available, and only the + device driver can free the allocated memory. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param size Size. + + @return + Non-zero -- Success; this returned value points to the allocated memory area. \n + Zero -- Error. + + @dependencies + None. +*/ +void *qurt_qdi_user_malloc(int client_handle, unsigned size); + +/**@ingroup func_qurt_qdi_user_free + Deallocates memory area in the QDI heap. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param ptr Pointer. + + @dependencies + None. +*/ +void qurt_qdi_user_free(int client_handle, void *ptr); + +/**@ingroup funct_qurt_qdi_client_detach + Detaches a client (a process), indicating that the client does not + participate in the qurt_wait() mechanism. This behavior + is opt-in and irrevocable. When a client is detached, it can + not be un-detached. + + @param client_handle Handle of the client to detach. + + @return + Zero -- Success. Detachable clients always return success. + Nonzero value -- client_handle did not refer to a + detachable user client. + + @dependencies + None. +*/ +static __inline int qurt_qdi_client_detach(int client_handle) +{ + return qurt_qdi_handle_invoke(client_handle, QDI_CLIENT_HANDLE_DETACH); +} + +/**@ingroup func_qurt_qdi_signal_group_create + Creates a new signal group for use in a device driver. + A QDI signal group contains up to 32 signals, which can be operated on either + individually (using the qurt_qdi_signal_* functions) or as a group (using the + qurt_qdi_signal_group_* functions). \n + @note1hang Driver implementation is responsible for using the proper signal group + handle in any given situation. \n + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param p_signal_group_handle_local Returns a handle intended for use by code that + resides in the same context and process as the created signal group + (for example, the device driver implementation that allocated the + signal group). + @param p_signal_group_handle_remote Returns a handle intended for use by code + that resides in a different context and process than the created signal group + (for example, the user-mode client of an OS driver). + + @return + Zero return value indicates success.\n + Negative return value indicates could not create signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_create(int client_handle, + int *p_signal_group_handle_local, + int *p_signal_group_handle_remote) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE, + p_signal_group_handle_local, + p_signal_group_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_group_wait + Suspends the current thread until any of the signals are set in the specified signal group. + + If a signal is set in a signal group object, and a thread waits on the signal group object, + the thread is awakened. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @param signal_group_handle Handle of the signal group. + + @return + If the client is remote: + QURT_EOK -- Wait complete \n + QURT_ECANCEL -- Wait cancelled.\n + If the client is local, returns a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_wait(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_group_poll + Returns a value that indicates if any of the signals are set in the specified signal group. + + @param signal_group_handle Handle of the signal group. + + @return + 1 -- Indicates whether any of the signals are set in the signal group.\n + 0 -- Indicates that none of the signals are set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_poll(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_POLL); +} + + +/**@ingroup func_qurt_qdi_signal_create + Creates a new signal in the specified signal group. + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @note1hang Driver implementation is responsible for using the proper signal handle in + any given situation. + + @param signal_group_handle Handle of an existing signal group. + @param p_signal_handle_local Returns a handle intended for use by code that resides in + the same context and process as the created signal (for example, + the device driver implementation that allocated the signal). + @param p_signal_handle_remote Returns a handle intended for use by code that resides in + a different context and process than the created signal (for + example, the user-mode client of an OS driver). + + @return + Nonzero value -- No more signals can be created in the specified + signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_create(int signal_group_handle, + int *p_signal_handle_local, + int *p_signal_handle_remote) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_SIGNAL_CREATE, + p_signal_handle_local, + p_signal_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_set + Sets the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_set(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_SET); +} + +/**@ingroup func_qurt_qdi_signal_clear + Clears the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_clear(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_CLEAR); +} + +/**@ingroup func_qurt_qdi_signal_wait + Suspends the current thread until the specified signal is set. + If a signal is set in a signal object, and a thread waits on the signal object, the + thread is awakened. If the awakened thread has higher priority than the current thread, a + context switch may occur. + + @param signal_handle Handle of the signal. + + @return + If client is remote: + QURT_EOK -- Wait complete. \n + QURT_ECANCEL -- Wait cancelled.\n + If client is local, return a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_wait(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_poll + Returns a value that indicates if the specified signal is set. + + @param signal_handle Handle of the signal. + + @return + 1 -- Signal is set. \n + 0 -- Signal is not set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_poll(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_POLL); +} + +/**@ingroup func_qurt_qdi_devname_register + Registers a QDI device with the generic QDI object in the + current QDI context. + + This function registers an exact name or a directory prefix with a QDI opener object. + Future invocations of qurt_qdi_open() in the context of the caller invokes the + opener object if a match is detected. + + Directory prefix names are specified by ending the name with a forward slash character. + + Example of an exact name: + @code qurt_qdi_devname_register(/dev/foobar, foobar_opener);@endcode + + Example of a directory prefix: + @code qurt_qdi_devname_register(/pipedev/, pipedev_opener);@endcode + + Given the two registrations shown above, the only qurt_qdi_open() requests to + direct to the foobar_opener object are requests for the exact name + "/dev/foobar", Any request beginning with "/pipedev/" is directed to the + pipedev_opener object. + + The pipedev invocation function presumably examines the name argument to + determine exactly how to handle the request. The name is passed to the invocation + function in the a1.ptr argument (Section @xref{sec:invocationFunction}). + + @param name Device name or device name prefix. + @param opener Pointer to the opener object for the device. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. + + @dependencies + None. + */ +static __inline int qurt_qdi_devname_register(const char *name, + qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, + QDI_DEVNAME_REGISTER, + name, + opener); +} + +// Macros for backward compatibility with deprecated APIs +// (These will go away soon) + +#define qurt_qdi_register_devname(name, opener) \ + qurt_qdi_devname_register((name), (void *)(opener)) +#define qurt_qdi_new_handle_from_obj_t(handle, obj) \ + qurt_qdi_handle_create_from_obj_t((handle), (obj)) +#define qurt_qdi_release_handle(client_handle, handle) \ + qurt_qdi_handle_release((client_handle), (handle)) +#define qurt_qdi_lock_buffer(handle, buf, len, perms, obuf) \ + qurt_qdi_buffer_lock((handle), (buf), (len), (perms), (obuf)) +#define qurt_qdi_usermalloc(handle, size) \ + qurt_qdi_user_malloc((handle), (size)) +#define qurt_qdi_userfree(handle, ptr) \ + qurt_qdi_user_free((handle), (ptr)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_ext.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_ext.h new file mode 100755 index 0000000000000..383e1799a15d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_ext.h @@ -0,0 +1,58 @@ +#ifndef QURT_QDI_EXT_H +#define QURT_QDI_EXT_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018, 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct qurt_qdi_ext_device { + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + struct qurt_qdi_ext_device * next; + char * instance; + fdt_node_handle context; +}; +typedef struct qurt_qdi_ext_device *qurt_qdi_ext_device_ptr; + +/**@ingroup func_qurt_qdi_dt_register + Registers a QDI device with the generic QDI object in the current QDI context, + if and only if a compatible device node is found in the device tree. This + function serves as a device tree aware wrapper for qurt_qdi_devname_register(). + + @param name Device name or device name prefix. + @param opener Pointer to QDI ext specialized opener object for the driver. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. +*/ +static __inline int qurt_qdi_dt_register(const char *name, qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_DT_REGISTER, name, opener); +} + +static inline void qurt_qdi_ext_deviceobj_set_name (struct qurt_qdi_ext_device * device, char * name) +{ + device->instance = name; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_imacros.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_imacros.h new file mode 100755 index 0000000000000..c0a8448ac87f8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_imacros.h @@ -0,0 +1,34 @@ +#ifndef QURT_QDI_IMACROS_H +#define QURT_QDI_IMACROS_H + +/** + @file qurt_qdi_imacros.h + @brief Internal macros used for QDI. Mostly consists of tricky (and ugly) + preprocessor hacks that permit us to do varargs function invocations + where we pass optional arguments in registers and where we can do + type casting and checking automatically. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _QDMPASTE(a,b) _QDMPASTE_(a,b) +#define _QDMPASTE_(a,b) a##b +#define _QDMCNT(...) _QDMCNT_(__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _QDMCNT_(a,b,c,d,e,f,g,h,i,j,k,l,cnt,...) cnt + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_proxy.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_proxy.h new file mode 100755 index 0000000000000..f1d8992ea8811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_qdi_proxy.h @@ -0,0 +1,55 @@ +/*============================================================================= + + qurt_qdi_proxy.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef _QURT_QDI_PROXY_H +#define _QURT_QDI_PROXY_H + +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* APIs allowing operation on the proxy object directly */ +int qurt_qdi_proxy_ref_create(void); + +/* APIs allowing to operate on proxy given a known proxy handle + * 1) using qdi handle of the object + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_handle(int proxy_handle, int qdi_handle); +int qurt_qdi_proxy_ref_sub_by_handle(int proxy_handle, int qdi_handle); + +/* 2) using object reference + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); +int qurt_qdi_proxy_ref_sub_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); + +/* API allowing to associate a proxy object with a particular client given a client handle + * successfule return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_install (int client_handle, int proxy_handle); + +/* APIs allowing operation on proxy object from user client + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_add(int qdi_handle); +int qurt_client_proxy_ref_remove(int qdi_handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_QDI_PROXY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex.h new file mode 100755 index 0000000000000..a013a0bbddb1d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_RMUTEX_H +#define QURT_RMUTEX_H +/** + @file qurt_rmutex.h + Prototypes of rmutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013 - 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_rmutex_init + Initializes a recursive mutex object. + The recursive mutex is initialized in unlocked state. + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_destroy + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex protects, and continues executing. + + If a thread performs a lock operation on a mutex that is already use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock_timed + Locks the specified recursive mutex. The wait must be terminated when the specified timeout expires.\n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex is protecting, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked by itself. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + If timeout expires, this wait must be terminated and no access to the mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + + */ +int qurt_rmutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + +/**@ingroup func_qurt_rmutex_unlock + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a mutex. When the mutex is + unlocked, the thread waiting on the mutex awakens. If the awakened + thread has higher priority than the current thread, a context switch occurs. + + @note1hang When a thread unlocks a recursive mutex, the mutex is not available until + the balanced number of locks and unlocks has been performed on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock + Attempts to lock the specified recursive mutex.\n + + If a thread performs a try_lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing.\n + If a thread performs a try_lock operation on a recursive mutex that another thread has + already locked, qurt_rmutex_try_lock immediately returns with a nonzero result + value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex_try_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock_block_once + Attempts to lock a mutex object recursively. If the mutex is available, + it locks the mutex. If the mutex is held by the current thread, + it increases the internal counter and returns 0. If not, it returns a + nonzero value. + If the mutex is already locked by another thread, the caller thread is + suspended. When the mutex becomes available again (because the other + thread has unlocked it), the caller thread is awakened and tries to lock + the mutex; and if it fails, this function returns failure with a nonzero + value. If it succeeds, this function returns success with zero. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the qurt_mutex_t object. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_rmutex_try_lock_block_once(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex2.h new file mode 100755 index 0000000000000..a37e7e4458c4b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_rmutex2.h @@ -0,0 +1,183 @@ +#ifndef QURT_RMUTEX2_H +#define QURT_RMUTEX2_H +/** + @file qurt_rmutex2.h + @brief Prototypes of rmutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT rmutex2 type. + Mutex type used with rmutex2 APIs. + */ +typedef struct { + /** @cond */ + unsigned int holder __attribute__((aligned(8))); /* UGP value of the mutex holder. */ + unsigned short waiters; /* Number of waiting threads. */ + unsigned short refs; /* Number of references to this mutex. */ + unsigned int queue; /* Kernel-maintained futex queuevalue. */ + unsigned int excess_locks; /* Number of excess times the holder has locked the mutex. */ + /** @endcond */ +} qurt_rmutex2_t; +/** @} */ /* end_addtogroup mutex_types */ +/** @cond internal_only*/ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_rmutex2_init + + @deprecated use #qurt_rmutex_init instead. + + Initializes a recursive mutex object. + + The recursive mutex is initially unlocked. + + Objects of type rmutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_destroy + + @deprecated use #qurt_rmutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code must destroy an rmutex2 object prior to + deallocating it; calling qurt_rmutex2_destroy() before deallocating it ensures + that all qurt_rmutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_lock + + @deprecated use #qurt_rmutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that the mutex protects, and continues + to execute. + + If a thread performs a lock operation on a recursive mutex that another thread is using, + the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_unlock + + @deprecated use #qurt_rmutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex awakens. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_rmutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_rmutex2_lock(). When a call to qurt_rmutex2_lock() + succeeds immediately, this function behaves similarly, returning 0 for success. + When a call to qurt_rmutex2_lock() does not succeed immediately, this function has + no effect and returns nonzero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex2_try_lock(qurt_rmutex2_t *lock); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sclk.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sclk.h new file mode 100755 index 0000000000000..a83cf5f1db889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sclk.h @@ -0,0 +1,145 @@ +#ifndef QURT_SCLK_H +#define QURT_SCLK_H +/** + @file qurt_sclk.h + @brief Header file describing the APIs supported by QuRT system SCLK + feature. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + + +/*============================================================================= + + INCLUDE FILES + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + Conversion from microseconds to sleep ticks. + */ +#define QURT_SYSCLOCK_TIMETICK_FROM_US(us) ((us) * 192ULL / 10UL) +#define qurt_sysclock_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_SYSCLOCK_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_SYSCLOCK_MAX_DURATION (1042499uLL * 3600uLL * 1000uLL * 1000uLL) +#define qurt_sysclock_max_duration() QURT_SYSCLOCK_MAX_DURATION +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_SYSCLOCK_MAX_DURATION_TICKS (1042499uLL * 3600uLL * 19200000uLL) +#define qurt_sysclock_max_duration_ticks() QURT_SYSCLOCK_MAX_DURATION_TICKS +/** + Sleep timer error margin for Qtimer is 192 ticks ~10 us. +*/ +#define QURT_SYSCLOCK_ERROR_MARGIN 192U //QURT_TIMER_MIN_DURATION*timer_freq; +#define qurt_sysclock_error_margin() QURT_SYSCLOCK_ERROR_MARGIN + +/*============================================================================= + + DATA DECLARATIONS + +=============================================================================*/ + +/**@ingroup func_qurt_sysclock_get_hw_ticks + @xreflabel{sec:qurt_sysclock_get_hw_ticks} + Gets the hardware tick count.\n + Returns the current value of a 64-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation must be used with care because of the wrap-around behavior. + + @return + Integer -- Current value of 64-bit hardware counter. + + @dependencies + None. + */ +unsigned long long qurt_sysclock_get_hw_ticks (void); + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_32 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_32} + Gets the hardware tick count in 32 bits.\n + Returns the current value of a 32-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 32 bits are the lower 32 bits of the Qtimer counter. + + @return + Integer -- Current value of the 32-bit timer counter. + + @dependencies + None. + */ +static inline unsigned long qurt_sysclock_get_hw_ticks_32 (void) +{ + //Beginning with v61 there is a HW register that can be read directly. + unsigned long count; + __asm__ __volatile__ (" %0 = c30 " : "=r"(count)); + return count; +} + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_16 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_16} + Gets the hardware tick count in 16 bits.\n + Returns the current value of a 16-bit timer counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 16 bits are based on the value of the lower 32 bits in Qtimer + counter, right shifted by 16 bits. + + @return + Integer -- Current value of the 16-bit timer counter, calculated from the lower 32 bits in the + Qtimer counter, right shifted by 16 bits. + + @dependencies + None. + */ + + +static inline unsigned short qurt_sysclock_get_hw_ticks_16 (void) +{ + unsigned long ticks; + + //Beginning with v61 there is a HW register that can be read directly. + __asm__ __volatile__ (" %0 = c30 " : "=r"(ticks)); + __asm__ __volatile__ ( "%0 = lsr(%0, #16) \n" :"+r"(ticks)); + + return (unsigned short)ticks; +} +unsigned long long qurt_timer_timetick_to_us(unsigned long long ticks); +#define qurt_sysclock_timetick_to_us(ticks) qurt_timer_timetick_to_us(ticks) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif /* QURT_SCLK_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_secure_proc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_secure_proc.h new file mode 100755 index 0000000000000..f40c7deb9bca1 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_secure_proc.h @@ -0,0 +1,53 @@ +#ifndef QURT_SECURE_PROC_H +#define QURT_SECURE_PROC_H + +/** + @file qurt_secure_proc.h + @brief Definitions, macros, and prototypes used for handling secure process + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_process_migrate_secure_process + Migrate the user process to Qurt secure process + + @param secure_phy_address Physical starting address of secure memory + @param secure_memory_size Size of secure memory + @param entry Entry function to secure process + + @return + EOK + Negative return value -- Error. + + @dependencies + None. +*/ +int qurt_process_migrate_secure_process(unsigned long long secure_phy_address, unsigned int secure_memory_size, void entry(unsigned)); + +/**@ingroup qurt_process_get_migration_mem_size + get the size of all writable memory regions in a user PD. This is for preparation on secure process migration. + + @return + size of all writable memory regions in a user PD. + + @dependencies + None. +*/ +int qurt_process_get_migration_mem_size(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sem.h new file mode 100755 index 0000000000000..ee5ce4b2d94ab --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_sem.h @@ -0,0 +1,252 @@ +#ifndef QURT_SEM_H +#define QURT_SEM_H +/** + @file qurt_sem.h + Prototypes of semaphore API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup semaphore_types +@{ */ + +/** QuRT semaphore type. */ +typedef union { + /** @cond */ + unsigned int raw[2] __attribute__((aligned(8))); + struct { + unsigned short val; /**< */ + unsigned short n_waiting; /**< */ + unsigned int reserved1; /**< */ + unsigned int queue; /**< */ + unsigned int reserved2; /**< */ + }X; /** @endcond */ +} qurt_sem_t; +/** @} */ /* end_addtogroup semaphore_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_sem_add + Releases access to a shared resource (the specified amount increments the semaphore count value).\n + When a thread performs an add operation on a semaphore, the specified value increments the semaphore count. + The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing. \n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel repeatedly awakens the highest-priority waiting thread and decrements + the semaphore count value until either no waiting threads remain or the + semaphore count value is zero. If any of the awakened threads has higher priority + than the current thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] amt Amount to increment the semaphore count value. + + @return + Unused integer value. + + @dependencies + None. + + */ +int qurt_sem_add(qurt_sem_t *sem, unsigned int amt); + +/**@ingroup func_qurt_sem_up + Releases access to a shared resource. When a thread performs an up operation on a semaphore, + the semaphore count value increments. The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing.\n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel awakens the highest-priority waiting thread and decrements the + semaphore count value. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +static inline int qurt_sem_up(qurt_sem_t *sem) { return qurt_sem_add(sem,1); } + +/**@ingroup func_qurt_sem_down + Requests access to a shared resource. When a thread performs a down operation on a + semaphore, the result depends on the semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +int qurt_sem_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_down_timed + When a thread performs a down operation on a semaphore, the result depends on the + semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. Terminate the wait when the specified timeout expires. + If timeout expires, terminate this wait and grant no access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_sem_down_timed(qurt_sem_t *sem, unsigned long long int duration); + +/**@ingroup func_qurt_sem_try_down + @xreflabel{hdr:qurt_sem_try_down} + Requests access to a shared resource (without suspend). When a thread performs a try down + operation on a semaphore, the result depends on the semaphore count value: \n + - The count value is decremented when it is nonzero. The down operation returns 0 as + the function result, and the thread gains access to the shared resource and is free to + continue executing.\n + - The count value is not decremented when it is zero. The down operation returns -1 + as the function result, and the thread does not gain access to the shared resource + and should not continue executing. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + 0 -- Success. \n + -1 -- Failure. + + @dependencies + None. + + */ +int qurt_sem_try_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init + Initializes a semaphore object. + The default initial value of the semaphore count value is 1. + + @param[out] sem Pointer to the initialized semaphore object. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_destroy + Destroys the specified semaphore.\n + @note1hang Semaphores must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Semaphores must not be destroyed while they are still in use. If this occur, + the behavior of QuRT is undefined. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_sem_destroy(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init_val + Initializes a semaphore object with the specified value. + + @datatypes + #qurt_sem_t + + @param[out] sem Pointer to the initialized semaphore object. + @param[in] val Initial value of the semaphore count value. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init_val(qurt_sem_t *sem, unsigned short val); + +/**@ingroup func_qurt_sem_get_val + Gets the semaphore count value.\n + Returns the current count value of the specified semaphore. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Integer semaphore count value + + @dependencies + None. + */ +static inline unsigned short qurt_sem_get_val(qurt_sem_t *sem ){return sem->X.val;} +int qurt_sem_down_cancellable(qurt_sem_t *sem); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SEM_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_shmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_shmem.h new file mode 100755 index 0000000000000..980557323708a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_shmem.h @@ -0,0 +1,89 @@ +#ifndef QURT_SHMEM_H +#define QURT_SHMEM_H + +/** + @file qurt_shmem.h + + @brief + Prototypes of QuRT inter-process shared memory APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MODE_T +#define MODE_T +typedef unsigned int mode_t; +#endif //MODE_T + +/** + * The shm_open() function establishes a connection between a shared memory object and a file descriptor. + * The file descriptor is used by other functions such as mmap() to refer to that shared memory object. + * + * + * @param name Pointer to string naming a shared memory object. Name has to start with "/shm/" + * @param oflag File status flags and file access modes of the open file description. Following + * flags are defined in and supported: + * O_RDONLY: oepn for read access only + * O_RDWR: Open for read or write access + * O_CREAT: If shared memory object doesn't exist, create one. + * @param mode Permission flags (currently ignored) + * + * @return file descriptor (positive number) if operation successful. + * negative error code if failed + * +*/ + +int shm_open(const char * name, int oflag, mode_t mode); + +/** + * The shm_mmap() function create a shared memory mapping in the virtual address space of the + * the calling process. + * + * @param addr The starting address for the new mapping is specified in addr. + * @param len Specifies the lengh of the shared memory region. + * @param prot Describes the desired memory protection of the mapping. Same as the one in mmap of POSIX. + * @param flags Determines whether updates to the mapping is visible or not to other process. Same as + * the one in mmap of POSIX. + * @param fd The starting adddress for the new mapping is returned. + * @param offset unused. + * + * @return The starting adddress for the new mapping is returned. + * negative error code if failed + * +*/ + +void *shm_mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset); + +/** + * The shm_close() function removes a connection between a shared memory object and a file descriptor. + * If there is no file descriptor connects to the shared memory object, the shared memory object will + * be deleted automatically. Shared memory object has same virtual address in any process. This is + * restriction of single virtual address space. + * + * + * @param fd File descriptor of shared memory object + * + * @return 0 if operation successful. + * negative error code if failed + * +*/ + + +int shm_close(int fd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal.h new file mode 100755 index 0000000000000..3a89c53394ad5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal.h @@ -0,0 +1,518 @@ +#ifndef QURT_SIGNAL_H +#define QURT_SIGNAL_H + +/** + @file qurt_signal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup signals_types +@{ */ +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 /**< Wait any. */ +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 /**< Wait all. */ + +/*===================================================================== + Typedefs + ======================================================================*/ + + +/** QuRT signal type. + */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int signals; + unsigned int waiting; + unsigned int queue; + unsigned int attribute; + }X; + /** @endcond */ +} qurt_signal_t; + + +/** QuRT 64-bit signal type. + */ +typedef struct { + /** @cond */ + qurt_signal_t signal_sum; + unsigned long long signals; + unsigned long long waiting; + /** @endcond */ +} qurt_signal_64_t; +/** @} */ /* end_addtogroup signals_types */ +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal_init + Initializes a signal object. + Signal returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_init(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_destroy + Destroys the specified signal object. + + @note1hang Signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_destroy(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting on the signal. + + If a thread is waiting on a signal object for any of the specified set of signals to set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared when the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread waits to set any of the signals, or to set all of + them. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_timed + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set or until timeout. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared after the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value that identifies the individual signals in the signal object to wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] signals Bitmask of signals that are set + @param[in] duration Duration (microseconds) to wait. Must be in the range + [#QURT_TIMER_MIN_DURATION ... #QURT_TIMER_MAX_DURATION] + + @return + #QURT_EOK -- Success; one or more signals were set \n + #QURT_ETIMEDOUT -- Timed-out \n + #QURT_EINVALID -- Duration out of range + + @dependencies + Timed-waiting support in the kernel. +*/ +/* ======================================================================*/ +int qurt_signal_wait_timed(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, unsigned int *signals, unsigned long long int duration); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_any + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on the thread. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_any(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_all + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_all(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to set the signal, and 0 indicates not to set it. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 32-bit word with current signals + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_get(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_clear + Clear signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_clear(qurt_signal_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal_wait_cancellable + @xreflabel{hdr:qurt_signal_wait_cancellable} + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] return_mask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_signal_wait_cancellable(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, + unsigned int *return_mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_init + Initializes a 64-bit signal object.\n + The signal argument returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore. + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_init(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_destroy + Destroys the specified signal object. + + @note1hang 64-bit signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_destroy(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_wait + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value, which identifies the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_wait(qurt_signal_64_t *signal, unsigned long long mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set it. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifiying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_64_set(qurt_signal_64_t *signal, unsigned long long mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_64_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 64-bit double word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_get(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_clear + Clears signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_clear(qurt_signal_64_t *signal, unsigned long long mask); + +#ifdef __cplusplus +} +#endif + +#endif /* QURT_SIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal2.h new file mode 100755 index 0000000000000..43975100cbf75 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_signal2.h @@ -0,0 +1,340 @@ +#ifndef QURT_SIGNAL2_H +#define QURT_SIGNAL2_H + +/** + @file qurt_signal2.h + @brief Prototypes of kernel signal2 API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 + +/*===================================================================== + Typedefs + ======================================================================*/ + +/** @addtogroup signals2_types +@{ */ +/** qurt_signal2 type. + */ +typedef union { + /** @cond */ + struct{ + unsigned int cur_mask; /* Current set of signal bits that are set. */ + unsigned int sig_state; /* Current state. */ + /* Bit 0 -- in anysignal wait. */ + /* Bit 1 -- in allsignal wait. */ + /* Bit 2 -- in interrupt wait. */ + /* Bits 31-3 -- reference count field. */ + unsigned int queue; /* Kernel-maintained futex queue value. */ + unsigned int wait_mask; /* When sig_state indicates a waiter is present, this is the wait mask. */ + }; + unsigned long long int raw; + /** @endcond */ +} qurt_signal2_t; +/* @} */ /* end_addtogroup signals2_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_init + + @deprecated use #qurt_signal_init instead. + + Initializes a signal2 object. + Signal returns the initialized object. + The signal object is initially cleared. + + Objects of type signal2 solve a potential race condition between + set() and destroy() operations. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + Each mutex-based object has an associated + kernel resource(s), therefore users must call qurt_signal2_destroy() + when this object no longer in use. + */ +/* ======================================================================*/ +void qurt_signal2_init(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_destroy + + @deprecated use #qurt_signal_destroy instead. + + Destroys the specified signal object. + + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont Application code should destroy a signal2 object prior to deallocating it. + Calling qurt_signal2_destroy() before deallocating a + signal2 object ensures completion of all qurt_signal2_set() calls. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_destroy(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait + + @deprecated use #qurt_signal_wait instead. + + Suspends the current thread until the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ANY, the thread will be awakened when + any of the signals specified in the mask are set. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ALL, the thread will be awakened only + when all the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to wait on. + @param[in] attribute Specifies whether the thread waits for any of the signals to be set, or for all of + them to be set. Values:\n + - QURT_SIGNAL_ATTR_WAIT_ANY \n + - QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_any + + @deprecated use #qurt_signal_wait_any instead. + + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened when any of the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_any(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_all + + @deprecated use #qurt_signal_wait_all instead. + + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened only when all the signals specified in the mask are set. + + @note1hang At most one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_all(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_set + + @deprecated use #qurt_signal_set instead. + + Sets signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_get + + @deprecated use #qurt_signal_get instead. + + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the signal object to access. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_get(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_clear + + @deprecated use #qurt_signal_clear instead. + + Clear signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_clear(qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal2_wait_cancellable + + @deprecated use #qurt_signal_wait_cancellable instead. + + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] p_returnmask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +int qurt_signal2_wait_cancellable(qurt_signal2_t *signal, + unsigned int mask, + unsigned int attribute, + unsigned int *p_returnmask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SIGNAL2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_space.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_space.h new file mode 100755 index 0000000000000..2c3f9e4496697 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_space.h @@ -0,0 +1,230 @@ +#ifndef QURT_SPACE_H +#define QURT_SPACE_H +/** + @file qurt_space.h + @brief Prototypes of QuRT process control APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** This flag is a request to the OS to suspend the processes just before calling main() +But it is going to be obsoleted and replaced by QURT_PROCESS_SUSPEND_ON_STARTUP */ +#define SPAWNN_FLAG_SUSPEND_ON_STARTUP QURT_PROCESS_SUSPEND_ON_STARTUP + +/** + * Creates and starts a process from ELF of a specified name. The slash symbols + * "/" or "\" are ignored. Do not include the directory name in the input. This function + * accepts the the SPAWN flags. Multiple SPAWN flags can be specified by OR'ing the flags. + * + * @param name ELF name of the executable. Name shall not contain directories, + * use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf" + * + * @param return + Process ID -- Success \n + Negative error code -- failure\n + #QURT_EPRIVILEGE -- Caller does not have enough privilege for this operation\n + #QURT_EMEM -- Not enough memory to perform the operation \n + #QURT_EFAILED -- Operation failed \n + #QURT_ENOTALLOWED -- Operation not allowed \n + #QURT_ENOREGISTERED -- Not registered \n + #QURT_ENORESOURCE -- Resource exhaustion \n + #QURT_EINVALID -- Invalid argument value +*/ + +int qurt_spawn_flags(const char * name, int flags); + +/** + Creates and starts a process from an ELF of the specified name. The slash symbols + "/" or "\" are ignored. Do not include the directory name in the input. + + @param name ELF name of the executable. Name shall not contain directories, + use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf". + + @return + Process ID -- Success. \m + Negative error code -- Failure. + +*/ +static inline int qurt_spawn(const char *name) +{ + return qurt_spawn_flags(name,0); +} + +/** + * Returns the process ID of the current process. + * + * @return + * Process ID + * +*/ +#define qurt_getpid qurt_process_get_id + +/** + * The qurt_wait() function waits for status change in a child process. It could be used by parent + * process to block on any child process terminates. + * + * This API returns error if there are no user processes or all user processes got detached. + * + * @param status Pointer to status variable. The variable provides the status value of child process. + * The value comes from exit() system call made by child process. + * + * @return + Process ID of the child process that changes status -- Success \n + * Negative error code -- Failure + * +*/ + +int qurt_wait(int *status); + + +/** @cond */ +/* APIs that allow registering callbacks on spawn of user pd */ +typedef void (*QURT_SPAWN_PFN)(int client_handle, void *data_ptr); //no return, since we won't be error checking it in spawn +typedef int (*QURT_CB_PFN)(int client_handle, void *user_data, void *info); +typedef union { + QURT_SPAWN_PFN spawn_pfn; + QURT_CB_PFN cb_pfn; +} qurt_process_callback_pfn_t; +/** @endcond */ + +/** @cond internal_only */ + +/**@ingroup func_qurt_event_register +Sets the specified bits by mask in the signal passed by the caller. The signal gets set +when the client handle indicated by value goes away (at process exit). Multiple clients can register for the signal +to be set. + +@datatypes + +@param[in] type QURT_PROCESS_EXIT is the only event that can be registered for. +@param[in] value Indicates the client handle of the process for which the event is registered. +@param[in] signal Pointer to the signal object to set when the event occurs. +@param[in] mask Mask bits to set in the signal. +@param[out] data Pointer to the variable that would receive the exit code of the exiting process. +@param[in] datasize Size of the data variable. + +@return +#QURT_EOK -- Success \n +#QURT_EMEM -- Not enough memory to allocate resources \n +#QURT_EVAL -- Invalid values passed to the API + +@dependencies +None. +*/ +int qurt_event_register(int type, int value, qurt_signal_t *psig, unsigned int mask, void *data, unsigned int data_size); + +/**@ingroup func_qurt_callback_register_onspawn +Allows registering for a callback on spawn of any user process. + +@datatypes +#QURT_SPAWN_PFN + +@param[in] pFn Callback function to call when any user process is spawned. +@param[in] user_data Pointer to the argument that the callback must be called with. + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_callback_register_onspawn(QURT_SPAWN_PFN pFn, void *user_data); + +/**@ingroup func_qurt_callback_deregister_onspawn +Allows de-registering callback on spawn. + +@param[in] callback_handle Handle returned by qurt_callback_register_onspawn. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_callback_deregister_onspawn(int callback_handle); + +/**@ingroup func_qurt_process_callback_register +Allows registering for a callback during or after image loading. +Generic callback types: + Functions similarly to qurt_callback_register_onspawn(). Callback is called after process is + loaded, before process thread starts. Callback has no return value and has no info provided + from OS. + pFn - QURT_SPAWN_PFN + type - QURT_PROCESS_CB_GENERIC + arg1 - not used + arg2 - not used + arg3 - not used +Note callback types: + Callback is called during process loading: before segment loading(QURT_PROCESS_NOTE_CB_PRE_MAP), + or after segment loading (QURT_PROCESS_NOTE_CB_POST_MAP). OS provides info to the callback. info + argument in callback is populated with pointer to the mapped note corresponding to the callback. + Callback has return value, loader fails if callback returns a value that is not QURT_EOK. + pFn - QURT_CB_PFN + type - QURT_PROCESS_NOTE_CB_PRE_MAP or QURT_PROCESS_NOTE_CB_POST_MAP + arg1 - note type (ex: NOTE_TYPE_POOL_INFO, NOTE_TYPE_SEGMENT_INFO, NOTE_TYPE_ARB_INFO) + arg2 - note name + arg3 - not used + +@datatypes + +@param[in] pFn Callback function to call +@param[in] type Callback type +@param[in] user_data Pointer to the argument that the callback must be called with. +@param[in] arg1 Arguments interpreted by OS based on callback type +@param[in] arg2 Arguments interpreted by OS based on callback type +@param[in] arg3 Arguments interpreted by OS based on callback type (currently not used) + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_process_callback_register(qurt_process_callback_pfn_t pFn, + qurt_process_cb_type_t type, + void *user_data, + qurt_process_callback_arg_t arg1, + qurt_process_callback_arg_t arg2, + qurt_process_callback_arg_t arg3); + + + +/**@ingroup func_qurt_process_callback_deregister +Allows de-registering callback for imate loading. +@param[in] callback_handle Handle returned by qurt_process_callback_register. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_process_callback_deregister(int callback_handle); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SPACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_consts.h new file mode 100755 index 0000000000000..48a8b6a38c402 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_consts.h @@ -0,0 +1,32 @@ +#ifndef QURT_SRM_CONSTS_H +#define QURT_SRM_CONSTS_H +/** + @file qurt_srm_consts.h + @brief Type definitions for srm + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2020-2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +#define QURT_SRM_WAKEUP_REQUEST 1U << 0 /**< Value = 1: Send wakeup request to the SRM server. */ +#define QURT_SRM_SET_HANDLE 1U << 1 /**< Value = 2: Set the client handle for a new SRM client. */ +#define QURT_SRM_ALLOC_KERNEL_PAGES 1U << 2 /**< Value = 4: Allocate pages from the kernel VA space. */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_driver.h new file mode 100755 index 0000000000000..5489e3dddbcca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_srm_driver.h @@ -0,0 +1,140 @@ +#ifndef QURT_SRM_DRIVER_H +#define QURT_SRM_DRIVER_H +/** + @file qurt_srm_driver.h + @brief Definitions, macros, and prototypes used by SRM drivers. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + + =============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Define qurt_srm_driver_t structure, which represents +|| the "registration" object for an SRM driver. +*/ +/** @cond internal_only */ +struct _qurt_srm_driver { + const char *name; + qurt_qdi_obj_t *obj; +}; + +typedef struct _qurt_srm_driver qurt_srm_driver_t; + +/* +|| qurt_srm_object_invoke() is an internal equivalent to qurt_qdi_handle_invoke(). +|| It behaves the same, but it takes a QDI object pointer instead of a handle. +*/ + +#define qurt_srm_object_invoke(o,m,...) \ + _QDMPASTE(_QDMSOI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__) +#define _QDMSOI3(a,b,c) qurt_srm_oi3(a,b,c) +#define _QDMSOI4(a,b,c,d) qurt_srm_oi4(a,b,c,(int)(d)) +#define _QDMSOI5(a,b,c,d,e) qurt_srm_oi5(a,b,c,(int)(d),(int)(e)) +#define _QDMSOI6(a,b,c,d,e,f) qurt_srm_oi6(a,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMSOI7(a,b,c,d,e,f,g) qurt_srm_oi7(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMSOI8(a,b,c,d,e,f,g,h) qurt_srm_oi8(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMSOI9(a,b,c,d,e,f,g,h,i) qurt_srm_oi9(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMSOI10(a,b,c,d,e,f,g,h,i,j) qurt_srm_oi10(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMSOI11(a,b,c,d,e,f,g,h,i,j,k) qurt_srm_oi11(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMSOI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_srm_oi12(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) + +int qurt_srm_oi3(int, qurt_qdi_obj_t *, int); +int qurt_srm_oi4(int, qurt_qdi_obj_t *, int, int); +int qurt_srm_oi5(int, qurt_qdi_obj_t *, int, int, int); +int qurt_srm_oi6(int, qurt_qdi_obj_t *, int, int, int, int); +int qurt_srm_oi7(int, qurt_qdi_obj_t *, int, int, int, int, int); +int qurt_srm_oi8(int, qurt_qdi_obj_t *, int, int, int, int, int, int); +int qurt_srm_oi9(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int); +int qurt_srm_oi10(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int); +int qurt_srm_oi11(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int); +int qurt_srm_oi12(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int, int); + +#define QDI_SRM_INIT 192 + +/* +|| QURT_SRM_DECLARE_DRIVER() declares an SRM driver to the SRM infrastructure. +|| +|| The three arguments are: +|| unique_id -- Unique C identifier, unused but must be a unique global symbol. +|| name -- Name of the driver by which an SRM client attempts to open it. +|| obj -- Pointer to the singleton object of the driver, which handles things such as +|| initialization and QDI_OPEN requests. +*/ + +#define QURT_SRM_DECLARE_DRIVER(unique_id, xname, xobj) \ + __attribute__((section(".srm.rodata.user.main.DECL"))) const qurt_srm_driver_t unique_id = \ + { .name = xname, .obj = xobj } + + +/*@ingroup func_qurt_srm_mapping_create + Creates a memory mapping in pagetable with specified attributes + + @param[in] client_handle Client handle representing the process for which + mapping would be created. + @param[in] pageno_virt pointer to the virtual page. NULL indicates SRM + would indicate the virtual memory. + @param[in] pageno_phys physical page to be used for the mapping + @param[in] page_count number of 4k pages to be mapped + @param[in] cache_attr cache attributes for the mapping + @param[in] perm permissions to be used for the mapping + + @return value greater than 0 indicates a handle which can be passed to + qdi_close() to remove the mapping. Negative value indicates + an error. + + @dependencies + None. +*/ +int qurt_srm_mapping_create(int client_handle, + unsigned *pageno_virt, + unsigned pageno_phys, + unsigned page_count, + qurt_mem_cache_mode_t cache_attr, + qurt_perm_t perm); + + +/**@ingroup func_qurt_srm_get_pid + Gets the PID for the client_handle that is passed. + + @param[in] client_handle Client handle for which PID is required. + + @return PID of the client + Negative PID value '-1' will be returned in case of Error + + @dependencies + None. +*/ +unsigned qurt_srm_get_pid(int client_handle); + + +/*@ingroup func_qurt_srm_get_thread_id + Gets the thread id of the client requesting a service from SRM + + @param[in] None. + + @return thead id of client thread + + @dependencies + None. +*/ +qurt_thread_t qurt_srm_get_client_thread_id(void); + +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_DRIVER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_stid.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_stid.h new file mode 100755 index 0000000000000..379f46aaa4b80 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_stid.h @@ -0,0 +1,73 @@ +#ifndef QURT_STID_H +#define QURT_STID_H +/** + @file qurt_stid.h + Prototypes of software thread identifier(stid) interface APIs. + A stid is 8 bit identifier that can be assigned to a software thread. + The performance monitor logic uses stid as a counting match criteria + for maskable events. stid is also used by the hardware debugger + (ISDB) to match breakpoints. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2024 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_stid_alloc + Allocate a unique stid + + @param[in] pid Process identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - Allocation success + QURT_ENORESOURCE - No stid available for allocation + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_stid_alloc(unsigned int pid, unsigned int *stid); + +/**@ingroup func_qurt_stid_release + Release the stid. + + + @param[in] pid Process identifier + @param[in] stid STID to release + + @note1hang + User shall ensure to clear the released stid from process or thread(s) + to default value (QURT_STID_DEFAULT) before releasing that stid + + @return + QURT_EOK - Release success + QURT_ENOTALLOWED - Operation not allowed for a pid + QURT_EINVALID - Invalid stid + + @dependencies + None. + */ +int qurt_stid_release(unsigned int pid, unsigned int stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_STID_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread.h new file mode 100755 index 0000000000000..499699e7c72e2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread.h @@ -0,0 +1,1260 @@ +#ifndef QURT_THREAD_H +#define QURT_THREAD_H +/** + @file qurt_thread.h + @brief Prototypes of Thread API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2020-2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +#include +#include "qurt_pmu.h" +#include "qurt_api_version.h" +#endif /* __ASSEMBLER__ */ +#include "qurt_consts.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/* + Bitmask configuration to select DSP hardware threads. + To select all the hardware threads, use #QURT_THREAD_CFG_BITMASK_ALL + and the following: \n + - For QDSP6 V2/V3, all six hardware threads are selected \n + - For QDSP6 V3L, all four hardware threads are selected \n + - For QDSP6 V4, all three hardware threads are selected + */ + +#define QURT_THREAD_CFG_BITMASK_HT0 0x00000001 /**< HTO. */ +#define QURT_THREAD_CFG_BITMASK_HT1 0x00000002 /**< HT1. */ +#define QURT_THREAD_CFG_BITMASK_HT2 0x00000004 /**< HT2. */ +#define QURT_THREAD_CFG_BITMASK_HT3 0x00000008 /**< HT3. */ +#define QURT_THREAD_CFG_BITMASK_HT4 0x00000010 /**< HT4. */ +#define QURT_THREAD_CFG_BITMASK_HT5 0x00000020 /**< HT5. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{sec:qurt_thread_cfg} */ + +#define QURT_THREAD_CFG_BITMASK_ALL 0x000000ffU /**< Select all the hardware threads. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_CFG_USE_RAM 0x00000000 /**< Use RAM. */ +#define QURT_THREAD_CFG_USE_TCM 0x00000100 /**< Use TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_BUS_PRIO_DISABLED 0 /**< Thread internal bus priority disabled. */ +#define QURT_THREAD_BUS_PRIO_ENABLED 1 /**< Thread internal bus priority enabled. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_AUTOSTACK_DISABLED 0 /**< Thread has autostack v2 feature disabled. */ +#define QURT_THREAD_AUTOSTACK_ENABLED 1 /**< Thread has autostack v2 feature enabled. */ + +/* + Macros for QuRT thread attributes. + */ +#define QURT_HTHREAD_L1I_PREFETCH 0x1 /**< Enables hardware L1 instruction cache prefetching. */ +#define QURT_HTHREAD_L1D_PREFETCH 0x2 /**< Enables hardware L1 data cache prefetching. */ +#define QURT_HTHREAD_L2I_PREFETCH 0x4 /**< Enables hardware L2 instruction cache prefetching. */ +#define QURT_HTHREAD_L2D_PREFETCH 0x8 /**< Enables hardware L2 data cache prefetching. */ +#define QURT_HTHREAD_DCFETCH 0x10 /**< Enables DC fetch to the provided virtual address. + DC fetch indicates the hardware that a data memory access is likely. + Instructions are dropped when there is high bus utilization. */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{hdr:partition_tcm} */ +/* + Below value is used to create legacy QuRT threads by default. + If a thread has this as the detach_state, the thread can be joined + on until it exits. When we are able to change default behavior of all + QuRT threads to JOINABLE (posix default), we can remove this legacy + behavior. +*/ +#define QURT_THREAD_ATTR_CREATE_LEGACY 0U /**< Create a legacy QuRT thread by default. If a thread has this as a detach state, the thread can be joined on until it exits. */ +#define QURT_THREAD_ATTR_CREATE_JOINABLE 1U /**< Create a joinable thread. */ +#define QURT_THREAD_ATTR_CREATE_DETACHED 2U /**< Create a detached thread. */ +/** @} */ /* end_addtogroup thread_macros */ + + +#define QURT_THREAD_ATTR_NAME_MAXLEN 16 /**< Maximum name length. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_RAM 0 /**< Creates threads in RAM/DDR. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_TCM 1 /**< Creates threads in TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT QURT_THREAD_ATTR_TCB_PARTITION_RAM /**< Backward compatibility. */ +#define QURT_THREAD_ATTR_PRIORITY_DEFAULT 254 /**< Priority.*/ +#define QURT_THREAD_ATTR_ASID_DEFAULT 0 /**< ASID. */ +#define QURT_THREAD_ATTR_AFFINITY_DEFAULT (-1) /**< Affinity. */ +#define QURT_THREAD_ATTR_BUS_PRIO_DEFAULT 255 /**< Bus priority. */ +#define QURT_THREAD_ATTR_AUTOSTACK_DEFAULT 0 /**< Default autostack v2 disabled thread. */ +#define QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT (-2) /**< Timetest ID. */ +#define QURT_THREAD_ATTR_STID_DEFAULT QURT_STID_DEFAULT /**< STID. */ +#define QURT_THREAD_ATTR_STID_ENABLE 1 /**< Indicate to allocate STID during thread creation. */ + +#define QURT_PRIORITY_FLOOR_DEFAULT 255U /**< Default floor. */ +/** @} */ /* end_addtogroup thread_macros */ + +// Option for suspending thread +#define QURT_THREAD_SUSPEND_SYNCHRONOUS 0x0U // bit#0 +#define QURT_THREAD_SUSPEND_ASYNCHRONOUS 0x1U // bit#0 +#define QURT_THREAD_SUSPEND_KEEP_HMX 0x0U // bit#1 +#define QURT_THREAD_SUSPEND_DETACH_HMX 0x2U // bit#1 + +// Option for resuming thread +#define QURT_THREAD_RESUME_DEFAULT 0x0 + +// Thread property IDs +#define QURT_THREAD_PROPERTY_SUSPENDABLE 0x0U +#define QURT_THREAD_PROPERTY_RESUMABLE 0x1 + +// Thread group +#define QURT_THREAD_DEFAULT_GROUP_ID 0x0U +#define QURT_THREAD_GROUP_ID_MASK 0x3FU + +/** @endcond*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup thread_types +@{ */ +/** @cond rest_reg_dist */ +typedef unsigned int qurt_cache_partition_t; /**< QuRT cache partition type. */ + +#define CCCC_PARTITION 0U /**< Use the CCCC page attribute bits to determine the main or auxiliary partition. */ +#define MAIN_PARTITION 1U /**< Use the main partition. */ +#define AUX_PARTITION 2U /**< Use the auxiliary partition. */ +#define MINIMUM_PARTITION 3U /**< Use the minimum. Allocates the least amount of cache (no-allocate policy possible) for this thread. */ +/** @endcond */ + +/** Thread ID type. */ +typedef unsigned int qurt_thread_t; + +/** @cond rest_reg_dist */ +/** Thread attributes. */ +typedef struct _qurt_thread_attr { + + char name[QURT_THREAD_ATTR_NAME_MAXLEN]; /**< Thread name. */ + unsigned char tcb_partition; /**< Indicates whether the thread TCB resides in RAM or + on chip memory (TCM). */ + unsigned char stid; /**< Software thread ID used to configure the stid register + for profiling purposes. */ + unsigned short priority; /**< Thread priority. */ + unsigned char autostack:1; /**< Autostack v2 enabled thread. */ + unsigned char group_id:6; /**< Group ID. */ + unsigned char reserved:1; /**< Reserved bits. */ + unsigned char bus_priority; /**< Internal bus priority. */ + unsigned short timetest_id; /**< Timetest ID. */ + unsigned int stack_size; /**< Thread stack size. */ + void *stack_addr; /**< Pointer to the stack address base. The range of the stack is + (stack_addr, stack_addr+stack_size-1). */ + unsigned short detach_state; /**< Detach state of the thread. */ + +} qurt_thread_attr_t; +/** @endcond */ + +/** @cond rest_reg_dist */ +/** Dynamic TLS attributes. */ +typedef struct qurt_tls_info { + unsigned int module_id; /**< Module ID of the loaded dynamic linked library. */ + unsigned int tls_start; /**< Start address of the TLS data. */ + unsigned int tls_data_end; /**< End address of the TLS RW data. */ + unsigned int tls_end; /**< End address of the TLS data. */ +}qurt_tls_info; +/** @endcond */ + +/** @} */ /* end_addtogroup thread_types */ + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_thread_attr_init + Initializes the structure used to set the thread attributes when a thread is created. + After an attribute structure is initialized, Explicity set the individual attributes in the structure + using the thread attribute operations. + + The initialize operation sets the following default attribute values: \n + - Name -- NULL string \n + - TCB partition -- QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT + - Priority -- QURT_THREAD_ATTR_PRIORITY_DEFAULT \n + - Autostack -- QURT_THREAD_ATTR_AUTOSTACK_DEFAULT \n + - Bus priority -- QURT_THREAD_ATTR_BUS_PRIO_DEFAULT \n + - Timetest ID -- QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT \n + - stack_size -- 0 \n + - stack_addr -- NULL \n + - detach state -- #QURT_THREAD_ATTR_CREATE_LEGACY \n + - STID -- #QURT_THREAD_ATTR_STID_DEFAULT + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_init (qurt_thread_attr_t *attr) +{ + + attr->name[0] = '\0'; + attr->tcb_partition = QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT; + attr->priority = QURT_THREAD_ATTR_PRIORITY_DEFAULT; + attr->autostack = QURT_THREAD_ATTR_AUTOSTACK_DEFAULT; /* Default attribute for autostack v2*/ + attr->bus_priority = QURT_THREAD_ATTR_BUS_PRIO_DEFAULT; + attr->timetest_id = (unsigned short)QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT; + attr->stack_size = 0; + attr->stack_addr = NULL; + attr->detach_state = QURT_THREAD_ATTR_CREATE_LEGACY; + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + attr->group_id = QURT_THREAD_DEFAULT_GROUP_ID; +} + +/**@ingroup func_qurt_thread_attr_set_name + Sets the thread name attribute.\n + This function specifies the name to use by a thread. + Thread names identify a thread during debugging or profiling. + Maximum name length is 16 charactes \n + @note1hang Thread names differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] name Pointer to the character string containing the thread name. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_name (qurt_thread_attr_t *attr, const char *name) +{ + strlcpy (attr->name, name, QURT_THREAD_ATTR_NAME_MAXLEN); + attr->name[QURT_THREAD_ATTR_NAME_MAXLEN - 1] = '\0'; +} + + +/**@ingroup func_qurt_thread_attr_set_tcb_partition + Sets the thread TCB partition attribute. + Specifies the memory type where a TCB of a thread is allocated. + Allocates TCBs in RAM or TCM/LPM. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] tcb_partition TCB partition. Values:\n + - 0 -- TCB resides in RAM \n + - 1 -- TCB resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_tcb_partition (qurt_thread_attr_t *attr, unsigned char tcb_partition) +{ + attr->tcb_partition = tcb_partition; +} + +/**@ingroup func_qurt_thread_attr_set_priority + Sets the thread priority to assign to a thread. + Thread priorities are specified as numeric values in the range 1 to 254, with 1 representing + the highest priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] priority Thread priority. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_priority (qurt_thread_attr_t *attr, unsigned short priority) +{ + attr->priority = priority; +} + +/**@ingroup func_qurt_thread_attr_set_detachstate + Sets the thread detach state with which thread is created. + Thread detach state is either joinable or detached; specified by the following values: + - #QURT_THREAD_ATTR_CREATE_JOINABLE \n + - #QURT_THREAD_ATTR_CREATE_DETACHED \n + + When a detached thread is created (QURT_THREAD_ATTR_CREATE_DETACHED), its thread + ID and other resources are reclaimed as soon as the thread exits. When a joinable thread + is created (QURT_THREAD_ATTR_CREATE_JOINABLE), it is assumed that some + thread waits to join on it using a qurt_thread_join() call. + By default, detached state is QURT_THREAD_ATTR_CREATE_LEGACY + If detached state is QURT_THREAD_ATTR_CREATE_LEGACY then other + thread can join before thread exits but it will not wait other thread to join. + + @note1hang For a joinable thread (QURT_THREAD_ATTR_CREATE_JOINABLE), it is very + important that some thread joins on it after it terminates, otherwise + the resources of that thread are not reclaimed, causing memory leaks. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] detachstate Thread detach state. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_detachstate (qurt_thread_attr_t *attr, unsigned short detachstate) +{ + if(detachstate == QURT_THREAD_ATTR_CREATE_JOINABLE || detachstate == QURT_THREAD_ATTR_CREATE_DETACHED){ + attr->detach_state = detachstate; + } +} + + +/**@ingroup func_qurt_thread_attr_set_timetest_id + Sets the thread timetest attribute.\n + Specifies the timetest identifier to use by a thread. + + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] timetest_id Timetest identifier value. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_thread_attr_set_timetest_id (qurt_thread_attr_t *attr, unsigned short timetest_id) +{ + attr->timetest_id = timetest_id; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute.\n + Specifies the size of the memory area to use for a call stack of a thread. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_size Size (in bytes) of the thread stack. + + @return + None. + + @dependencies + None. +*/ + +static inline void qurt_thread_attr_set_stack_size (qurt_thread_attr_t *attr, unsigned int stack_size) +{ + attr->stack_size = stack_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size2 + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute for island threads that require a higher guest OS stack size than the stack size + defined in the configuration XML.\n + Specifies the size of the memory area to use for a call stack of an island thread in User and Guest mode. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] user_stack_size Size (in bytes) of the stack usage in User mode. + @param[in] root_stack_size Size (in bytes) of the stack usage in Guest mode. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_size2 (qurt_thread_attr_t *attr, unsigned short user_stack_size, unsigned short root_stack_size) +{ + union qurt_thread_stack_info{ + unsigned int raw_size; + struct{ + unsigned short user_stack; + unsigned short root_stack; + }; + }user_root_stack_size; + user_root_stack_size.user_stack = user_stack_size; + user_root_stack_size.root_stack = root_stack_size; + + attr->stack_size = user_root_stack_size.raw_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_addr + @xreflabel{sec:set_stack_addr} + Sets the thread stack address attribute. \n + Specifies the base address of the memory area to use for a call stack of a thread. + + stack_addr must contain an address value that is 8-byte aligned. + + The thread stack address and stack size (Section @xref{sec:set_stack_size}) specify the memory area used as a + call stack for the thread. \n + @note1hang The user is responsible for allocating the memory area used for the thread + stack. The memory area must be large enough to contain the stack that the thread + creates. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_addr Pointer to the 8-byte aligned address of the thread stack. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_addr (qurt_thread_attr_t *attr, void *stack_addr) +{ + attr->stack_addr = stack_addr; +} + +/**@ingroup func_qurt_thread_attr_set_bus_priority + Sets the internal bus priority state in the Hexagon core for this software thread attribute. + Memory requests generated by the thread with bus priority enabled are + given priority over requests generated by the thread with bus priority disabled. + The default value of bus priority is disabled. + + @note1hang Sets the internal bus priority for Hexagon processor version V60 or greater. + The priority is not propagated to the bus fabric. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + + @param[in] bus_priority Enabling flag. Values: \n + - #QURT_THREAD_BUS_PRIO_DISABLED \n + - #QURT_THREAD_BUS_PRIO_ENABLED @tablebulletend + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_bus_priority ( qurt_thread_attr_t *attr, unsigned short bus_priority) +{ + attr->bus_priority = (unsigned char)bus_priority; +} + +/**@ingroup func_qurt_thread_attr_set_autostack + Enables autostack v2 feature in the thread attributes. + + When autostack is enabled by the subsystem, in the case that + an autostack enabled thread gets framelimit exception, kernel will + allocate more stack for thread and return to normal execution. + + If autostack is not enabled by the subsystem, or it is not enabled + for the thread, the framelimit exception will be fatal. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] autostack Autostack enable or disable flag. Values: \n + - #QURT_THREAD_AUTOSTACK_DISABLED \n + - #QURT_THREAD_AUTOSTACK_ENABLED @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_autostack ( qurt_thread_attr_t *attr, unsigned short autostack) +{ + attr->autostack = (unsigned char)autostack; +} +/**@ingroup qurt_thread_attr_enable_stid + Set STID in the thread attributes. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] enable_stid STID to be set. Values: \n + - #QURT_THREAD_ATTR_STID_DEFAULT (0): Default STID. \n + - #QURT_THREAD_ATTR_STID_ENABLE (1): QuRT assigns an STID that is not already in use \n + - #2 through #255 : User provided STID. @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_enable_stid ( qurt_thread_attr_t *attr, char enable_stid) +{ + if (enable_stid != '\0') { + attr->stid = enable_stid; + } + else + { + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + } +} + +/**@ingroup func_qurt_thread_attr_set_stid + Sets the stid thread attribute. + The default stid value is QURT_THREAD_ATTR_STID_DEFAULT + + @note1hang When a thread is created with non default stid , + the stid set in thread attribute will be assigned to a thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] stid Stid to be set for a thread. + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stid( qurt_thread_attr_t *attr, unsigned int stid){ + attr->stid = stid; +} + +/**@ingroup func_qurt_thread_attr_set_group_id + Sets group id in the thread attributes. + Primordial/first thread has group ID 0. + If a new thread is created without assigning group_id, it + inherits the group ID from its parent thread. + + @note1hang + 1) Group ID can only be set before creating a thread. It cannot be + changed after the thread is created. + 2) If a non-activated group_id is passed, thread creation will fail. + 3) Only a thread with Group ID #0 can set Group ID for its child threads. + 4) If thread with non-zero group ID set the group ID for its child threads, + QuRT will ingore this parameter and child threads will inherit the parent + thread's group ID. But if passed group ID is not activated, thread creation + will still fail. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] group_id Group identifier. Its valid range is 0 ~ 63 + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_group_id(qurt_thread_attr_t *attr, unsigned int group_id) +{ + attr->group_id = group_id & QURT_THREAD_GROUP_ID_MASK; +} + +/**@ingroup func_qurt_thread_set_autostack + Sets autostack enable in the TCB. + + @param[in] Pointer to UGP + + @return + None. + + @dependencies + None. +*/ + +void qurt_thread_set_autostack(void *); + + +/**@ingroup func_qurt_thread_get_name + Gets the thread name of current thread.\n + Returns the thread name of the current thread. + Thread names are assigned to threads as thread attributes, see qurt_thread_attr_set_name(). Thread names + identify a thread during debugging or profiling. + + @param[out] name Pointer to a character string, which specifies the address where the returned thread name is stored. + @param[in] max_len Maximum length of the character string that can be returned. + + @return + None. + + @dependencies + None. +*/ +void qurt_thread_get_name (char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_create + @xreflabel{hdr:qurt_thread_create} + Creates a thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + @param[in] entrypoint C function pointer, which specifies the main function of a thread. + @param[in] arg Pointer to a thread-specific argument structure + + + @return + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_thread_create (qurt_thread_t *thread_id, qurt_thread_attr_t *attr, void (*entrypoint) (void *), void *arg); + +/**@ingroup func_qurt_thread_stop + Stops the current thread, frees the kernel TCB, and yields to the next highest ready thread. + + @return + void + + @dependencies + None. + */ +void qurt_thread_stop(void); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_resume + When a demand-loading paging solution is enabled, this function + will resumes the execution of a thread that was suspended due to + a page miss. + + @param[in] thread_id Thread identifier. + + @return + #QURT_EOK -- Thread successfully resumed. \n + #QURT_EFATAL -- Resume operation failed. + + @dependencies + None. + */ +int qurt_thread_resume(unsigned int thread_id); +/** @endcond */ + +/**@ingroup func_qurt_thread_get_id + Gets the identifier of the current thread.\n + Returns the thread identifier for the current thread. + + @return + Thread identifier -- Identifier of the current thread. + + @dependencies + None. + */ +qurt_thread_t qurt_thread_get_id (void); + + +/**@ingroup func_qurt_thread_get_l2cache_partition + Returns the current value of the L2 cache partition assigned to the caller thread.\n + + @return + Value of the #qurt_cache_partition_t data type. + + @dependencies + None. + */ +qurt_cache_partition_t qurt_thread_get_l2cache_partition (void); + +/**@ingroup func_qurt_thread_set_timetest_id + Sets the timetest identifier of the current thread. + Timetest identifiers are used to identify a thread during debugging or profiling.\n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @param[in] tid Timetest identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_timetest_id (unsigned short tid); + +/**@ingroup func_qurt_thread_set_cache_partition + Sets the cache partition for the current thread. This function uses the qurt_cache_partition_t type + to select the cache partition of the current thread for the L1 Icache, L1 Dcache, and L2 cache. + + @datatypes + #qurt_cache_partition_t + + @param[in] l1_icache L1 I cache partition. + @param[in] l1_dcache L1 D cache partition. + @param[in] l2_cache L2 cache partition. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_cache_partition(qurt_cache_partition_t l1_icache, qurt_cache_partition_t l1_dcache, qurt_cache_partition_t l2_cache); + + +/**@ingroup func_qurt_thread_get_timetest_id + Gets the timetest identifier of the current thread.\n + Returns the timetest identifier of the current thread.\n + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @return + Integer -- Timetest identifier. + + @dependencies + None. + */ +unsigned short qurt_thread_get_timetest_id (void); + +/**@ingroup func_qurt_thread_exit + @xreflabel{sec:qurt_thread_exit} + Stops the current thread, awakens threads joined to it, then destroys the stopped + thread. + + Threads that are suspended on the current thread (by performing a thread join + Section @xref{sec:thread_join}) are awakened and passed a user-defined status value + that indicates the status of the stopped thread. + + @note1hang Exit must be called in the context of the thread to stop. + + @param[in] status User-defined thread exit status value. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_exit(int status); + +/**@ingroup func_qurt_thread_join + @xreflabel{sec:thread_join} + Waits for a specified thread to finish; the specified thread is another thread within + the same process. + The caller thread is suspended until the specified thread exits. When the unspecified thread + exits, the caller thread is awakened. \n + @note1hang If the specified thread has already exited, this function returns immediately + with the result value #QURT_ENOTHREAD. \n + @note1cont Two threads cannot call qurt_thread_join to wait for the same thread to finish. + If this occurs, QuRT generates an exception (see Section @xref{sec:exceptionHandling}). + + @param[in] tid Thread identifier. + @param[out] status Destination variable for thread exit status. Returns an application-defined + value that indicates the termination status of the specified thread. + + @return + #QURT_ENOTHREAD -- Thread has already exited. \n + #QURT_EOK -- Thread successfully joined with valid status value. + + @dependencies + None. + */ +int qurt_thread_join(unsigned int tid, int *status); + +/**@ingroup qurt_thread_detach + @xreflabel{sec:thread_detach} + Detaches a joinable thread. The specified thread is another thread within the + same process. Create the thread as a joinable thread; only joinable threads + can be detached. + If a joinable thread is detached, it finishes execution and exits. + + @param[in] tid Thread identifier. + + @return + #QURT_ENOTHREAD -- Thread specifed by TID does not exist. \n + #QURT_EOK -- Thread successfully detached. + + @dependencies + None. + */ +int qurt_thread_detach(unsigned int tid); + + +/**@ingroup func_qurt_thread_get_priority + Gets the priority of the specified thread. \n + Returns the thread priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. \n + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + + @return + -1 -- Invalid thread identifier. \n + 1 through 254 -- Thread priority value. + + @dependencies + None. + */ +int qurt_thread_get_priority (qurt_thread_t threadid); + +/**@ingroup func_qurt_thread_set_priority + Sets the priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. For more + information, see Section @xref{sec:AppDev}. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + @param[in] newprio New thread priority value. + + @return + 0 -- Priority successfully set. \n + -1 -- Invalid thread identifier. \n + + @dependencies + None. + */ +int qurt_thread_set_priority (qurt_thread_t threadid, unsigned short newprio); + + + +/**@ingroup func_qurt_thread_attr_get + Gets the attributes of the specified thread. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[out] attr Pointer to the destination structure for thread attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid argument. + + @dependencies + None. + */ +int qurt_thread_attr_get (qurt_thread_t thread_id, qurt_thread_attr_t *attr); + + + +/**@ingroup func_qurt_thread_get_tls_base + Gets the base address of thread local storage (TLS) of a dynamically loaded module + for the current thread. + + @datatypes + #qurt_tls_info + + @param[in] info Pointer to the TLS information for a module. + + @return + Pointer to the TLS object for the dynamically loaded module.\n + NULL -- TLS information is invalid. + + @dependencies + None. + */ +void * qurt_thread_get_tls_base(qurt_tls_info* info); + +/**@ingroup func_qurt_thread_pktcount_get + Gets the PKTCOUNT of a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + PKTCOUNT + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_get (qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_pktcount_set + Sets the PKTCOUNT for the current QuRT thread. + + @return + Value to which pktcount is set. + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_set (long long int); + +/**@ingroup func_qurt_thread_stid_get + Gets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + STID + + @dependencies + None. + */ + +char qurt_thread_stid_get(qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_stid_get2 + Returns the set stid for a thread + + @param[in] thread_id thread identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - success + QURT_ENOTALLOWED - operation not allowed for a thread + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_thread_stid_get2(unsigned int thread_id, unsigned int *stid); + +/**@ingroup func_qurt_thread_stid_set + Sets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] stid Thread identifier. + + @return + #QURT_EOK -- STID set created. \n + #QURT_EFAILED -- STID not set. + + @dependencies + None. + */ + +int qurt_thread_stid_set(char stid); + +/**@ingroup qurt_thread_stid_set2 + Sets the stid for a specified thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[in] stid Stid to be set for a thread. + + @return + QURT_EOK -- Success + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_EVAL -- Failure because of invalid inputs. + + @dependencies + None. +*/ +int qurt_thread_stid_set2(unsigned int thread_id, unsigned int stid); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_get_running_ids + Returns the thread IDs of the running threads in the system; use only during fatal error handling. + + @datatypes + #qurt_thread_t + + @param[in,out] * Array of thread identifier of size #QURT_MAX_HTHREAD_LIMIT + 1. + + @return + #QURT_EINVALID -- Incorrect argument \n + #QURT_ENOTALLOWED -- API not called during error handling \n + #QURT_EOK -- Success, returns a NULL-terminated array of thread_id + + @dependencies + None. + */ +int qurt_thread_get_running_ids(qurt_thread_t *); +/** @endcond */ + + +/**@ingroup func_qurt_thread_get_thread_id + Gets the thread identifier of the thread with the matching name in the same process + of the caller. + + @datatypes + #qurt_thread_t + + @param[out] thread_id Pointer to the thread identifier. + @param[in] name Pointer to the name of the thread. + + @return + #QURT_EINVALID -- No thread with matching name in the process of the caller \n + #QURT_EOK -- Success + + @dependencies + None. + */ +int qurt_thread_get_thread_id (qurt_thread_t *thread_id, char *name); + +/**@ingroup func_qurt_sleep + Suspends the current thread for the specified amount of time. + + @note1hang Because QuRT timers are deferrable, this call is guaranteed to block + at least for the specified amount of time. If power-collapse is + enabled, the maximum amount of time this call can block depends on + the earliest wakeup from power-collapse past the specified duration. + + @param[in] duration Duration (in microseconds) for which the thread is suspended. + + @return + None. + + @dependencies + None. + */ +void qurt_sleep (unsigned long long int duration); + + +/**@ingroup func_qurt_system_set_priority_floor + Sets a priority floor to move threads with thread priority lower than the floor out of the running state. + Running threads with thread priority lower than the priority floor are moved into the kernel ready queue, and they + are not scheduled to run when the thread priority is lower than the floor. + Later the caller should reset the priority floor back to the default value of QURT_PRIORITY_FLOOR_DEFAULT. + Threads in the kernel ready queue are scheduled to run when the thread priority is higher than the floor. + + The priority floor is set and associated to the user process of the caller. When the caller gets into QuRTOS and + sets a new floor, the new floor is associated to its original user process, not the QuRTOS process. + The floor associated to the user process is reset when the user process exits or is killed, but not at the time + when the user thread of the caller exits. + + The priority floor cannot be set to a priority higher than the thread priority of the caller. + + The priority floor cannot be set to a priority lower than the default #QURT_PRIORITY_FLOOR_DEFAULT system floor. + + This function is not supported in Island mode. + + After the system floor is set above QURT_PRIORITY_FLOOR_DEFAULT, power collapse is skipped, and sleep task + is not scheduled to run. + + @param[in] priority_floor Priority floor. + + @return + #QURT_EOK -- Success \n + #QURT_ENOTALLOWED -- Floor setting is not allowed + + @dependencies + None. + */ +int qurt_system_set_priority_floor (unsigned int priority_floor); + + +/**@ingroup func_qurt_thread_suspend_thread + Suspend a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent process. + After the target thread is suspended, the kernel will not schedule it to run until it is resumed later. + + If the target thread is set as non-suspendable, this function call returns an error without suspending + the target thread. + + If the target thread is already suspended, this function call returns success to confirm + the target thread suspend. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + suspending the target thread. + + If the target thread is running in the guest OS/root process via a QDI call, this function call does not suspend + the target thread in guest OS, but marks the target thread as suspend-pending. The target thread is + suspended when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success even with the #QURT_THREAD_SUSPEND_SYNCHRONOUS option, while the target + thread can runn in the guest OS, and is suspended when exiting the guest OS. + + QuRT debug monitor threads that are in a user process are non-suspendable. This function does not suspend + those threads. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, multiple options can be ORed. \n + #QURT_THREAD_SUSPEND_SYNCHRONOUS (default) -- set to synchronous function call, + the function returns after the thread is completely suspended.\n + #QURT_THREAD_SUSPEND_ASYNCHRONOUS -- set to asynchronous function call, the function returns + after the kernel acts to suspend the target thread. The target thread + might still be running before it is completely suspended. \n + #QURT_THREAD_SUSPEND_KEEP_HMX (default) -- keep the HMX attachment on the target thread + if it locks the HMX with qurt_hmx_lock(). In this case, the HMX cannot be re-used by other threads. \n + #QURT_THREAD_SUSPEND_DETACH_HMX -- detach HMX from the target thread if it locks the HMX with qurt_hmx_lock(). + Later when the target thread resumes, the HMX is re-attached to the thread. Note that, this option is only + supported for the caller from the same user process of the target thread, not for a caller from the parent + process of the target thread, or other processes. With the HMX detach option, Qurt does not save the HMX + context. Thus, the HMX context state will be lost. It is the responsibility of caller to ensure HMX operations + and its context state saving when calling qurt_thread_suspend_thread() with the HMX detach option. + If a thread from another process uses this detach option, QURT_EHMXNOTDETACHABLE will be returned; in this + case, if the caller is qualified to suspend the target thread, the target thread will be moved to suspended + state without HMX detached. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in secure process/CPZ process. + #QURT_EHMXNOTDETACHABLE -- Failure because HMX is not detachable from the target thread. + + @dependencies + None. + */ +int qurt_thread_suspend_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_resume_thread + Resume a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent + process. After the target thread resumes, the kernel scheduler can schedule the thread to run based on + the thread priority. + + There is an option argument in this function, with only one default option as of now, + QURT_THREAD_RESUME_DEFAULT: resume the target thread in default way. + + By default, this is an asynchronous function. The function returns after kernel moves the + target thread from suspended state to runnable state. The thread is scheduled to run based on its + thread priority. + + If the target thread is set as non-resumable, this function call does not resume the target thread. + + If the target thread has already resumed, this function confirms that the target thread resumes + by returning success. + + If the target thread is in a secure user process or CPZ process, this function call returns an error without + resuming the operation. + + If the target thread runs in the guest OS/root process via a QDI call, this function call clears the mark of + suspend-pending on the target thread, and the target thread is not suspended when it exits the + guest OS. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, #QURT_THREAD_RESUME_DEFAULT, which resumes the target thread. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + #QURT_EHMXNOTAVAIL -- Failure because when resume a HMX thread, the HMX is not available/free for the HMX thread resume. + + @dependencies + None. + */ +int qurt_thread_resume_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_set_thread_property + Set a QuRT thread property with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be from the same user process of the target thread, or from its parent process. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + changing the property of the target thread. + + @param[in] thread_id Thread identifier \n + @param[in] property_id Thread property identifier \n + #QURT_THREAD_PROPERTY_SUSPENDABLE -- thread is suspendable. Default is TRUE. \n + #QURT_THREAD_PROPERTY_RESUMEABLE -- thread is resumable. Default is TRUE + @param[in] value Proper value: \n + TRUE(1) -- TRUE for the property \n + FALSE(0) -- FALSE for the property + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_thread_set_thread_property( unsigned int thread_id, unsigned int property_id, unsigned int value ); + +/**@ingroup func_qurt_thread_get_group_id + Get the group id of the thread specified by thread_id.\n + + @param[in] thread_id Thread identifier + @param[out] group_id Pointer to the variable of group identifier + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Thread id is invalid, or the process has no groups enabled \n + #QURT_ENOTALLOWED -- Operation is not allowed \n + + @dependencies + None. +*/ +int qurt_thread_get_group_id(qurt_thread_t thread_id, unsigned int* group_id); + +#endif /* __ASSEMBLER__ */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread_context.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread_context.h new file mode 100755 index 0000000000000..bab09deec8889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_thread_context.h @@ -0,0 +1,234 @@ +#ifndef QURT_THREAD_CONTEXT_H +#define QURT_THREAD_CONTEXT_H +/** + @file qurt_thread_context.h + @brief Kernel thread context structure + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond internal_only */ + +#define THREAD_ITERATOR_END ((qurt_thread_t)(-1)) /**< Thread iterator is complete. */ + + +/**@ingroup func_qurt_thread_iterator_create +Gives the ability to the caller to enumerate threads in the system. + +@return +Handle of the newly created iterator must be passed for +subsequent operations on the iterator. + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_create(void) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_OS_THREAD_ITERATOR_CREATE); +} + +/**@ingroup func_qurt_thread_iterator_next +Iterates over the list of threads in the system. + +@datatypes +#qurt_thread_t + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#THREAD_ITERATOR_END -- iterator has reached the end of the thread list. \n +Other values indicate a valid thread_id. + +@dependencies +None. +*/ +static inline qurt_thread_t qurt_thread_iterator_next(int iter) +{ + return (qurt_thread_t)qurt_qdi_handle_invoke(iter, QDI_OS_THREAD_ITERATOR_NEXT); +} + +/**@ingroup func_qurt_thread_iterator_destroy +Cleans up thread iterator resources. + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#QURT_EOK -- Successful completion of operation \n +#QURT_EFATAL -- Invalid handle passed + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_destroy(int iter) +{ + return qurt_qdi_close(iter); +} + +/**@ingroup func_qurt_thread_context_get_tname +Gets the name of the thread from the specified thread ID. + +@param[in] thread_id Thread for which name is returned. +@param[in,out] name Pointer to the local buffer where name is copied back. +@param[in] max_len Size of the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_tname(unsigned int thread_id, char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_context_get_prio +Gets the priority for the specified thread. + +@param[in] thread_id Thread for which priority is returned. +@param[in,out] prio Pointer to the local variable where priority is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_prio(unsigned int thread_id, unsigned char *prio); + +/**@ingroup func_qurt_thread_context_get_pcycles +Gets pcycles for the specified thread. + +@param[in] thread_id Thread for which processor cycles are returned. +@param[in,out] pcycles Pointer to the local variable where processor cycles are written. + +@return +#QURT_EOK -- Success \n +Failure otherwise. + +@dependencies +None. +*/ +int qurt_thread_context_get_pcycles(unsigned int thread_id, unsigned long long int *pcycles); + +/**@ingroup func_qurt_thread_context_get_stack_base +Gets the stack base address for the specified thread. + +@param[in] thread_id Thread for which stack base address is returned. +@param[in,out] sbase Pointer to the local variable where stack base address is written. + +@return +QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_base(unsigned int thread_id, unsigned int *sbase); + +/**@ingroup func_qurt_thread_context_get_stack_size +Gets the stack size for the specified thread. + +@param[in] thread_id Thread for which stack size is returned. +@param[in,out] ssize Pointer to the local variable where stack size is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_size(unsigned int thread_id, unsigned int *ssize); + +/**@ingroup func_qurt_thread_context_get_pid +Gets the process ID for the specified thread. + +@param[in] thread_id Thread for which process ID is returned. +@param[in,out] pid Pointer to the local variable where process id is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pid(unsigned int thread_id, unsigned int *pid); + +/**@ingroup func_qurt_thread_context_get_pname +Gets the process name for the specified thread. + +@param[in] thread_id Represents the thread for which process name is returned. +@param[in, out] name Pointer to the local buffer where process name is copied back. +@param[in] len Length allocated to the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pname(unsigned int thread_id, char *name, unsigned int len); + +/** @addtogroup thread_types +@{ */ +/** Structure that defines how TCB is interpreted to crash dump tools.*/ +/* Keys are defined in consts.h */ +struct qurt_debug_thread_info { +/** @cond */ + char name[QURT_MAX_NAME_LEN]; /**< Name of the thread. */ + struct { + unsigned key; + unsigned val; + } os_info[40]; + unsigned gen_regs[32]; /**< General mode registers. */ + unsigned user_cregs[32]; /**< User mode registers. */ + unsigned guest_cregs[32]; /**< Guest mode registers. */ + unsigned monitor_cregs[64]; /**< Monitor mode registers. */ +/** @endcond */ +}; /* should add up to 1K */ +/** @} */ /* end_addtogroup thread_types */ + + +/**@ingroup func_qurt_system_tcb_dump_get +Cleans up thread iterator resources. + +@datatypes +#qurt_thread_t + +@param[in] thread_id Thread on which the operation must be performed. +@param[in, out] ptr Pointer to the local buffer where contents are written. +@param[in] size Size of the debug thread information structure obtained by calling + qurt_system_tcb_dump_get_size(). + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_system_tcb_dump_get(qurt_thread_t thread_id, void *ptr, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_CONTEXT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_timer.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_timer.h new file mode 100755 index 0000000000000..7bdfdb8f3c3df --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_timer.h @@ -0,0 +1,560 @@ +#ifndef QURT_TIMER_H +#define QURT_TIMER_H +/** + @file qurt_timer.h + @brief Prototypes of qurt_timer API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include "qurt_anysignal.h" +#include "qurt_signal2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@addtogroup timer_const_macros +@{ */ +/** + Default values. +*/ +/** @xreflabel{hdr:QURT_TIMER_ONESHOT}*/ +#define QURT_TIMER_DEFAULT_TYPE QURT_TIMER_ONESHOT /**< One shot.*/ +#define QURT_TIMER_DEFAULT_DURATION 1000uL /**< Default duration. */ +#define QURT_TIMER_DEFAULT_EXPIRY 0uL /**< Default expiration. */ + +/** + Conversion from microseconds to timer ticks. + */ +#define QURT_TIMER_TIMETICK_FROM_US(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_TIMER_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** Minimum microseconds value is 100 microseconds (sleep timer).*/ +#define QURT_TIMER_MIN_DURATION 100uL + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_TIMER_MAX_DURATION QURT_SYSCLOCK_MAX_DURATION + +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_TIMER_MAX_DURATION_TICKS QURT_SYSCLOCK_MAX_DURATION_TICKS + +/** + Sleep timer error margin for Qtimer is 1,000 ticks ~52 us. +*/ +#define QURT_TIMETICK_ERROR_MARGIN QURT_SYSCLOCK_ERROR_MARGIN + +/* + qurt_timer group defines. +*/ +#define QURT_TIMER_MAX_GROUPS 5U /**< Maximum groups.*/ +#define QURT_TIMER_DEFAULT_GROUP 0U /**< Default groups. */ +/** @} */ /* end_addtogroup timer_const_macros */ + +/** @addtogroup timer_types +@{ */ +/** + QuRT timer types. + */ +typedef enum +{ + QURT_TIMER_ONESHOT = 0, /**< One shot.*/ + /** @xreflabel{hdr:QURT_TIMER_PERIODIC}*/ + QURT_TIMER_PERIODIC /**< Periodic. */ +} qurt_timer_type_t; + + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT timer type.*/ +typedef unsigned int qurt_timer_t; + +/** QuRT timer duration type. */ +typedef unsigned long long qurt_timer_duration_t; + +/** QuRT timer time type. */ +typedef unsigned long long qurt_timer_time_t; + +typedef void (*pfn_t)(void); +/** QuRT timer attribute type. */ +typedef struct +{ + /** @cond */ + unsigned int magic; /**< Magic number to verify the qmsgq_attr_t pointer. */ + + qurt_timer_duration_t duration; /**< Specifies the duration of the new timer. */ + + qurt_timer_time_t expiry; /**< Specifies the absolute expiry of the new timer. */ + + qurt_timer_duration_t remaining; /**< Specifies the remaining time of an active timer. */ + + qurt_timer_type_t type; /**< Specifies the timer type; only #QURT_TIMER_ONESHOT and + #QURT_TIMER_PERIODIC are supported. */ + + unsigned int group; /**< Group number of the timer; the criterion used to disable or enable the set + of timers. */ + pfn_t pFn; /**< Callback other than the signal set */ + /** @endcond */ +} +qurt_timer_attr_t; + +/** @} */ /* end_addtogroup timer_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_timer_stop + @xreflabel{sec:qurt_timer_stop} + Stops a running timer. + The timer must be a one-shot timer. + + @note1hang Restart stopped timers with the timer restart operation, + see Section @xref{sec:qurt_timer_restart}. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one shot timer. \n + #QURT_EMEM -- Out of memory error. + + @dependencies + None. + */ +int qurt_timer_stop (qurt_timer_t timer); + +/**@ingroup func_qurt_timer_restart + @xreflabel{sec:qurt_timer_restart} + Restarts a stopped timer with the specified duration. The timer must be a one-shot timer. + Timers stop after they have expired or after they are explicitly stopped with qurt_timer_stop(). + A restarted timer expires after the specified duration, the starting time is when the function is called. + + @note1hang Timers stop after they have expired or after they are explicitly + stopped with the timer stop operation, see Section @xref{sec:qurt_timer_stop}. + + @datatypes + #qurt_timer_t \n + #qurt_timer_duration_t + + @param[in] timer Timer object. + @param[in] duration Timer duration (in microseconds) before the restarted timer + expires again. + The valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one-shot timer. \n + #QURT_EMEM -- Out-of-memory error. + + @dependencies + None. + */ +int qurt_timer_restart (qurt_timer_t timer, qurt_timer_duration_t duration); + + +/**@ingroup func_qurt_timer_create + Creates a timer.\n + Allocates and initializes a timer object, and starts the timer. + + @note1hang A timer event handler must be defined to wait on the specified signal + to handle the timer event. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t \n + #qurt_anysignal_t + + @param[out] timer Pointer to the created timer object. + @param[in] attr Pointer to the timer attribute structure. + @param[in] signal Pointer to the signal object set when timer expires. + @param[in] mask Signal mask, which specifies the signal to set in the signal object when the + time expires. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to create the timer. \n + #QURT_EINVALID -- One of the arguments in the attr field is invalid. \n + Other error code -- Operation failed. \n + + @dependencies + None. + */ +int qurt_timer_create (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_anysignal_t *signal, unsigned int mask); + +int qurt_timer_create_sig2 (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_timer_attr_init + Initializes the specified timer attribute structure with default attribute values: \n + - Timer duration -- #QURT_TIMER_DEFAULT_DURATION (Section @xref{dox:timers}) \n + - Timer type -- #QURT_TIMER_ONESHOT \n + - Timer group -- #QURT_TIMER_DEFAULT_GROUP + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_init(qurt_timer_attr_t *attr); + + +/*Tech Comm note: removed qurt_timer_attr_set_pfn from documentation 9/10/2020 +@ingroup func_qurt_timer_attr_set_pfn + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + @param[in] pFn pFn. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_pfn(qurt_timer_attr_t *attr, pfn_t pFn); + + +/**@ingroup func_qurt_timer_attr_set_duration + Sets the timer duration in the specified timer attribute structure.\n + + The timer duration specifies the interval (in microseconds) between the creation of the + timer object and the generation of the corresponding timer event. + + The timer duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). Otherwise, the set operation is ignored. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] duration Timer duration (in microseconds). + Valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_attr_set_expiry + Sets the absolute expiry time in the specified timer attribute structure.\n + The timer expiry specifies the absolute time (in microseconds) of the generation of the + corresponding timer event.\n + Timer expiries are relative to when the system first began executing. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_time_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] time Timer expiry. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_expiry(qurt_timer_attr_t *attr, qurt_timer_time_t time); + +/**@ingroup func_qurt_timer_attr_get_duration + Gets the timer duration from the specified timer attribute structure. + The value returned is the duration that was originally set for the timer. + + @note1hang This function does not return the remaining time of an active timer; + use qurt_timer_attr_get_remaining() to get the remaining time. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attributes object + @param[out] duration Pointer to the destination variable for timer duration. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t *duration); + +/**@ingroup func_qurt_timer_attr_get_remaining + Gets the timer remaining duration from the specified timer attribute structure. \n + + The timer remaining duration indicates (in microseconds) how much time remains before + the generation of the next timer event on the corresponding timer. + In most cases this function assumes that the timer attribute structure was obtained by + calling qurt_timer_get_attr(). + + @note1hang This attribute is read-only and thus has no set operation defined for it. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attribute object. + @param[out] remaining Pointer to the destination variable for remaining time. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_remaining(qurt_timer_attr_t *attr, qurt_timer_duration_t *remaining); + +/**@ingroup func_qurt_timer_attr_set_type + Sets the timer type in the specified timer attribute structure. + + The timer type specifies the functional behavior of the timer: \n + - A one-shot timer (#QURT_TIMER_ONESHOT) waits for the specified timer duration + and then generates a single timer event. After this the timer is nonfunctional. \n + - A periodic timer (#QURT_TIMER_PERIODIC) repeatedly waits for the specified + timer duration and then generates a timer event. The result is a series of timer + events with interval equal to the timer duration. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] type Timer type. Values are: \n + - #QURT_TIMER_ONESHOT -- One-shot timer. \n + - #QURT_TIMER_PERIODIC -- Periodic timer. @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_type(qurt_timer_attr_t *attr, qurt_timer_type_t type); + +/**@ingroup func_qurt_timer_attr_get_type + Gets the timer type from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] type Pointer to the destination variable for the timer type. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_type(qurt_timer_attr_t *attr, qurt_timer_type_t *type); + +/**@ingroup func_qurt_timer_attr_set_group + Sets the timer group identifier in the specified timer attribute structure.\n + The timer group identifier specifies the group that the timer belongs to. Timer groups are + used to enable or disable one or more timers in a single operation. \n + The timer group identifier value must be between 0 and (#QURT_TIMER_MAX_GROUPS - 1). + See Section @xref{dox:timers}. + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the timer attribute object. + @param[in] group Timer group identifier; + Valid range is 0 to (#QURT_TIMER_MAX_GROUPS - 1). + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_group(qurt_timer_attr_t *attr, unsigned int group); + +/**@ingroup func_qurt_timer_attr_get_group + Gets the timer group identifier from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] group Pointer to the destination variable for the timer group identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_group(qurt_timer_attr_t *attr, unsigned int *group); + +/**@ingroup func_qurt_timer_get_attr + @xreflabel{hdr:qurt_timer_get_attr} + Gets the timer attributes of the specified timer when it was created. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t + + @param[in] timer Timer object. + @param[out] attr Pointer to the destination structure for timer attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_get_attr(qurt_timer_t timer, qurt_timer_attr_t *attr); + +/**@ingroup func_qurt_timer_delete + Deletes the timer.\n + Destroys the specified timer and deallocates the timer object. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_delete(qurt_timer_t timer); + +/**@ingroup func_qurt_timer_sleep + Suspends the current thread for the specified amount of time. + The sleep duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). + + @datatypes + #qurt_timer_duration_t + + @param[in] duration Interval (in microseconds) between when the thread is suspended + and when it is re-awakened. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to perform the operation. + + @dependencies + None. + */ + +int qurt_timer_sleep(qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_group_disable + Disables all timers that are assigned to the specified timer group. + If a specified timer is already disabled, ignore it. + If a specified timer is expired, do not process it. + If the specified timer group is empty, do nothing. + + @note1hang When a timer is disabled its remaining time does not change, thus it + cannot generate a timer event. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_disable (unsigned int group); + +/**@ingroup func_qurt_timer_group_enable + Enables all timers that are assigned to the specified timer group. + If a specified timer is already enabled, ignore it. + If a specified timer is expired, process it. + If the specified timer group is empty, do nothing. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_enable (unsigned int group); + + +/** + Notifies the timer server recovery from power collapse. The server + must account for any missed interrupts during power collapse. + */ +void qurt_timer_recover_pc (void); + +/** + Determines whether the Qtimer is initialized. + + @return + 0 -- Not initialized. \n + Nonzero -- Initialized. + */ +static inline int qurt_timer_is_init (void) {return 1;} + +/**@ingroup func_qurt_timer_get_ticks + Gets current ticks. The ticks are accumulated since the RTOS + has started. Each tick is equal to a single timer clock + cycle, where the frequency is 32 KHz on RGPT or 19.2 MHz on Qtimer. + + @return + Ticks since system started. + */ +unsigned long long qurt_timer_get_ticks (void); + +#define qurt_timer_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TIMER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tlb.h new file mode 100755 index 0000000000000..b1b2d261d31c0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tlb.h @@ -0,0 +1,215 @@ +#ifndef QURT_TLB_H +#define QURT_TLB_H + +/** + @file qurt_tlb.h + @brief Prototypes of TLB API + The TLB APIs allow explicit control of the portion of TLB between TLB_first_replaceble and TLB_LAST_REPLACEABLE. + Both are nonconfigurable for the time being. This portion of TLB is permanently assigned/locked unless manually removed + by qurt_tlb_remove. Implementation does not change depending on the configuration, such as whether CONFIG_STATIC is set or not. + In CONFIG_STATIC=y, TLB_LAST_REPLACEABLE is set to the last TLB index, which indicates that the entire TLB is permanently + assigned and is not backed up by page table (page table does not exist). TLB indicies are maintained through a 64-bit bitmask. + A new entry is placed in the first available slot. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tlb_entry_create + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (such as if the address is not aligned with the + size), the entry is created and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the ASID argument to -1. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr Physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry is not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry is not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry is not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_t paddr, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_create_64 + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (the address is not aligned with the + size), the entry is not created, and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the asid argument to -1. + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr_64 64-bit physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry was not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry was not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry was not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create_64 (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_delete + Deletes the specified TLB entry from the TLB of the Hexagon processor. + If the specified entry does not exist, no deletion occurs and an error result is returned. + + @param[in] entry_id TLB entry identifier. + + @return + #QURT_EOK -- TLB entry successfully deleted. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_delete (unsigned int entry_id); + +/**@ingroup func_qurt_tlb_entry_query + Searches for the specified TLB entry in the TLB of the Hexagon processor. + If the TLB entry is found, its entry identifier is returned. + + @datatypes + #qurt_addr_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_query (unsigned int *entry_id, qurt_addr_t vaddr, int asid); + +/**@ingroup func_qurt_tlb_entry_set + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[in] entry 64-bit TLB entry to store. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set (unsigned int entry_id, unsigned long long int entry); + +/**@ingroup func_qurt_tlb_entry_get + Gets the TLB entry. \n + Returns the specified 64-bit TLB entry in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[out] entry 64-bit TLB entry. + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_get (unsigned int entry_id, unsigned long long int *entry); + +/**@ingroup func_qurt_tlb_get_pager_physaddrs + Searches the TLB of the Hexagon processor, and returns all physical addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_phys_addrs Pointer to the return array of pager physical addresses. + + @return + Integer -- Number of addresses returned in array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_physaddr(unsigned int** pager_phys_addrs); + +/**@ingroup func_qurt_tlb_get_pager_virtaddr + Searches the TLB of the Hexagon processor, and returns all virtual addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_virt_addrs Pointer to the return array of pager virtual addresses. + + @return + Integer -- Number of addresses returned in the array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_virtaddr(unsigned int** pager_virt_addrs); + + +/**@ingroup func_qurt_tlb_entry_set2 + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. An additional option can be passed + to lock the TLB entry in the TLB of the Hexagon processor. + + @param[in] id TLB entry identifier. + @param[in] tlb 64-bit TLB entry to store. + @param[in] lock Nonzero value indicates that the TLB entry must be locked in the hardware TLB. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set2(unsigned id, unsigned long long tlb, unsigned lock); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLB_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tls.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tls.h new file mode 100755 index 0000000000000..6ec3b39ff5cb0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_tls.h @@ -0,0 +1,100 @@ +#ifndef QURT_TLS_H +#define QURT_TLS_H +/** + @file qurt_tls.h + @brief Prototypes of TLS APIs + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tls_create_key + @xreflabel{sec:tls_create_key} + Creates a key for accessing a thread local storage data item.\n + Subsequent get and set operations use the key value. + + @note1hang The destructor function performs any clean-up operations needed by a thread + local storage item when its containing thread is deleted (Section @xref{sec:qurt_thread_exit}). + + @param[out] key Pointer to the newly created thread local storage key value. + @param[in] destructor Pointer to the key-specific destructor function. Passing NULL + specifies that no destructor function is defined for the key. + + @return + #QURT_EOK -- Key successfully created. \n + #QURT_ETLSAVAIL -- No free TLS key available. + + @dependencies + None. + */ +int qurt_tls_create_key (int *key, void (*destructor)(void *)); + +/**@ingroup func_qurt_tls_set_specific + Stores a data item to thread local storage along with the specified key. + + @param[in] key Thread local storage key value. + @param[in] value Pointer to user data value to store. + + @return + #QURT_EOK -- Data item successfully stored. \n + #QURT_EINVALID -- Invalid key. \n + #QURT_EFAILED -- Invoked from a non-thread context. + */ +int qurt_tls_set_specific (int key, const void *value); + +/**@ingroup func_qurt_tls_get_specific + Loads the data item from thread local storage. \n + Returns the data item that is stored in thread local storage with the specified key. + The data item is always a pointer to user data. + + @param[in] key Thread local storage key value. + + @return + Pointer -- Data item indexed by key in thread local storage. \n + 0 (NULL) -- Key out of range. + + @dependencies + None. + */ +void * __attribute__((section(".text.qurt_tls_get_specific "))) qurt_tls_get_specific (int key); + + +/**@ingroup func_qurt_tls_delete_key + Deletes the specified key from thread local storage. + + @note1hang Explicitly deleting a key does not execute any destructor function that is + associated with the key (Section @xref{sec:tls_create_key}). + + @param[in] key Thread local storage key value to delete. + + @return + #QURT_EOK -- Key successfully deleted. \n + #QURT_ETLSENTRY -- Key already free. + + @dependencies + None. + */ +int qurt_tls_delete_key (int key); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_trace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_trace.h new file mode 100755 index 0000000000000..541f8f1d34bf6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_trace.h @@ -0,0 +1,317 @@ +#ifndef QURT_TRACE_H +#define QURT_TRACE_H +/** + @file qurt_trace.h + @brief Prototypes of system call tracing helpers API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + GLOBAL VARIABLES +=============================================================================*/ +/** @cond internal_only */ +/** @addtogroup etm_macros +@{ */ +/* ETM trace types. */ +#define QURT_ETM_TYPE_PC_ADDR (1U<<0) /**< PC address.*/ +#define QURT_ETM_TYPE_MEMORY_ADDR (1U<<1) /**< Memory address. */ +#define QURT_ETM_TYPE_TESTBUS (1U<<2) /**< Test bus. */ +#define QURT_ETM_TYPE_CYCLE_ACCURATE (1U<<3) /**< Cycle accurate. */ +#define QURT_ETM_TYPE_CYCLE_COARSE (1U<<4) /**< Cycle coarse. */ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR) /**< PC and memory address. */ +#define QURT_ETM_TYPE_PC_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC address and test bus. */ +#define QURT_ETM_TYPE_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< Memory address and test bus.*/ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC, memory address, and test bus. */ + +/* ETM routes. */ +#define QURT_ETM_ROUTE_TO_QDSS 0U /**< ETM route to QDSS. */ +#define QURT_ETM_ROUTE_TO_Q6ETB 1U /**< ETM route to Q6ETB. */ + +/* ETM filters. */ +#define QURT_ETM_TRACE_FILTER_ALL_DEFAULT 0U /*< Filter all as default. */ +#define QURT_ETM_TRACE_FILTER_HNUM0 (1U<<0) /*< Filter HNUM0. */ +#define QURT_ETM_TRACE_FILTER_HNUM1 (1U<<1) /*< Filter HNUM1. */ +#define QURT_ETM_TRACE_FILTER_HNUM2 (1U<<2) /*< Filter HNUM2. */ +#define QURT_ETM_TRACE_FILTER_HNUM3 (1U<<3) /*< Filter HNUM3. */ +#define QURT_ETM_TRACE_FILTER_HNUM4 (1U<<4) /*< Filter HNUM4. */ +#define QURT_ETM_TRACE_FILTER_HNUM5 (1U<<5) /*< Filter HNUM5. */ +#define QURT_ETM_TRACE_FILTER_HNUM6 (1U<<6) /*< Filter HNUM6. */ +#define QURT_ETM_TRACE_FILTER_HNUM7 (1U<<7) /*< Filter HNUM7. */ +#define QURT_ETM_TRACE_FILTER_HNUM8 (1U<<8) /*< Filter HNUM8. */ +#define QURT_ETM_TRACE_FILTER_HNUM9 (1U<<9) /*< Filter HNUM9. */ +#define QURT_ETM_TRACE_FILTER_HNUM10 (1U<<10) /*< Filter HNUM10. */ +#define QURT_ETM_TRACE_FILTER_HNUM11 (1U<<11) /*< Filter HNUM11. */ +#define QURT_ETM_TRACE_FILTER_HNUM12 (1U<<12) /*< Filter HNUM12. */ +#define QURT_ETM_TRACE_FILTER_HNUM13 (1U<<13) /*< Filter HNUM13. */ +#define QURT_ETM_TRACE_FILTER_HNUM14 (1U<<14) /*< Filter HNUM14. */ +#define QURT_ETM_TRACE_FILTER_HNUM15 (1U<<15) /*< Filter HNUM15. */ +#define QURT_ETM_TRACE_FILTER_ALL QURT_ETM_TRACE_FILTER_ALL_DEFAULT + +#define QURT_ETM_TRACE_FILTER_CLUSTER0 (1<<16) /*< Filter trace cluster0 address. */ +#define QURT_ETM_TRACE_FILTER_CLUSTER1 (1<<17) /*< Filter trace cluster1 address. */ +#define QURT_ETM_TRACE_FILTER_PC_RANGE (1<<19) /*< Filter PC address range. */ + +/* ETM memory source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< ETM memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< ETM memory source of SAC* is data. */ + +/* Period between synchronization traces */ +#define QURT_ETM_ASYNC_PERIOD 0 /**< Async.*/ +#define QURT_ETM_ISYNC_PERIOD 1 /**< Isync.*/ +#define QURT_ETM_GSYNC_PERIOD 2 /**< Gsync. */ + +/* ETM enable flags */ +#define QURT_ETM_OFF 0U /**< ETM off. */ +#define QURT_ETM_ON 1U /**< ETM on. */ +/** @endcond */ +/** @} */ /* end_addtogroup etm_macros */ + +/** @addtogroup function_tracing_macro +@{ */ +/* ETM setup return values */ +#define QURT_ETM_SETUP_OK 0 /**< ETM setup OK. */ +#define QURT_ETM_SETUP_ERR 1 /**< ETM setup error. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* ETM breakpoint types */ +#define QURT_ETM_READWRITE_BRKPT 0U /**< ETM read/write breakpoint. */ +#define QURT_ETM_READ_BRKPT 1U /**< ETM read breakpoint. */ +#define QURT_ETM_WRITE_BRKPT 2U /**< ETM write breakpoint. */ +#define QURT_ETM_BRKPT_INVALIDATE 3U /**< Invalidate breakpoint. */ +/** @addtogroup function_tracing_macro +@{ */ +/* ATB status flags */ +#define QURT_ATB_OFF 0 /**< ATB off. */ +#define QURT_ATB_ON 1 /**< ATB on. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* DTM enable flags */ +#define QURT_DTM_OFF 0 /**< DTM off. */ +#define QURT_DTM_ON 1 /**< DTM on. */ + +/** @addtogroup function_tracing_datatypes +@{ */ +/**STM trace information. */ +typedef struct qurt_stm_trace_info { + /** @cond */ + unsigned int stm_port_addr[6]; /* STM port address to which trace data must be written.*/ + unsigned int thread_event_id; /* Event ID for context switches.*/ + unsigned int interrupt_event_id; /* Event ID for interrupts. */ + unsigned int marker; /* Marker value that must be written at the beginning of the trace. */ + /** @endcond */ +} qurt_stm_trace_info_t; +/** @} */ /* end_addtogroup function_tracing_datatypes */ +/*============================================================================= + GLOBAL FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_trace_get_marker + Gets the kernel trace marker.\n + Returns the current value of the kernel trace marker. + The marker consists of a hardware thread identifier and an index into the kernel trace + buffer. The trace buffer records kernel events. + + @note1hang Using this function with qurt_trace_changed() + determines whether certain kernel events occurred in a block of code. + + @return + Integer -- Kernel trace marker. + + @dependencies + None. +*/ +unsigned int qurt_trace_get_marker(void); + +/**@ingroup func_qurt_trace_changed + Determines whether specific kernel events have occurred. \n + Returns a value that indicates whether the specified kernel events are recorded in the + kernel trace buffer since the specified kernel trace marker was obtained. + + The prev_trace_marker parameter specifies a kernel trace marker that was obtained by calling + qurt_trace_get_marker(). + @cond rest_dist For more information on the mask value, see the description of the trace_mask element in + @xhyperref{80VB41992,80-VB419-92}. \n @endcond + + @note1hang Used with qurt_trace_get_marker(), this function determines whether + certain kernel events occurred in a block of code.\n + @note1cont This function cannot determine whether a specific kernel event type has + occurred unless that event type has been enabled in the trace_mask element + of the system configuration file. \n + @note1cont QuRT supports the recording of interrupt and context switch events only (such as + a trace_mask value of 0x3). + + @param[in] prev_trace_marker Previous kernel trace marker. + @param[in] trace_mask Mask value that indicates which kernel events to check for. + + @returns + 1 -- Kernel events of the specified type have occurred since the + specified trace marker was obtained.\n + 0 -- No kernel events of the specified type have occurred since the + specified trace marker was obtained. + + @dependencies + None. +*/ +int qurt_trace_changed(unsigned int prev_trace_marker, unsigned int trace_mask); + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup function_tracing_macro +@{ */ +#ifndef QURT_DEBUG +#define QURT_TRACE(str, ...) __VA_ARGS__ + /**< Function tracing is implemented with the QURT_TRACE debug macro, which + optionally generates printf statements both before and after every function call that is + passed as a macro argument. + + For example, in the following macro calls in the source code: + @code + QURT_TRACE(myfunc, my_func(33)) + + @endcode + generates the following debug output: + @code + myfile:nnn: my_func >>> calling my_func(33) + myfile:nnn: my_func >>> returned my_func(33) + @endcode + The debug output includes the source file and line number of the function call, along with + the text of the call. Compile the client source file with -D __FILENAME__ + defined for its file name. + + The library function qurt_printf() generates the debug output. + The QURT_DEBUG symbol controls generation of the debug output. If this symbol is + not defined, function tracing is not generated.\n + @note1hang The debug macro is accessed through the QuRT API header file. + */ +#else +#define QURT_TRACE(str, ...) \ + do { \ + qurt_printf("%s:%d: %s: >>> calling %s\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + __VA_ARGS__; \ + qurt_printf("%s:%d: %s: <<< %s returned\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + } while (0); +#endif +/** @} */ /* end_addtogroup function_tracing_macro */ + +/**@ingroup func_qurt_etm_set_pc_range + Sets the PC address range for ETM filtering. + Depending on the Hexagon core design, a maximum of four PC ranges are supported. + + @param[in] range_num 0 to 3. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_pc_range(unsigned int range_num, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_range + Sets the address range for ETM filtering. + It allows the user to select the source type of addresses - QURT_ETM_SOURCE_PC and QURT_ETM_SOURCE_DATA. + + @param[in] addr_source_type Type of the address source:\n + - #QURT_ETM_SOURCE_PC \n + - #QURT_ETM_SOURCE_DATA @tablebulletend + @param[in] trig_block_num 0 to 3. + @param[in] pid pid of the process + 1. Any valid PID number will enable the ASID based trace filtering. + 2. QURT_ETM_NO_PID - Disable the ASID based trace filtering. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_range(unsigned int addr_source_type, unsigned int trig_block_num, unsigned int pid, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_atb + Sets the advanced trace bus (ATB) state to notify QuRT that the ATB is actively enabled or disabled. + QuRT performs the corresponding actions at low power management. + + @param[in] flag Values: \n + #QURT_ATB_ON \n + #QURT_ATB_OFF + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure + + @dependencies + None. +*/ +unsigned int qurt_etm_set_atb(unsigned int flag); + +/**@ingroup func_qurt_etm_set_sync_period + Sets the period for types of synchronization trace packets. \n + ASYNC defines the period between alignment synchronization packets. + Period is in terms of bytes in the packet stream. \n + ISYNC defines the period between instruction synchronization packets. + Period is per thread and is defined as the bytes sent out for that thread. \n + GSYNC is the defined period in thread cycles between GSYNC packets. + + @param[in] sync_type Type of synchronization packets: \n + #QURT_ETM_ASYNC_PERIOD \n + #QURT_ETM_ISYNC_PERIOD \n + #QURT_ETM_GSYNC_PERIOD + @param[in] period Period value. + + @return + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. + */ +unsigned int qurt_etm_set_sync_period(unsigned int sync_type, unsigned int period); + +/**@ingroup func_qurt_stm_trace_set_config + Sets up a STM port for tracing events. + + @datatypes + #qurt_stm_trace_info_t + + @param[in] stm_config_info Pointer to the STM trace information used to set up the trace + in the kernel. + The strucure must have the following:\n + - One port address per hardware thread \n + - Event ID for context switches \n + - Event ID for interrupt tracing n + - Header or marker to identify the beginning of the trace. @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Failure; possibly because the passed port address is not in the page table. + + @dependencies + None. + */ +unsigned int qurt_stm_trace_set_config(qurt_stm_trace_info_t *stm_config_info); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TRACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_types.h new file mode 100755 index 0000000000000..bdb83a3fe2fb2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_types.h @@ -0,0 +1,294 @@ +#ifndef QURT_TYPES_H +#define QURT_TYPES_H +/** + @file qurt_types.h + @brief Contains types common to all configurations + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +//#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define PGA_BITFIELD_MASK(hi,lo) (((~0u)>>(31U-((hi)-(lo))))<<(lo)) +#define PGA_BITFIELD_GET(x,hi,lo) (((x)&PGA_BITFIELD_MASK((hi),(lo)))>>(lo)) +#define PGA_BITFIELD_INS(hi,lo,v) (((v)<<(lo))&PGA_BITFIELD_MASK((hi),(lo))) +#define PGA_BITFIELD_SET(x,hi,lo,v) ((x)=((x)&~PGA_BITFIELD_MASK((hi),(lo)))|PGA_BITFIELD_INS((hi),(lo),(v))) +#define QURT_PGATTR_C_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 3U, 0U) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 5U, 4U) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_C_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 3U, 0U, (v)) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 5U, 4U, (v)) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_MKRAW(v) ((qurt_pgattr_t){.pga_value = (v)}) +#define QURT_PGATTR_MK(c,a) QURT_PGATTR_MKRAW(PGA_BITFIELD_INS(3U,0U,(c))|PGA_BITFIELD_INS(5U,4U,(a))) + +/*return types for qurt_island_get_status2*/ +#define QURT_ISLAND_MODE_NORMAL 0U /**< Normal operating mode */ +#define QURT_ISLAND_MODE_ISLAND 1U /**< Island mode */ +#define QURT_ISLAND_MODE_EXITING 2U /**< In transition from Island mode to Normal mode */ + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/** @addtogroup memory_management_types +@{ */ +typedef unsigned int qurt_addr_t; /**< QuRT address type.*/ +typedef unsigned int qurt_paddr_t; /**< QuRT physical memory address type. */ +/** @cond rest_reg_dist */ +typedef unsigned long long qurt_addr_64_t; /**< QuRT 64-bit memory address type. */ +typedef unsigned long long qurt_paddr_64_t; /**< QuRT 64-bit physical memory address type. */ +typedef unsigned int qurt_mem_region_t; /**< QuRT memory regions type. */ +typedef unsigned int qurt_mem_fs_region_t; /**< QuRT memory FS region type. */ +/**@endcond */ +typedef unsigned int qurt_mem_pool_t; /**< QuRT memory pool type.*/ +typedef unsigned int qurt_size_t; /**< QuRT size type. */ +/** @cond */ +typedef unsigned long long qurt_mmu_entry_t;/**< QuRT MMU entry type. */ +#define QURT_PHYSPOOL_NAME_LEN (32) +typedef char qurt_physpool_name_t[QURT_PHYSPOOL_NAME_LEN]; + + +/* + * Mapping type + * + * QMEM_MAPPING_VIRTUAL is the default mode, in which the system + * picks up the available range of the virtual address, and maps it to + * available contiguous physical addresses. Physical-to-virtual + * is not guaranteed to be 1:1; both virtual and physical memory is + * contiguous. + * + * In QMEM_MAPPING_IDEMPOTENT mode, the user provides the physical address; + * the kernel allocates 1:1 physical-to-virtual memory. Primary use of + * of this mapping is to allocate physical-to-virtual memory 1:1. + * + * In QMEM_MAPPING_PHYS_CONTIGUOUS mode, the virtual address might + * not be the same as the physical address. But the physical address of the + * memory region is guaranteed to be contiguous starting at the provided + * address, it is required to provide a fixed physical address. The primary + * use of this mapping is to allocate physical memory from a particular + * address, where 1:1 physical-to-virtual is not required. + * + * QMEM_MAPPING_NONE mode must be used to reserve a virtual memory + * area (VMA); no physical memory is reserved or mapped to this virtual + * space; all standard qmem_region APIs apply to a VMA, however physical + * address is always INVALID_ADDR. qmem_region_create() in this mode + * returns a handle to the VMA, both virt_addr and phys_addr must + * be set to INVALID_ADDR, kernel allocates any available virtual + * memory of the specified size. Obtain the starting virtual address + * of VMA through qmem_region_attr_getvirtaddr(). + * Primary purpose of this mapping mode is to provide a mechanism for + * delayed binding in QuRT, for example reserve virtual memory and map it at + * some later time to possibly discontiguous physical blocks. Thus, a + * single VMA can be partitioned among several physical-virtual mappings + * created via qmem_region_create() with QMEM_VIRTUAL_FIXED mapping mode. + * Each VMA keeps track of associated mapped regions. + * Deletion of VMA succeeds only if all associated "virtual_fixed" + * regions are freed prior to VMA deletion. + * + * Use QMEM_MAPPING_VIRTUAL_FIXED mode to create a region + * from virtual space that has been reserved via qmem_region_create() + * with QMEM_MAPPING_NONE mapping. A valid virt_add is required, if + * phys_addr is specified, the kernel attempts to map it accordingly, + * if no phys_addr is specified, kernel maps any available physical + * memory. All standard qmem_region APIs apply to such region. Remapping + * a virtual range without prior freeing of the region is not permitted. + * When such region is deleted its corresponding VMA remains intact. + * + * QMEM_MAPPING_PHYS_DISCONTIGUOUS mode can obtain contiguous + * virtual memory but physical memory can be discontiguous. This method + * tries to club small physical memory blocks to obtain requested + * memory and is useful in case where there is no contiguous full block + * of requested size. If client does not need contiguous physical memory, + * (for example, if client does not use physical addressing), this helps + * use smaller physical memory blocks rather than using contiguous memory. + * Note: When memory is allocated through this method, physical address is + * not returned to the caller using the qurt_mem_region_attr_get() API as there might + * not be a single physical address. + * + */ +/**@endcond */ +/** QuRT memory region mapping type. */ +typedef enum { + QURT_MEM_MAPPING_VIRTUAL=0, /**< Default mode. The region virtual address range maps to an + available contiguous area of physical memory. For the most + efficient use of virtual memory, the QuRT system + chooses the base address in physical memory. This works for most memory + use cases.*/ + QURT_MEM_MAPPING_PHYS_CONTIGUOUS = 1, /**< The region virtual address space must be mapped to a + contiguous area of physical memory. This is necessary when the + memory region is accessed by external devices that bypass Hexagon + virtual memory addressing. The base address in physical + memory must be explicitly specified.*/ + QURT_MEM_MAPPING_IDEMPOTENT=2, /**< Region virtual address space maps + to the identical area of physical memory. */ + QURT_MEM_MAPPING_VIRTUAL_FIXED=3, /**< Virtual address space of the region maps either to the + specified area of physical memory or (if no area is specified) + to available physical memory. Use this mapping to create + regions from virtual space that was reserved by calling + qurt_mem_region_create() with mapping. */ + QURT_MEM_MAPPING_NONE=4, /**< Reserves a virtual memory area (VMA). Remapping a virtual range is not + permitted without first deleting the memory region. When such a region is + deleted, its corresponding virtual memory addressing remains intact. */ + QURT_MEM_MAPPING_VIRTUAL_RANDOM=7, /**< System chooses a random virtual address and + maps it to available contiguous physical addresses.*/ + QURT_MEM_MAPPING_PHYS_DISCONTIGUOUS=8, /**< While virtual memory is contiguous, allocates in discontiguous physical + memory blocks. This helps when there are smaller contiguous blocks + than the requested size. + Physical address is not provided as part of the get_attr call */ + QURT_MEM_MAPPING_INVALID=10, /**< Reserved as an invalid mapping type. */ +} qurt_mem_mapping_t; + + +/** QuRT cache mode type. */ +typedef enum { + QURT_MEM_CACHE_WRITEBACK=7, /**< Write back. */ + QURT_MEM_CACHE_NONE_SHARED=6, /**< Normal uncached memory that can be shared with other subsystems.*/ + QURT_MEM_CACHE_WRITETHROUGH=5, /**< Write through. */ + QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE=0, /**< Write back non-L2-cacheable.*/ + QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE=1, /**< Write through non-L2-cacheable. */ + QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE=QURT_MEM_CACHE_WRITEBACK, /**< Write back L2 cacheable. */ + QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE=QURT_MEM_CACHE_WRITETHROUGH, /**< Write through L2 cacheable. */ + QURT_MEM_CACHE_DEVICE = 4, /**< Volatile memory-mapped device. Access to device memory cannot be cancelled by interrupts, re-ordered, or replayed.*/ + QURT_MEM_CACHE_NONE = 4, /**< Deprecated -- use #QURT_MEM_CACHE_DEVICE instead. */ + QURT_MEM_CACHE_DEVICE_SFC = 2, /**< Enables placing limitations on the number of outstanding transactions. */ + QURT_MEM_CACHE_INVALID=10, /**< Reserved as an invalid cache type. */ +} qurt_mem_cache_mode_t; + +/** Memory access permission. */ +#define QURT_PERM_NONE 0x0U /**< No permission. */ +#define QURT_PERM_READ 0x1U /**< Read permission. */ +#define QURT_PERM_WRITE 0x2U /**< Write permission. */ +#define QURT_PERM_EXECUTE 0x4U /**< Execution permission. */ +#define QURT_PERM_NODUMP 0x8U + /**< Skip dumping the mapping. During process domain dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and DSP process + crashed before the mapping is removed. */ +#define QURT_PERM_FULL QURT_PERM_READ | QURT_PERM_WRITE | QURT_PERM_EXECUTE /**< Read, write, and execute permission. */ + +typedef unsigned char qurt_perm_t; + + +/** @cond rest_reg_dist*/ +/** QuRT cache type; specifies data cache or instruction cache. */ +typedef enum { + QURT_MEM_ICACHE, /**< Instruction cache.*/ + QURT_MEM_DCACHE /**< Data cache.*/ +} qurt_mem_cache_type_t; + +/** QuRT cache operation code type. */ +typedef enum { + QURT_MEM_CACHE_FLUSH, /**< Flush. */ + QURT_MEM_CACHE_INVALIDATE, /**< Invalidate */ + QURT_MEM_CACHE_FLUSH_INVALIDATE, /**< Flush invalidate. */ + QURT_MEM_CACHE_FLUSH_ALL, /**< Flush all. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_ALL, /**< Flush invalidate all. */ + QURT_MEM_CACHE_TABLE_FLUSH_INVALIDATE, /**< Table flush invalidate. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_L2, /**< L2 flush invalidate.*/ +} qurt_mem_cache_op_t; + +/** QuRT memory region type. */ +typedef enum { + QURT_MEM_REGION_LOCAL=0, /**< Local. */ + QURT_MEM_REGION_SHARED=1, /**< Shared.*/ + QURT_MEM_REGION_USER_ACCESS=2, /**< User access. */ + QURT_MEM_REGION_FS=4, /**< FS. */ + QURT_MEM_REGION_INVALID=10, /**< Reserved as an invalid region type. */ +} qurt_mem_region_type_t; + +/* Cache and bus attributes are combined into a value of this type for convenience, + and macros for combining and extracting fields are defined here. */ +/** @cond */ +struct qurt_pgattr { + unsigned pga_value; /**< PGA value.*/ +}; +typedef struct qurt_pgattr qurt_pgattr_t; +/** @endcond */ +/** QuRT memory region attributes type.*/ +/* QMEM_MAPPING_IDEMPOTENT and QMEM_MAPPING_PHYS_CONTIGUOUS mode can specify physaddr. + virtaddr cannot be specified for a memory region, it can only be queried by the + qmem_attr_getvirtaddr() function. + */ +typedef struct { + /** @cond */ + qurt_mem_mapping_t mapping_type; + unsigned char perms; + unsigned short owner; + qurt_pgattr_t pga; + unsigned ppn; //physical page number (physical>>12) + qurt_addr_t virtaddr; + qurt_mem_region_type_t type; + qurt_size_t size; + /** @endcond */ +} qurt_mem_region_attr_t; + + +/** QuRT user physical memory pool type. */ +typedef struct { + /** @cond */ + char name[32]; + struct ranges{ + unsigned int start; + unsigned int size; + } ranges[MAX_POOL_RANGES]; + /** @endcond */ +} qurt_mem_pool_attr_t; + +/** QuRT memory pool status type.*/ +typedef struct _qurt_mem_pool_status { + + qurt_size_t contig_size; /**< Largest contiguous free memory in bytes. */ + qurt_size_t free_size; /**< Total free memory in bytes. */ + qurt_size_t total_size; /**< Total declared memory in bytes. */ + +} qurt_mem_pool_status_t; + +typedef enum { + HEXAGON_L1_I_CACHE = 0, /**< Hexagon L1 instruction cache. */ + HEXAGON_L1_D_CACHE = 1, /**< Hexagon L1 data cache. */ + HEXAGON_L2_CACHE = 2 /**< Hexagon L2 cache. */ +} qurt_cache_type_t; + +typedef enum { + FULL_SIZE = 0, /**< Fully shared cache, without partitioning. */ + HALF_SIZE = 1, /**< 1/2 for main, 1/2 for auxiliary. */ + THREE_QUARTER_SIZE = 2, /**< 3/4 for main, 1/4 for auxiliary. */ + SEVEN_EIGHTHS_SIZE = 3 /**< 7/8 for main, 1/8 for auxiliary; for L2 cache only. */ +} qurt_cache_partition_size_t; + +typedef enum { + QURT_PROCESS_CB_GENERIC, /**< generic unconditional cb called after image loading. */ + QURT_PROCESS_NOTE_CB_PRE_MAP, /**< note cb called before segment loading. */ + QURT_PROCESS_NOTE_CB_POST_MAP /**< note cb called after segment loading. */ +} qurt_process_cb_type_t; + +typedef union { + void *ptr; + int num; +} qurt_process_callback_arg_t; + + +/**@endcond*/ + +/** @} */ /* end_addtogroup memory_management_types */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TYPES_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_user_dma.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_user_dma.h new file mode 100755 index 0000000000000..e05a6429fd703 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_user_dma.h @@ -0,0 +1,44 @@ +#ifndef QURT_USER_DMA_H +#define QURT_USER_DMA_H + +/** + @file qurt_user_dma.h + @brief Definitions, macros, and prototypes used for handling user DMA. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_user_dma_dmsyncht + Sends the DMSyncht command to the user DMA engine. + + Call this function to ensure all posted DMA memory operations are + complete. + + This stalls the current thread until the instruction + is complete and returns. + + @return + QURT_EOK - On dmsyncht completion \n + QURT_ENOTSUPPORTED - User DMA not supported + + @dependencies + None. +*/ +int qurt_user_dma_dmsyncht(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_vtlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_vtlb.h new file mode 100755 index 0000000000000..e064042e447ac --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/include/qurt/qurt_vtlb.h @@ -0,0 +1,76 @@ +/*============================================================================= + + qurt_vtlb.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef QURT_VTLB_H +#define QURT_VTLB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Names starting with "qurt_i_vtlb" are the internal low-level functions. +|| These should be considered subject to change. +*/ + +int qurt_i_vtlb_entry_create(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension); + +int qurt_i_vtlb_entry_create_with_pid(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension, + unsigned target_pid); + +int qurt_i_vtlb_entry_delete(unsigned index); + +int qurt_i_vtlb_entry_read(unsigned index, unsigned *tlbinfo); + +int qurt_i_vtlb_entry_write(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension); + +int qurt_i_vtlb_entry_write_with_pid(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension, unsigned target_pid); + +int qurt_i_vtlb_entry_probe(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex); + +int qurt_i_vtlb_entry_probe_with_pid(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex, unsigned target_pid); + + +int qurt_i_vtlb_statistics(unsigned *stats); // Returns stats[0] -- total number of VTLB entries + // stats[1] -- number of available VTLB entries + // stats[2] -- max size of VTLB tree since boot + +//can return index to an entry that was specialed, change it to take addresses instead of pages +int qurt_i_vtlb_set_special(int index, unsigned pageno, unsigned asid, unsigned size); + +int qurt_i_vtlb_queue_ppage(unsigned pageno, unsigned vtlb_index); + +#define QURT_VTLB_EXT_DEFAULT 0U +#define QURT_VTLB_EXT_LOCKED 1U +#define QURT_VTLB_EXT_EXCLUDE_DUMP 2U /* Temporary ability to skip certain mappings in pd dump */ +#define QURT_VTLB_EXT_FREELIST 0x800000u + +#define QURT_VTLB_ERR_OVERLAP -64 +#define QURT_VTLB_ERR_TREE_NO_SPACE -65 +#define QURT_VTLB_ERR_INVALID_SIZE -68 +#define QURT_VTLB_ERR_INVALID_EXT -69 +#define QURT_VTLB_ERR_DEL_PGT_LOCKED -70 +#define QURT_VTLB_ERR_PGT_LOCK_CNT -71 + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_VTLB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libposix.a new file mode 100755 index 0000000000000..f338fbee708ef Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurt.a new file mode 100755 index 0000000000000..e35606134ddfa Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurtcfs.a new file mode 100755 index 0000000000000..02250fa425ac4 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_island.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_island.a new file mode 100755 index 0000000000000..bce4fe8cc49b2 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_island.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_main.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_main.a new file mode 100755 index 0000000000000..041565908f9c6 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/libtimer_main.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libposix.a new file mode 100755 index 0000000000000..044c93bb65797 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurt.a new file mode 100755 index 0000000000000..a91e0fbb660b7 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurtcfs.a new file mode 100755 index 0000000000000..02250fa425ac4 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libtimer.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libtimer.a new file mode 100755 index 0000000000000..10bc3e63c2efc Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev73/lib/pic/libtimer.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/confname.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/confname.h new file mode 100755 index 0000000000000..d9ca3135501e3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/confname.h @@ -0,0 +1,528 @@ +#ifndef CONFNAME_H +#define CONFNAME_H +/** + @file confname.h + @brief Named literals for 'name' argument of sysconf, pathconf + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly. Instead include unistd.h. For now since + toolchain doesnt provide a hook by including bits/confname.h, we stick this + header in QuRT's sys/types.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum +{ + _PC_LINK_MAX, +#define _PC_LINK_MAX _PC_LINK_MAX + _PC_MAX_CANON, +#define _PC_MAX_CANON _PC_MAX_CANON + _PC_MAX_INPUT, +#define _PC_MAX_INPUT _PC_MAX_INPUT + _PC_NAME_MAX, +#define _PC_NAME_MAX _PC_NAME_MAX + _PC_PATH_MAX, +#define _PC_PATH_MAX _PC_PATH_MAX + _PC_PIPE_BUF, +#define _PC_PIPE_BUF _PC_PIPE_BUF + _PC_CHOWN_RESTRICTED, +#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED + _PC_NO_TRUNC, +#define _PC_NO_TRUNC _PC_NO_TRUNC + _PC_VDISABLE, +#define _PC_VDISABLE _PC_VDISABLE + _PC_SYNC_IO, +#define _PC_SYNC_IO _PC_SYNC_IO + _PC_ASYNC_IO, +#define _PC_ASYNC_IO _PC_ASYNC_IO + _PC_PRIO_IO, +#define _PC_PRIO_IO _PC_PRIO_IO + _PC_SOCK_MAXBUF, +#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF + _PC_FILESIZEBITS, +#define _PC_FILESIZEBITS _PC_FILESIZEBITS + _PC_REC_INCR_XFER_SIZE, +#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE + _PC_REC_MAX_XFER_SIZE, +#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE + _PC_REC_MIN_XFER_SIZE, +#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE + _PC_REC_XFER_ALIGN, +#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN + _PC_ALLOC_SIZE_MIN, +#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN + _PC_SYMLINK_MAX, +#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX + _PC_2_SYMLINKS +#define _PC_2_SYMLINKS _PC_2_SYMLINKS +}; + +/* Values for the argument to `sysconf'. */ +enum +{ + _SC_ARG_MAX, +#define _SC_ARG_MAX _SC_ARG_MAX + _SC_CHILD_MAX, +#define _SC_CHILD_MAX _SC_CHILD_MAX + _SC_CLK_TCK, +#define _SC_CLK_TCK _SC_CLK_TCK + _SC_NGROUPS_MAX, +#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX + _SC_OPEN_MAX, +#define _SC_OPEN_MAX _SC_OPEN_MAX + _SC_STREAM_MAX, +#define _SC_STREAM_MAX _SC_STREAM_MAX + _SC_TZNAME_MAX, +#define _SC_TZNAME_MAX _SC_TZNAME_MAX + _SC_JOB_CONTROL, +#define _SC_JOB_CONTROL _SC_JOB_CONTROL + _SC_SAVED_IDS, +#define _SC_SAVED_IDS _SC_SAVED_IDS + _SC_REALTIME_SIGNALS, +#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + _SC_PRIORITY_SCHEDULING, +#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + _SC_TIMERS, +#define _SC_TIMERS _SC_TIMERS + _SC_ASYNCHRONOUS_IO, +#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + _SC_PRIORITIZED_IO, +#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO + _SC_SYNCHRONIZED_IO, +#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + _SC_FSYNC, +#define _SC_FSYNC _SC_FSYNC + _SC_MAPPED_FILES, +#define _SC_MAPPED_FILES _SC_MAPPED_FILES + _SC_MEMLOCK, +#define _SC_MEMLOCK _SC_MEMLOCK + _SC_MEMLOCK_RANGE, +#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + _SC_MEMORY_PROTECTION, +#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + _SC_MESSAGE_PASSING, +#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING + _SC_SEMAPHORES, +#define _SC_SEMAPHORES _SC_SEMAPHORES + _SC_SHARED_MEMORY_OBJECTS, +#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + _SC_AIO_LISTIO_MAX, +#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX + _SC_AIO_MAX, +#define _SC_AIO_MAX _SC_AIO_MAX + _SC_AIO_PRIO_DELTA_MAX, +#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX + _SC_DELAYTIMER_MAX, +#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX + _SC_MQ_OPEN_MAX, +#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX + _SC_MQ_PRIO_MAX, +#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX + _SC_VERSION, +#define _SC_VERSION _SC_VERSION + _SC_PAGESIZE, +#define _SC_PAGESIZE _SC_PAGESIZE +#define _SC_PAGE_SIZE _SC_PAGESIZE + _SC_RTSIG_MAX, +#define _SC_RTSIG_MAX _SC_RTSIG_MAX + _SC_SEM_NSEMS_MAX, +#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX + _SC_SEM_VALUE_MAX, +#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX + _SC_SIGQUEUE_MAX, +#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX + _SC_TIMER_MAX, +#define _SC_TIMER_MAX _SC_TIMER_MAX + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, +#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX + _SC_BC_DIM_MAX, +#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX + _SC_BC_SCALE_MAX, +#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX + _SC_BC_STRING_MAX, +#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX + _SC_COLL_WEIGHTS_MAX, +#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX + _SC_EQUIV_CLASS_MAX, +#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX + _SC_EXPR_NEST_MAX, +#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX + _SC_LINE_MAX, +#define _SC_LINE_MAX _SC_LINE_MAX + _SC_RE_DUP_MAX, +#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX + _SC_CHARCLASS_NAME_MAX, +#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX + + _SC_2_VERSION, +#define _SC_2_VERSION _SC_2_VERSION + _SC_2_C_BIND, +#define _SC_2_C_BIND _SC_2_C_BIND + _SC_2_C_DEV, +#define _SC_2_C_DEV _SC_2_C_DEV + _SC_2_FORT_DEV, +#define _SC_2_FORT_DEV _SC_2_FORT_DEV + _SC_2_FORT_RUN, +#define _SC_2_FORT_RUN _SC_2_FORT_RUN + _SC_2_SW_DEV, +#define _SC_2_SW_DEV _SC_2_SW_DEV + _SC_2_LOCALEDEF, +#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF + + _SC_PII, +#define _SC_PII _SC_PII + _SC_PII_XTI, +#define _SC_PII_XTI _SC_PII_XTI + _SC_PII_SOCKET, +#define _SC_PII_SOCKET _SC_PII_SOCKET + _SC_PII_INTERNET, +#define _SC_PII_INTERNET _SC_PII_INTERNET + _SC_PII_OSI, +#define _SC_PII_OSI _SC_PII_OSI + _SC_POLL, +#define _SC_POLL _SC_POLL + _SC_SELECT, +#define _SC_SELECT _SC_SELECT + _SC_UIO_MAXIOV, +#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV + _SC_IOV_MAX = _SC_UIO_MAXIOV, +#define _SC_IOV_MAX _SC_IOV_MAX + _SC_PII_INTERNET_STREAM, +#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM + _SC_PII_INTERNET_DGRAM, +#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM + _SC_PII_OSI_COTS, +#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS + _SC_PII_OSI_CLTS, +#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS + _SC_PII_OSI_M, +#define _SC_PII_OSI_M _SC_PII_OSI_M + _SC_T_IOV_MAX, +#define _SC_T_IOV_MAX _SC_T_IOV_MAX + + /* Values according to POSIX 1003.1c (POSIX threads). */ + _SC_THREADS, +#define _SC_THREADS _SC_THREADS + _SC_THREAD_SAFE_FUNCTIONS, +#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + _SC_GETGR_R_SIZE_MAX, +#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX + _SC_GETPW_R_SIZE_MAX, +#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX + _SC_LOGIN_NAME_MAX, +#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX + _SC_TTY_NAME_MAX, +#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX + _SC_THREAD_DESTRUCTOR_ITERATIONS, +#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + _SC_THREAD_KEYS_MAX, +#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + _SC_THREAD_STACK_MIN, +#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN + _SC_THREAD_THREADS_MAX, +#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + _SC_THREAD_ATTR_STACKADDR, +#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + _SC_THREAD_ATTR_STACKSIZE, +#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + _SC_THREAD_PRIORITY_SCHEDULING, +#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + _SC_THREAD_PRIO_INHERIT, +#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + _SC_THREAD_PRIO_PROTECT, +#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + _SC_THREAD_PROCESS_SHARED, +#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + + _SC_NPROCESSORS_CONF, +#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF + _SC_NPROCESSORS_ONLN, +#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN + _SC_PHYS_PAGES, +#define _SC_PHYS_PAGES _SC_PHYS_PAGES + _SC_AVPHYS_PAGES, +#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES + _SC_ATEXIT_MAX, +#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX + _SC_PASS_MAX, +#define _SC_PASS_MAX _SC_PASS_MAX + + _SC_XOPEN_VERSION, +#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION + _SC_XOPEN_XCU_VERSION, +#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION + _SC_XOPEN_UNIX, +#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX + _SC_XOPEN_CRYPT, +#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT + _SC_XOPEN_ENH_I18N, +#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + _SC_XOPEN_SHM, +#define _SC_XOPEN_SHM _SC_XOPEN_SHM + + _SC_2_CHAR_TERM, +#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM + _SC_2_C_VERSION, +#define _SC_2_C_VERSION _SC_2_C_VERSION + _SC_2_UPE, +#define _SC_2_UPE _SC_2_UPE + + _SC_XOPEN_XPG2, +#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2 + _SC_XOPEN_XPG3, +#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3 + _SC_XOPEN_XPG4, +#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4 + + _SC_CHAR_BIT, +#define _SC_CHAR_BIT _SC_CHAR_BIT + _SC_CHAR_MAX, +#define _SC_CHAR_MAX _SC_CHAR_MAX + _SC_CHAR_MIN, +#define _SC_CHAR_MIN _SC_CHAR_MIN + _SC_INT_MAX, +#define _SC_INT_MAX _SC_INT_MAX + _SC_INT_MIN, +#define _SC_INT_MIN _SC_INT_MIN + _SC_LONG_BIT, +#define _SC_LONG_BIT _SC_LONG_BIT + _SC_WORD_BIT, +#define _SC_WORD_BIT _SC_WORD_BIT + _SC_MB_LEN_MAX, +#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX + _SC_NZERO, +#define _SC_NZERO _SC_NZERO + _SC_SSIZE_MAX, +#define _SC_SSIZE_MAX _SC_SSIZE_MAX + _SC_SCHAR_MAX, +#define _SC_SCHAR_MAX _SC_SCHAR_MAX + _SC_SCHAR_MIN, +#define _SC_SCHAR_MIN _SC_SCHAR_MIN + _SC_SHRT_MAX, +#define _SC_SHRT_MAX _SC_SHRT_MAX + _SC_SHRT_MIN, +#define _SC_SHRT_MIN _SC_SHRT_MIN + _SC_UCHAR_MAX, +#define _SC_UCHAR_MAX _SC_UCHAR_MAX + _SC_UINT_MAX, +#define _SC_UINT_MAX _SC_UINT_MAX + _SC_ULONG_MAX, +#define _SC_ULONG_MAX _SC_ULONG_MAX + _SC_USHRT_MAX, +#define _SC_USHRT_MAX _SC_USHRT_MAX + + _SC_NL_ARGMAX, +#define _SC_NL_ARGMAX _SC_NL_ARGMAX + _SC_NL_LANGMAX, +#define _SC_NL_LANGMAX _SC_NL_LANGMAX + _SC_NL_MSGMAX, +#define _SC_NL_MSGMAX _SC_NL_MSGMAX + _SC_NL_NMAX, +#define _SC_NL_NMAX _SC_NL_NMAX + _SC_NL_SETMAX, +#define _SC_NL_SETMAX _SC_NL_SETMAX + _SC_NL_TEXTMAX, +#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX + + _SC_XBS5_ILP32_OFF32, +#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32 + _SC_XBS5_ILP32_OFFBIG, +#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG + _SC_XBS5_LP64_OFF64, +#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64 + _SC_XBS5_LPBIG_OFFBIG, +#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG + + _SC_XOPEN_LEGACY, +#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY + _SC_XOPEN_REALTIME, +#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME + _SC_XOPEN_REALTIME_THREADS, +#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + _SC_ADVISORY_INFO, +#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO + _SC_BARRIERS, +#define _SC_BARRIERS _SC_BARRIERS + _SC_BASE, +#define _SC_BASE _SC_BASE + _SC_C_LANG_SUPPORT, +#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT + _SC_C_LANG_SUPPORT_R, +#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R + _SC_CLOCK_SELECTION, +#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION + _SC_CPUTIME, +#define _SC_CPUTIME _SC_CPUTIME + _SC_THREAD_CPUTIME, +#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME + _SC_DEVICE_IO, +#define _SC_DEVICE_IO _SC_DEVICE_IO + _SC_DEVICE_SPECIFIC, +#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC + _SC_DEVICE_SPECIFIC_R, +#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R + _SC_FD_MGMT, +#define _SC_FD_MGMT _SC_FD_MGMT + _SC_FIFO, +#define _SC_FIFO _SC_FIFO + _SC_PIPE, +#define _SC_PIPE _SC_PIPE + _SC_FILE_ATTRIBUTES, +#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES + _SC_FILE_LOCKING, +#define _SC_FILE_LOCKING _SC_FILE_LOCKING + _SC_FILE_SYSTEM, +#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM + _SC_MONOTONIC_CLOCK, +#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + _SC_MULTI_PROCESS, +#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS + _SC_SINGLE_PROCESS, +#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS + _SC_NETWORKING, +#define _SC_NETWORKING _SC_NETWORKING + _SC_READER_WRITER_LOCKS, +#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + _SC_SPIN_LOCKS, +#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS + _SC_REGEXP, +#define _SC_REGEXP _SC_REGEXP + _SC_REGEX_VERSION, +#define _SC_REGEX_VERSION _SC_REGEX_VERSION + _SC_SHELL, +#define _SC_SHELL _SC_SHELL + _SC_SIGNALS, +#define _SC_SIGNALS _SC_SIGNALS + _SC_SPAWN, +#define _SC_SPAWN _SC_SPAWN + _SC_SPORADIC_SERVER, +#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER + _SC_THREAD_SPORADIC_SERVER, +#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + _SC_SYSTEM_DATABASE, +#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE + _SC_SYSTEM_DATABASE_R, +#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R + _SC_TIMEOUTS, +#define _SC_TIMEOUTS _SC_TIMEOUTS + _SC_TYPED_MEMORY_OBJECTS, +#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + _SC_USER_GROUPS, +#define _SC_USER_GROUPS _SC_USER_GROUPS + _SC_USER_GROUPS_R, +#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R + _SC_2_PBS, +#define _SC_2_PBS _SC_2_PBS + _SC_2_PBS_ACCOUNTING, +#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + _SC_2_PBS_LOCATE, +#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE + _SC_2_PBS_MESSAGE, +#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE + _SC_2_PBS_TRACK, +#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK + _SC_SYMLOOP_MAX, +#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX + _SC_STREAMS, +#define _SC_STREAMS _SC_STREAMS + _SC_2_PBS_CHECKPOINT, +#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + + _SC_V6_ILP32_OFF32, +#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + _SC_V6_ILP32_OFFBIG, +#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + _SC_V6_LP64_OFF64, +#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + _SC_V6_LPBIG_OFFBIG, +#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + + _SC_HOST_NAME_MAX, +#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX + _SC_TRACE, +#define _SC_TRACE _SC_TRACE + _SC_TRACE_EVENT_FILTER, +#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + _SC_TRACE_INHERIT, +#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT + _SC_TRACE_LOG, +#define _SC_TRACE_LOG _SC_TRACE_LOG + + _SC_LEVEL1_ICACHE_SIZE, +#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE + _SC_LEVEL1_ICACHE_ASSOC, +#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC + _SC_LEVEL1_ICACHE_LINESIZE, +#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE + _SC_LEVEL1_DCACHE_SIZE, +#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE + _SC_LEVEL1_DCACHE_ASSOC, +#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC + _SC_LEVEL1_DCACHE_LINESIZE, +#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE + _SC_LEVEL2_CACHE_SIZE, +#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE + _SC_LEVEL2_CACHE_ASSOC, +#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC + _SC_LEVEL2_CACHE_LINESIZE, +#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE + _SC_LEVEL3_CACHE_SIZE, +#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE + _SC_LEVEL3_CACHE_ASSOC, +#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC + _SC_LEVEL3_CACHE_LINESIZE, +#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE + _SC_LEVEL4_CACHE_SIZE, +#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE + _SC_LEVEL4_CACHE_ASSOC, +#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC + _SC_LEVEL4_CACHE_LINESIZE, +#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE + /* Leave room here, maybe we need a few more cache levels some day. */ + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, +#define _SC_IPV6 _SC_IPV6 + _SC_RAW_SOCKETS, +#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS + + _SC_V7_ILP32_OFF32, +#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32 + _SC_V7_ILP32_OFFBIG, +#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG + _SC_V7_LP64_OFF64, +#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64 + _SC_V7_LPBIG_OFFBIG, +#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG + + _SC_SS_REPL_MAX, +#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX + + _SC_TRACE_EVENT_NAME_MAX, +#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + _SC_TRACE_NAME_MAX, +#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + _SC_TRACE_SYS_MAX, +#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + _SC_TRACE_USER_EVENT_MAX, +#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + + _SC_XOPEN_STREAMS, +#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS + + _SC_THREAD_ROBUST_PRIO_INHERIT, +#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT + _SC_THREAD_ROBUST_PRIO_PROTECT +#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT + +}; +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/posix1_lim.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/posix1_lim.h new file mode 100755 index 0000000000000..0739958c5a6c4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/bits/posix1_lim.h @@ -0,0 +1,34 @@ +#ifndef POSIX1_LIM_H +#define POSIX1_LIM_H +/** + @file posix1_lim.h + @brief POSIX Minimum values + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +TODO + This header should be ideally relocated under api/posix/bits (something that + doesnt exist today) and be included from api/posix/bits/limits.h which inturn + should be included from toolchain's limits.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +#ifndef _POSIX_PATH_MAX +/** @brief Maximum number of bytes in a pathname, including the terminating + nul character */ +#define _POSIX_PATH_MAX 256 +#endif + +#ifndef _POSIX_SEM_NSEMS_MAX +/** @brief Maximum number of semaphores that a process may have */ +#define _POSIX_SEM_NSEMS_MAX 16 +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/common/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/common/time.h new file mode 100755 index 0000000000000..76b0d39ab7039 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/common/time.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/fcntl.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/fcntl.h new file mode 100755 index 0000000000000..c80ec98a449b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/fcntl.h @@ -0,0 +1,51 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/*========================================================================== + * FILE: fcntl.h + * + * SERVICES: POSIX fcntl.h + * + * DESCRIPTION: The header is needed by the open() and fcntl() + * system calls, which have a variety of parameters and + * flags. They are described here. + * + * The formats of the calls to each of these are: + * + * open(path, oflag [,mode]) open a file + * fcntl(fd, cmd [,arg]) get or set file attributes + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Oflag values for open(). POSIX Table 6-4. */ +#define POSIX_O_CREAT 0x100 /* creat file if it doesn't exist */ +#define POSIX_O_EXCL 0x200 /* exclusive use flag */ +#define POSIX_O_NOCTTY 0x400 /* do not assign a controlling terminal */ +#define POSIX_O_TRUNC 0x1000 /* truncate flag */ + +/* File status flags for open() and fcntl(). POSIX Table 6-5. */ +#define POSIX_O_APPEND 0x2000 /* set append mode */ +#define POSIX_O_NONBLOCK 0x4000 /* no delay */ + +/* File access modes for open() and fcntl(). POSIX Table 6-6. */ +#define POSIX_O_RDONLY 0 /* open(name, POSIX_O_RDONLY) opens read only */ +#define POSIX_O_WRONLY 1 /* open(name, POSIX_O_WRONLY) opens write only */ +#define POSIX_O_RDWR 2 /* open(name, POSIX_O_RDWR) opens read/write */ + +/* Mask for use with file access modes. POSIX Table 6-7. */ +#define POSIX_O_ACCMODE 0x3 /* mask for file access modes */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FCNTL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/hooks/unistd.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/hooks/unistd.h new file mode 100755 index 0000000000000..1c618bfe36b4f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/hooks/unistd.h @@ -0,0 +1,115 @@ +#ifndef UNISTD_H +#define UNISTD_H +/** + @file posix/hooks/unistd.h + @brief POSIX related declarations in that are missing in toolchain + header + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly! Instead include unistd.h. + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include /* For various POSIX ID types from toolchain headers */ + +#ifdef __cplusplus +extern "C" { +#endif +extern long pathconf (char const * path, int name); + +/* Process*/ + +/** The getppid() function shall return the parent process ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the parent process ID + */ +pid_t getppid(void); + +/** The getpgid() function shall return the process group ID of the process whose process ID is equal to pid + * Please refer to POSIX standard for details. + * @param thread [in] process ID + * @param value_ptr [out] process group ID + */ +pid_t getpgid(pid_t pid); + +/** The getpgrp() function shall return the process group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] process group ID of the calling process + */ +pid_t getpgrp(void); + +/**The getuid() function shall return the real user ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the real user ID of the calling process. + */ +uid_t getuid(void); + +/** The geteuid() function shall return the effective user ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective user ID of the calling process + */ +uid_t geteuid(void); + +/** The getegid() function shall return the effective group ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective group ID of the calling process. + */ +gid_t getegid(void); + +/** The getgid() function shall return the real group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] real group ID of the calling process. + */ + gid_t getgid(void); + +/** seteuid set effective user ID + * Please refer to POSIX standard for details. + * @param thread [in] effective user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int seteuid(uid_t uid); + +/** setpgrp - set the process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setpgrp(void); + +/** setuid - set user ID + * Please refer to POSIX standard for details. + * @param thread [in] user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setuid(uid_t uid); + +/** setpgid - set process group ID for job control + * Please refer to POSIX standard for details. + * @param thread [in] PID of process, PGID to be set + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setpgid(pid_t pid, pid_t pgid); + +/** setsid - create session and set process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setsid(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/mqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/mqueue.h new file mode 100755 index 0000000000000..74dcc2fa202c6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/mqueue.h @@ -0,0 +1,203 @@ +#ifndef _POSIX_MQUEUE_H_ +#define _POSIX_MQUEUE_H_ + +/*========================================================================== + * FILE: mqueue.h + * + * SERVICES: POSIX Message Queue API interface + * + * DESCRIPTION: POSIX Message Queue API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technlogies, Inc. + *==========================================================================*/ + +#include /*ssize_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MQ_PRIO_MAX 255 /* max priority */ +#define MQ_PRIO_DEFAULT 0 /* default priority */ + +typedef int mqd_t; + +struct mq_attr +{ + long mq_flags; /* message queue flags */ + long mq_maxmsg; /* maximum number of messages */ + long mq_msgsize; /* maximum message size */ + long mq_curmsgs; /* number of messages currently queued */ +}; + +typedef struct mq_attr mqueue_attr; + +/** \details + * This provides POSIX Message Queue API. + * + * mq_notify is not supported. + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * it only supports Message sending and receiving within one process. + * Message sending and receiving among processes are not supported. + */ + +/** \defgroup mqueue POSIX Message Queue API */ +/** \ingroup mqueue */ +/** @{ */ + +/** Open a message queue. + * Please refer to POSIX standard for details. + */ +mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */...); + +/** Close a message queue. + * Please refer to POSIX standard for details. + */ +int mq_close(mqd_t mq_desc); + +/** Remove a message queue. + * Please refer to POSIX standard for details. + */ +int mq_unlink(const char *name); + +/** Send a message to a message queue. + * Please refer to POSIX standard for details. + * + * If the queue is full, instead of blocking the sender, this function + * will return -1 with errno EAGAIN, in this implementation. This behavior + * may change in the future. + */ +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); + +/** Send a message to a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); + +/** Receive a message from a message queue. + * Please refer to POSIX standard for details. + */ +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); + +/** Receive a message from a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msg_prio, const struct timespec *restrict abs_timeout); + +/** Get message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); + +/** Set message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, struct mq_attr *restrict omqstat); + +/** @} */ + +#define NBBY 8U /* number of bits in a byte */ + +/* + * Select uses bit masks of file descriptors in longs. These macros + * manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here should + * be enough for most uses. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256U +#endif + +typedef unsigned long fd_mask; +#define NFDBITS (sizeof(fd_mask) * (unsigned int)NBBY) /* bits per mask */ + +#ifndef howmany +#define howmany(x, y) (((x) + ((y) - 1U)) / (y)) +#endif + +//equivalent of fd_set fpr WINNT env +typedef struct fd_set +{ + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +/** \addtogroup mqueue */ +/** @{ */ + +/** Sets the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_SET(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] |= (1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Clears the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_CLR(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] &= ~(1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise. + */ +#define FD_ISSET(n, p) ((unsigned long)(p)->fds_bits[((unsigned int) (n)) / NFDBITS] & (unsigned long)((unsigned)1U << (((unsigned int) (n)) % NFDBITS))) + +/** Copies the file descriptor set. + */ +#define FD_COPY(f, t) (void)(memcpy)((t), (f), sizeof(*(f))) + +/** Initializes the file descriptor set fdset to have zero bits for all file descriptors. + */ +#define FD_ZERO(p) (void)memset((p), 0, sizeof(*(p))) + +/** Error check the file descriptor set. + */ +#define FD_BAD(fd) ((fd) < 0 /*|| fd >= fd_arraylen || fd_array[fd].obj == 0*/) + +/*! Wait for both message queues and signals. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int pselect(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict sigmask); + +/*! Wait for multiple message queues. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout); + +/** @} */ + +/* this function is needed for test framework which needs to clean up memory when teardown */ +void _mq_teardown(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread.h new file mode 100755 index 0000000000000..f64242e8dc683 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread.h @@ -0,0 +1,287 @@ +#ifndef QURT_PTHREAD_H +#define QURT_PTHREAD_H + +/*========================================================================== + * FILE: pthread.h + * + * SERVICES: POSIX pthread API interface + * + * DESCRIPTION: POSIX pthread API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016,2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *========================================================================== + * + * EDIT HISTORY FOR MODULE + * + * This section contains comments describing changes made to the module. + * Notice that changes are listed in reverse chronological order. + * + * + * + * when who what, where, why + * -------- --- ------------------------------------------------------- + * 10/13/08 cz Initial version. + *==========================================================================*/ + +#include +#include "sys/sched.h" /* For struct sched_param */ +#include "sys/errno.h" /* error values */ +#include +#include +#include +#include +#include +#include "pthread_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* the range of the set supported by the kernel data type used to represent CPU sets. */ +#define CONFIG_NR_CPUS QURT_THREAD_CFG_BITMASK_ALL + +#define UNIMPLEMENTED(FUNC, RETURNTYPE, ARGS) static inline RETURNTYPE FUNC ARGS { qurt_printf("Unimplemented: %s... exiting\n", __FUNCTION__); exit(1); } + +/** @brief Magic (non-portable) value for a stack's address to enable usage + of auto-stack feature (if available) */ +#define PTHREAD_AUTO_STACK_MAGIC_ADDR_NP ((void *)0xFFF) + +/** \details + * This provides POSIX thread API. + * + */ + +/** \defgroup pthread POSIX pthread API */ +/** \ingroup pthread */ +/** @{ */ + +/** Compare Two Threads. + * Please refer to POSIX standard for details. + */ +static inline int pthread_equal(pthread_t t1, pthread_t t2) +{ + return (t1 == t2) ? 1 : 0; +} + +/** Create Thread. + * Please refer to POSIX standard for details. + */ +int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void *(*start)(void *), void *arg); + +/** Terminate Calling Thread. + * Please refer to POSIX standard for details. + */ +void pthread_exit(void *value_ptr); + +/** Wait for thread termination. + * Please refer to POSIX standard for details. + * @param thread [in] the thread to be joined + * @param value_ptr [out] the pointer of the exit status + */ +int pthread_join(pthread_t thread, void **value_ptr); + +/** Detach a joinable thread. + * Please refer to POSIX standard for details. + * @param id [in] id of the tread the thread to be detached. + */ +int pthread_detach(pthread_t id); + +/** Dynamic package initialisation + * Please refer to POSIX standard for details. + */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + +pthread_t pthread_self(void); +int pthread_cancel(pthread_t thread); +static inline void pthread_yield(void) +{ + return; +} + +int pthread_kill(pthread_t thread, int sig); + +/** + * @brief Return name of thread + * @warning Donot call this in the error handling path as it may cause deadlock + * due to underlying OS calls + * @param thread [in] thread Thread whose name is to be retrieved + * @param name [out] name Buffer used to return thread name + * @param len [in] len Number of bytes available in name + * @return 0 on success, ESRCH, ERANGE on failure + */ +extern int pthread_getname_np (pthread_t thread, char * name, size_t len); + +int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param); +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); +int pthread_setschedprio(pthread_t thread, int prio); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); + +/* Attribute functions */ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const sched_param *restrict param); +int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, sched_param *restrict param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr); +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void ** stackaddr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); +int pthread_attr_setscope(pthread_attr_t *attr, int scope); +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_getguardsize(const pthread_attr_t * attr, size_t * guardsize); +int pthread_attr_setautostack(pthread_attr_t *attr); +int pthread_attr_setbuspriority(pthread_attr_t *attr, unsigned short bus_priority); + +/* Qualcomm additions to pthread get/set attribute functions */ +int pthread_attr_setthreadname(pthread_attr_t *attr, const char * name); +int pthread_attr_getthreadname(const pthread_attr_t *attr, char * name, int size); +int pthread_attr_settimetestid(pthread_attr_t *attr, unsigned int tid); +int pthread_attr_gettimetestid(const pthread_attr_t *attr, unsigned int* tid); + +/* Mutexes */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling); +int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling); + +/* For Mutex with type PTHREAD_MUTEX_NORMAL, Priority Inheritance is not + * supported even PTHREAD_PRIO_INHERIT is defined since QURT does not support + * this kind of Mutex */ +int pthread_mutexattr_init(pthread_mutexattr_t *attr); +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling); + +/* Spinlocks */ +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); + +/* Condition variables */ +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); +int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); +int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock); +int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock); +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *time); + +/* Barriers */ +int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); +int pthread_barrier_destroy(pthread_barrier_t *barrier); +int pthread_barrier_wait(pthread_barrier_t *barrier); +int pthread_barrierattr_init(pthread_barrierattr_t *attr); +int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); + + +/*Read-Write locks*/ +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +int pthread_rwlock_rdlock(pthread_rwlock_t *); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *); +int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); +int pthread_rwlock_unlock(pthread_rwlock_t *); + + +/** please refer to POSIX standard document + */ +int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/** set CPU affinity attribute in thread attributes object. + + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [in] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpuset specified a CPU that was outside the set supported + by the kernel. (The kernel configuration option + CONFIG_NR_CPUS defines the range of the set supported by + the kernel data type used to represent CPU sets.) + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); + +/** get CPU affinity attribute in thread attributes object. + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [out] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpusetsize is smaller than the size of the affinity mask + used by the kernel. + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset); + +/* TLS */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_getattr_np(pthread_t thread, pthread_attr_t * restrict attr); + +/** @} */ + +/* Calling non-pthread calls this function to create pthred tcb w/o creating actual thread */ +int pthread_fake(pthread_t * restrict thread, const pthread_attr_t * restrict attr); +int pthread_fake_destroy(pthread_t thread); + +//amitkulk: move these to unistd.h after we move that header within qurt +int posix_memalign(void **memptr, size_t alignment, size_t size); +void exit(int status); +#ifdef __cplusplus +} +#endif + +#endif /* QURT_PTHREAD_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread_types.h new file mode 100755 index 0000000000000..51c3b9dbca243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/pthread_types.h @@ -0,0 +1,193 @@ +#ifndef _PTHREAD_TYPES_H_ +#define _PTHREAD_TYPES_H_ + +/*========================================================================== + * FILE: pthread_types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2016, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif + +#define _SSIZE_T + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PTHREAD_MAX_THREADS 512U + +#define PTHREAD_NAME_LEN 16 +#define PTHREAD_MIN_STACKSIZE 512 //4096 +#define PTHREAD_MAX_STACKSIZE 1048576 +#define PTHREAD_DEFAULT_STACKSIZE 16384 + +#define PTHREAD_STACK_MIN (4096U*2U) +#define PTHREAD_MIN_PRIORITY 0U +#define PTHREAD_MAX_PRIORITY 255U +#define PTHREAD_DEFAULT_PRIORITY 1 + +/*Mutex initialization status*/ +#define PTHREAD_MUTEX_ATTR_UNINITIALIZED 0 +#define PTHREAD_MUTEX_ATTR_INITIALIZED 1 + +/*Conditional attributes initialization status*/ +#define PTHREAD_COND_ATTR_UNINITIALIZED 0 +#define PTHREAD_COND_ATTR_INITIALIZED 1 + +#define PTHREAD_DEFAULT_NAME "Anonymous" + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFFU) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFFU) + +/* mutex and cond_var shared */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* mutex type */ +#define PTHREAD_MUTEX_ERRORCHECK 0 +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT 3 + +/* mutex protocol */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_SPINLOCK_UNLOCKED 0 +#define PTHREAD_SPINLOCK_LOCKED 1 + +#define PTHREAD_ONCE_INIT (0) + +#define PTHREAD_MUTEX_OPAQUE //ToDo: amitkulk: debug + +typedef signed int ssize_t; + +/*detatchstate of a pthread*/ +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 0 + +/*contention scope*/ +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 + +/*scheduler*/ +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Types and structure definitions + * + */ +typedef unsigned int cpu_set_t; + +typedef unsigned int pthread_t; + +typedef struct pthread_attr_t +{ + void *stackaddr; + int internal_stack; /* this flag==1 means the stack needs to be freed by posix */ + size_t stacksize; + int priority; + unsigned short timetest_id; + /* This flag indicate if thread will be autostack thread*/ + unsigned short autostack:1; + /* This flag is to indicate thread's bus_priority high/low + bus_priority = 0 -- Bus_priority is low + bus_priority = 1 -- Bus_priority is high + bus_priority = 3 -- Bus_priority is default (takes the default set for the process) + */ + unsigned short bus_priority:2; + unsigned short reserved:13; + cpu_set_t cpumask; + char name[PTHREAD_NAME_LEN]; + /* This flag indicates whether pthread lib should create thread contexts for other OSALs */ + /* This is used internally by POSIX and not available for general usage */ + int ext_context; + int detachstate; +} pthread_attr_t; + +//mutex attr +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +struct pthread_mutexattr_t +{ + int is_initialized; + int type; + int pshared; + int protocol; +}; + +typedef unsigned int pthread_mutex_t; + +typedef unsigned int pthread_spinlock_t; + +typedef struct pthread_condattr_t +{ + int is_initialized; + int pshared; + clockid_t clock_id; +} pthread_condattr_t; + +typedef unsigned int pthread_cond_t; + +typedef struct pthread_barrierattr_t +{ + int is_initialized; + int pshared; +} pthread_barrierattr_t; + +typedef unsigned int pthread_barrier_t; + +typedef int pthread_key_t; + +typedef int pthread_once_t; + + +/*Read-Write locks*/ +#define PTW32_RWLOCK_MAGIC 0xfacade2 +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +#ifdef __cplusplus +} +#endif + +#endif /* _PTHERAD_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sched.h new file mode 100755 index 0000000000000..faf3365be9f82 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sched.h @@ -0,0 +1,21 @@ +/*============================================================================= + + sched.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include "sys/sched.h" + +#endif //__SCHED_H__ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/semaphore.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/semaphore.h new file mode 100755 index 0000000000000..d9145b295ae62 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/semaphore.h @@ -0,0 +1,114 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +/*========================================================================== + * FILE: semaphore.h + * + * SERVICES: POSIX semaphore API interface + * + * DESCRIPTION: POSIX semaphore API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ +#include // Get all C sys types - includes POSIX specific +#include "sys/errno.h" // error values + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** User facing semaphore container with opaque pointer to implementation */ +typedef struct +{ + unsigned int *opaque; +} sem_t; +#define _SEM_T + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* constant definitions */ +#define SEM_FAILED ((sem_t*) 0) + +/* @todo siqbal Should we put such configuration items in a common place + instead of this user-facing header? */ +#define SEM_VALUE_MAX ((unsigned int) 30) // If need be increase this + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/** \details + * POSIX standard comes with two kinds of semaphores: named and unnamed + * semaphores. + * + * This implementation of POSIX kernel API provide unnamed & named semaphore. + * + * + * sem_timedwait() is not provided. + */ + +/** \defgroup semaphore POSIX Semaphore API */ + +/** \ingroup semaphore */ +/** @{ */ + +/** Initialize an unnamed semaphore. + * Please refer to POSIX standard for details. + * @param pshared [in] This implementation does not support non-zero value, + * i.e., semaphore cannot be shared between processes in this implementation. + */ +int sem_init(sem_t *sem, int pshared, unsigned int value); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_wait(sem_t *sem); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_trywait(sem_t *sem); + +/** Unlock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_post(sem_t *sem); + +/** Get the value of a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_getvalue(sem_t *sem, int *value); + +/** Destroy an unnamed semaphore. + * Please refer to POSIX standard for details. + */ +int sem_destroy(sem_t *sem); + +/** creates and initializes a named semaphore. + * Please refer to POSIX standard for details. + */ +sem_t * sem_open(const char* name , int oflag , ...); + +/** closes a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_close(sem_t *sem); + +/** unlinkes a named semaphore. + * Please refer to POSIX standard for details. + */ +int sem_unlink(const char *name); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SEMAPHORE_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/signal.h new file mode 100755 index 0000000000000..35cb1f1a9a319 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/signal.h @@ -0,0 +1,201 @@ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/*========================================================================== + * FILE: signal.h + * + * SERVICES: POSIX Signal API interface + * + * DESCRIPTION: POSIX Signal API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX signal bits */ + +#define POSIX_MSG 7 /* POSIX msg type used in Qube API */ +#define POSIX_NOTIF 8 /* POSIX msg type used in Qube API */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ + +#define SIGRTMIN 10 +#define SIGRTMAX 32 + +/* Notification Types. */ +/* No asynchronous notification is delivered when the event of interest occurs. */ +#define SIGEV_NONE 0 +/* The signal specified in sigev_signo shall be generated for the process when + the event of interest occurs. */ +#define SIGEV_SIGNAL 1 +/* A notification function is called to perform notification. */ +#define SIGEV_THREAD 2 +#define SA_SIGINFO 1 + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +typedef unsigned long int sigset_t; + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent sigevent; +struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; +}; + +typedef struct siginfo_t siginfo_t; +struct siginfo_t +{ + int si_signo; + int si_code; + union sigval si_value; +/* int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band;*/ +}; +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_sigaction)(int, siginfo_t *, void *); +}; + +/* Signal functions */ + +/** \details + * This provides POSIX Signal API. Please note that this + * implementation does not fully comply with POSIX standard. + * + * In POSIX standard, Signal can be used as 'interrupt', which means + * an incoming signal will interrupt a running thread. After the + * registered signal handler is executed, the thread will resume. + * This behavior cannot be implemented w/o modifying L4 or QURT kernel. + * On the ohter hand, appliation need to be carefully written to avoid + * problems caused by 'interrupting' signals. + * + * Therefore, in this implementation of POSIX signal, thread will + * only receive signals when it explicitly waits for signals, i.e., when + * the thread calls either sigwait() or sigsuspend(). + * + * Therefore, pthread_sigmask(), which set or get signal mask for a thread, + * is not supported, since the signal mask will be set by sigwait() and + * sigsuspend(). + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * only threads can send and receive signals. The functions related to + * signal operations with processes, such as kill(), sigqueue(), + * sigprocmask(), are not provided. + * + * Queued signal is not supported. + * + * Applications will use signals from SIGRTMIN to SIGRTMAX. + * + * SIGEV_SIGNAL and SIGEV_THREAD are supported. SIGEV_NONE is not + * supported. + * + */ + +/** \defgroup signal POSIX Signal API */ +/** \ingroup signal */ +/** @{ */ + +/** Wait for signals. This implementation does not support queued signals. + * + * Please refer to POSIX standard for details. + */ +int sigwait(const sigset_t *restrict set, int *restrict sig); + +/** Examine and Change Signal Action. + * Please refer to POSIX standard for details. + * + * @param act [in] A pointer to the sigaction structure that describes the + * action to be taken for the signal. Can be NULL. + * The following flags for sa_flags field in struct sigaction are not + * supported: SA_NOCLDSTOP, SA_ONSTACK, SA_RESETHAND, SA_RESTART, + * SA_NOCLDWAIT and SA_NODEFER. Only flag SA_SIGINFO is supported. + * + * @note Define sigaction as macro to avoid a warning when included from + * C++ code - it's causing a "sigaction(...) hides constructor for + * 'struct sigaction'" warning. + */ +/*lint -esym(123,sigaction) Suppress "macro used with no arguments" */ +#define sigaction(sig,act,oact) _sigaction((sig),(act),(oact)) + +/** Wait for signals. + * Please refer to POSIX standard for details. + */ +int sigsuspend(const sigset_t *sigmask); + +/** Add Signal to Signal Set. + * Please refer to POSIX standard for details. + */ +int sigaddset(sigset_t *set, int signo); + +/** Delete Signal from Signal Set. + * Please refer to POSIX standard for details. + */ +int sigdelset(sigset_t *set, int signo); + +/** Initialize and Empty Signal Set. + * Please refer to POSIX standard for details. + */ +int sigemptyset(sigset_t *set); + +/** Initialize and Fill Signal Set. + * Please refer to POSIX standard for details. + */ +int sigfillset(sigset_t *set); + +/** Test for Signal in Signal Set. + * Please refer to POSIX standard for details. + */ +int sigismember(const sigset_t *set, int signo); + +/** @} */ + +/* this is not a public api function */ +int _sigaction(int sig, const struct sigaction *act, struct sigaction *oact); + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +/** Wait for the time interval specified in the timespec structure referenced + * by timeout. This implementation does not support queued signals. + * For struct siginfo_t, si_code and si_value are ignored in this implementation. + * + * Please refer to POSIX standard for details. + */ +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SIGNAL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/errno.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/errno.h new file mode 100755 index 0000000000000..b9edf57bab6c3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/errno.h @@ -0,0 +1,20 @@ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +/*========================================================================== + * FILE: errno.h + * + * SERVICES: POSIX errno header file + * + * DESCRIPTION: POSIX errno based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#ifndef EOK +#define EOK 0 +#endif + +#endif /* _SYS_ERRNO_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/sched.h new file mode 100755 index 0000000000000..2acc34d821725 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/sched.h @@ -0,0 +1,67 @@ +#ifndef _POSIX_SCHED_H_ +#define _POSIX_SCHED_H_ + +/*========================================================================== + * FILE: sched.c + * + * SERVICES: POSIX Thread sched API interface + * + * DESCRIPTION: POSIX Thread sched API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCHED_FIFO 0 /* First in, first out (FIFO) scheduling policy. */ +#define SCHED_RR 1 /* Round robin scheduling policy. */ +#define SCHED_SPORADIC 2 /* Sporadic server scheduling policy. */ +#define SCHED_OTHER 3 /* Another scheduling policy. */ + +typedef struct sched_param sched_param; +struct sched_param +{ + void *unimplemented; + int sched_priority; +}; + +/** \details + * This provides POSIX sched API. + */ + +/** \defgroup sched POSIX sched API */ +/** \ingroup sched */ +/** @{ */ + +/** Relinquish the CPU. + * Please refer to POSIX standard for details. + */ +static inline int sched_yield(void) +{ + return 0; +} + +/** Get the maximum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_max(int policy); + +/** Get the minimum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_min(int policy); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SCHED_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/types.h new file mode 100755 index 0000000000000..700026f9f9e4e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/sys/types.h @@ -0,0 +1,35 @@ +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/*========================================================================== + * FILE: types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#if !defined( _PID_T ) || !defined( __pid_t_defined ) +/* POSIX defines pid_t as signed 32-bit type. Hexagon toolchain's header + defines it as unsigned 32-bit type citing conflict with QuRT POSIX + compatibility later. If any such conflicts exist, we should fix them. + pid_t is being defined *BEFORE* inclusion of generic/sys/types.h + *INTENTIONALLY* to fix this */ +typedef int pid_t; +#define _PID_T +#define __pid_t_defined +#endif +#include +#include +#include +#include + +#ifndef __DEFINED_off_t +typedef long off_t; +#define __DEFINED_off_t +#endif + +#endif /* _SYS_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/time.h new file mode 100755 index 0000000000000..13aeb1ea9920d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/posix/time.h @@ -0,0 +1,142 @@ +#ifndef _POSIX_TIME_H_ +#define _POSIX_TIME_H_ + +/*========================================================================== + * FILE: time.h + * + * SERVICES: POSIX Timer API interface + * + * DESCRIPTION: POSIX Timer API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *==========================================================================*/ + + +#include + +typedef int clockid_t; /* ignored */ +#define _CLOCKID_T +#define _PROVIDE_POSIX_TIME_DECLS 1 +#include +/* @todo anandj sys/time.h has definition for struct timeval but is not + included by generic/time.h */ +#include + +#define CLOCK_FREQ_NOT_DEFINED -1 +/* Frequency of Sclk used */ +#define TIME_CONV_SCLK_FREQ 19200000 + +#define RES_CONV_FACTOR1 1 +#define RES_CONV_FACTOR2 1000000000 + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +#endif + +#if !defined(CLOCK_MONOTONIC) +# define CLOCK_MONOTONIC 1 +#endif + +#if !defined(CLOCK_THREAD_CPUTIME_ID) +# define CLOCK_THREAD_CPUTIME_ID 2 +#endif + +#if !defined(CLOCK_PROCESS_CPUTIME_ID) +# define CLOCK_PROCESS_CPUTIME_ID 3 +#endif + +#if !defined(CLOCK_MONOTONIC_RAW) +# define CLOCK_MONOTONIC_RAW 4 +#endif + +#if !defined(CLOCK_REALTIME_COARSE) +# define CLOCK_REALTIME_COARSE 5 +#endif + +#if !defined(CLOCK_MONOTONIC_COARSE) +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +#if !defined(CLOCK_BOOTTIME) +# define CLOCK_BOOTTIME 7 +#endif + +struct itimerspec +{ + struct timespec it_interval; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer functions */ + +/** \details + * POSIX timers can be either of two types: a one-shot type or a periodic + * type. + * + * A one-shot is an armed timer that is set to an expiration time relative + * to either a current time or an absolute time. The timer expires once and + * is disarmed. + * + * A periodic timer is armed with an initial expiration time and a repetition + * interval. Every time the interval timer + * expires, the timer is reloaded with the repetition interval. The timer + * is then rearmed. + */ + +/** \defgroup timer POSIX Timer API */ + +/** \ingroup timer */ +/** @{ */ + +/** Create a POSIX timer. + * Please refer to POSIX standard for details. + * @param clockid [in] ignored in this implementation + * @param evp [in] if non-NULL, points to a sigevent structure. This + * structure, allocated by the application, defines the asynchronous + * notification to occur when the timer expires. If the evp argument is + * NULL, the effect is as if the evp argument pointed to a sigevent + * structure with the sigev_notify member having the value SIGEV_SIGNAL, + * the sigev_signo having a default signal number (SIGALRM), and the + * sigev_value member having the value of the timer ID. + */ +int timer_create(clockid_t clockid, struct sigevent *restrict evp, + timer_t *restrict timerid); + +/** Delete a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_delete(timer_t timerid); + +/** Get the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_gettime(timer_t timerid, struct itimerspec *value); + + +/** Set the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + * @param flags [in] ignored in this implementation + */ +int timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); +/** Obtain ID of a process CPU-time clock + * @param pid [in] Process ID + * @param clock_id [out] Clock ID + * @return Error values as per POSIX standard + */ +int clock_getcpuclockid (pid_t pid, clockid_t * clock_id); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_TIME_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qube/qube.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qube/qube.h new file mode 100755 index 0000000000000..1e31e2deedb38 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qube/qube.h @@ -0,0 +1,51 @@ +#ifndef QUBE_H +#define QUBE_H +/*============================================================================= + + qube.h -- H E A D E R F I L E + +GENERAL DESCRIPTION + Prototypes of qpd API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Define Error codes as QuRT error codes preceed with QURT_ */ +#ifndef EOK +#define EOK QURT_EOK +#endif /* EOK */ +#ifndef EVAL +#define EVAL QURT_EVAL +#endif /* EVAL */ +#ifndef EMEM +#define EMEM QURT_EMEM +#endif /* EMEM */ +#ifndef EINVALID +#define EINVALID QURT_EINVALID +#endif /* EINVALID */ + + +/*============================================================================= + FUNCTION DECLARATIONS +=============================================================================*/ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QUBE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops.h new file mode 100755 index 0000000000000..0a9a9f8ba7db5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops.h @@ -0,0 +1,197 @@ +#ifndef ATOMIC_OPS_H +#define ATOMIC_OPS_H +/** + @file atomic_ops.h + + @brief Type definitions backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * Author: Carlos Dyonisio + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_plain_word_t; + +/*-------------------------------------------------------------------------*/ + /* Atomic Ops API. */ + +/* + * IMPORTANT! + * If you plan to change the structure atomic_word_t, please add the new + * elements after value. For more information, read the comment in + * arch/arm/libs/atomic_ops/v5/src/arm_atomic_ops.spp:66 + */ + +typedef struct { + volatile atomic_plain_word_t value; +} atomic_word_t; + +#define ATOMIC_INIT(i) { (i) } + +static inline void +atomic_init(atomic_word_t *a, atomic_plain_word_t v) +{ + a->value = v; +} + +#if defined(ARCH_ARM) && defined(ARCH_VER) && (ARCH_VER < 6) && \ + (!defined(__ATOMIC_OPS_IN_KERNEL__) || defined(MACHINE_SMP)) + +/* + * If it is ARMv4/v5, the function declarations may change + * and are defined in the arch specific header file, + * as some of then cannot be declared static because of + * the assembler implementation. + */ + +#else + +/* Arithmetic operations. */ + +void atomic_sub(atomic_word_t *target, atomic_plain_word_t v); + +/* Architecture independent definitions. */ + +static inline atomic_plain_word_t atomic_read(atomic_word_t *target) +{ + return target->value; +} + +typedef unsigned long long atomic64_plain_word_t; + +typedef struct { + volatile atomic64_plain_word_t value; +} atomic64_word_t; + +static inline void +atomic64_init(atomic64_word_t *a, atomic64_plain_word_t v) +{ + a->value = v; +} + +/********************* + Support 64-bit + *********************/ + +atomic64_plain_word_t atomic64_set(atomic64_word_t* target, + atomic64_plain_word_t value); + +void atomic64_xor(atomic64_word_t* target, + atomic64_plain_word_t mask); + +/*---------------------------------------------------------------------------*/ + +/* Architecture independent definitions. */ + +static inline atomic64_plain_word_t atomic64_read(atomic64_word_t *target) +{ + return target->value; +} + +#endif + + +/* Architecture dependent definitions. */ +#include + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops_plat.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops_plat.h new file mode 100755 index 0000000000000..b54b3ff83d978 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/atomic_ops_plat.h @@ -0,0 +1,86 @@ +#ifndef ATOMIC_OPS_PLAT_H +#define ATOMIC_OPS_PLAT_H +/** + @file atomic_ops_plat.h + + @brief Prototypes of atomic operations API backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define atomic_set(a,b) qurt_atomic_set((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and(a,b) qurt_atomic_and((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and_return(a,b) qurt_atomic_and_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or(a,b) qurt_atomic_or((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or_return(a,b) qurt_atomic_or_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor(a,b) qurt_atomic_xor((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor_return(a,b) qurt_atomic_xor_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_set_bit(a,b) qurt_atomic_set_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_clear_bit(a,b) qurt_atomic_clear_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_change_bit(a,b) qurt_atomic_change_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add(a,b) qurt_atomic_add((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_return(a,b) qurt_atomic_add_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_unless(a,b,c) qurt_atomic_add_unless((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_sub(a,b) qurt_atomic_sub((unsigned int *)(a),(unsigned int)(b)) +#define atomic_sub_return(a,b) qurt_atomic_sub_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_inc(a) qurt_atomic_inc((unsigned int *)(a)) +#define atomic_inc_return(a) qurt_atomic_inc_return((unsigned int *)(a)) +#define atomic_dec(a) qurt_atomic_dec((unsigned int *)(a)) +#define atomic_dec_return(a) qurt_atomic_dec_return((unsigned int *)(a)) +#define atomic_compare_and_set(a,b,c) qurt_atomic_compare_and_set((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_barrier qurt_atomic_barrier +#define atomic_barrier_write qurt_atomic_barrier_write +#define atomic_barrier_write_smp qurt_atomic_barrier_write_smp +#define atomic_barrier_read_smp qurt_atomic_barrier_read_smp +#define atomic_barrier_smp qurt_atomic_barrier_smp + +/*============================ + * 64 bits support + *============================ */ +#define atomic64_set(a,b) qurt_atomic64_set((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and(a,b) qurt_atomic64_and((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and_return(a,b) qurt_atomic64_and_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or(a,b) qurt_atomic64_or((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or_return(a,b) qurt_atomic64_or_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor(a,b) qurt_atomic64_xor((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor_return(a,b) qurt_atomic64_xor_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_set_bit(a,b) qurt_atomic64_set_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_clear_bit(a,b) qurt_atomic64_clear_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_change_bit(a,b) qurt_atomic64_change_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add(a,b) qurt_atomic64_add((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add_return(a,b) qurt_atomic64_add_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub(a,b) qurt_atomic64_sub((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub_return(a,b) qurt_atomic64_sub_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_inc(a) qurt_atomic64_inc((unsigned long long *)(a)) +#define atomic64_inc_return(a) qurt_atomic64_inc_return((unsigned long long *)(a)) +#define atomic64_dec(a) qurt_atomic64_dec((unsigned long long *)(a)) +#define atomic64_dec_return(a) qurt_atomic64_dec_return((unsigned long long *)(a)) +#define atomic64_compare_and_set(a,b,c) qurt_atomic64_compare_and_set((unsigned long long *)(a),(unsigned long long )(b),(unsigned long long )(c)) +#define atomic64_barrier qurt_atomic64_barrier +#define atomic64_barrier_write qurt_atomic64_barrier_write +#define atomic64_barrier_write_smp qurt_atomic64_barrier_write_smp +#define atomic64_barrier_read_smp qurt_atomic64_barrier_read_smp +#define atomic64_barrier_smp qurt_atomic64_barrier_smp + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_PLAT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt.h new file mode 100755 index 0000000000000..4d25c9b2b6243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt.h @@ -0,0 +1,111 @@ +#ifndef QURT_H +#define QURT_H + +/** + @file qurt.h + @brief Contains kernel header files that provide kernel OS API functions, constants, and + definitions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013,2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +/*====================================================================== + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Notice that changes are listed in reverse chronological + * order. + * + * + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------ + * 2011-02-25 op Add Header file + 2012-12-16 cm (Tech Pubs) Edited/added Doxygen comments and markup. + ======================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "qurt_consts.h" +#include "qurt_api_version.h" +#include "qurt_alloc.h" +#include "qurt_futex.h" +#include "qurt_mutex.h" +#include "qurt_pipe.h" +#include "qurt_printf.h" +#include "qurt_assert.h" +#include "qurt_thread.h" +#include "qurt_trace.h" +#include "qurt_cycles.h" +#include "qurt_profile.h" +#include "qurt_sem.h" +#include "qurt_cond.h" +#include "qurt_barrier.h" +#include "qurt_fastint.h" +#include "qurt_allsignal.h" +#include "qurt_anysignal.h" +#include "qurt_signal.h" +#include "qurt_rmutex.h" +#include "qurt_pimutex.h" +#include "qurt_signal2.h" +#include "qurt_rmutex2.h" +#include "qurt_pimutex2.h" +#include "qurt_int.h" +#include "qurt_lifo.h" +#include "qurt_power.h" +#include "qurt_event.h" +#include "qurt_pmu.h" +#include "qurt_stid.h" +//#include "qurt_version.h" +#include "qurt_tlb.h" +#include "qurt_vtlb.h" +#include "qurt_memory.h" +#include "qurt_qdi.h" +#include "qurt_sclk.h" +#include "qurt_space.h" +#include "qurt_process.h" +#include "qurt_timer.h" +#include "qurt_tls.h" +#include "qurt_thread_context.h" +#include "qurt_hvx.h" +#include "qurt_hmx.h" +#include "qurt_mailbox.h" +#include "qurt_island.h" +#include "qurt_qdi_proxy.h" +#include "qurt_l2cfg.h" +#include "qurt_mmap.h" +#include "qurt_isr.h" +#include "qurt_busywait.h" +#include "qurt_ecc.h" +#include "qurt_callback.h" +#include "qurt_error.h" +#include "qurt_except.h" +#include "qurt_mq.h" +#include "qurt_user_dma.h" +#include "qurt_fs_hub.h" +#include "qurt_os_services.h" + +#ifndef MAIN_ONLY +#define INCLUDE_ISLAND_CONTENTS +#endif +#ifndef ISLAND_ONLY +#define INCLUDE_MAIN_CONTENTS +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_alloc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_alloc.h new file mode 100755 index 0000000000000..da37a4c0a714e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_alloc.h @@ -0,0 +1,145 @@ +#ifndef QURT_ALLOC_H +#define QURT_ALLOC_H + +/** + @file qurt_alloc.h + @brief Prototypes of kernel memory allocation API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_malloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated memory area. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] size Size (in bytes) of the memory area. + + @return + Nonzero -- Pointer to the allocated memory area. \n + 0 -- Not enough memory in heap to allocate memory area. + + @dependencies + None. + + */ +/* ======================================================================*/ +void *qurt_malloc( unsigned int size); + +/*======================================================================*/ +/**@ingroup func_qurt_calloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated array. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] elsize Size (in bytes) of each array element. + @param[in] num Number of array elements. + + @return + Nonzero -- Pointer to allocated array.\n + Zero -- Not enough memory in heap to allocate array. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_calloc(unsigned int elsize, unsigned int num); + +/*======================================================================*/ +/**@ingroup func_qurt_realloc + Reallocates memory on the heap. \n + Changes the size of a memory area that is already allocated on the QuRT system heap. + The reallocate memory operation is functionally similar to realloc. It accepts a pointer + to an existing memory area on the heap, and resizes the memory area to the specified size + while preserving the original contents of the memory area. + + @note1hang This function might change the address of the memory area. + If the value of ptr is NULL, this function is equivalent to + qurt_malloc(). + If the value of new_size is 0, it is equivalent to qurt_free(). + If the memory area is expanded, the added memory is not initialized. + + @param[in] *ptr Pointer to the address of the memory area. + @param[in] newsize Size (in bytes) of the reallocated memory area. + + @return + Nonzero -- Pointer to reallocated memory area. \n + 0 -- Not enough memory in heap to reallocate the memory area. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_realloc(void *ptr, int newsize); + +/*======================================================================*/ +/**@ingroup func_qurt_free + Frees allocated memory from the heap.\n + Deallocates the specified memory from the QuRT system heap. + + @param[in] *ptr Pointer to the address of the memory to deallocate. + + @return + None. + + @dependencies + The memory item that the ptr value specifies must have been previously + allocated using one of the qurt_calloc(), + qurt_malloc(), or qurt_realloc() memory allocation functions. + Otherwise the behavior of QuRT is undefined. + + */ + /* ======================================================================*/ +void qurt_free( void *ptr); + + +void *qurt_memalign(unsigned int alignment, unsigned int size); + +/* +|| Macro to define a static heap for a QuRT program. +|| +|| Usage: +|| Declare at the top-level of any C source file that +|| is part of the build (and is guaranteed +|| to actually be pulled into the build). Place +|| it in the same function with main(): +|| +|| QURT_DECLARE_STATIC_HEAP(512000); +|| +|| The only argument is the size in bytes, and it is +|| rounded up to the nearest 64 bytes (size of an +|| L2 cache block). +|| +*/ + +#define QURT_DECLARE_STATIC_HEAP(sz) \ + static struct qurt_static_heap { \ + char space[(sz)] __attribute__((aligned(64))); \ + } static_heap[1]; \ + void * const override_heap_Base = &static_heap[0]; \ + void * const override_heap_Limit = &static_heap[1] + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLOC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_allsignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_allsignal.h new file mode 100755 index 0000000000000..5dc89e495130d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_allsignal.h @@ -0,0 +1,176 @@ + +#ifndef QURT_ALLSIGNAL_H +#define QURT_ALLSIGNAL_H + +/** + @file qurt_allsignal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup all_signal_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** +qurt_signal_t supersedes qurt_allsignal_t. This type definition was added for backwards compatibility. */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int waiting; /**< */ + unsigned int signals_in; /**< */ + unsigned int queue; /**< */ + unsigned int reserved; /**< */ + }X; + /** @endcond */ +} qurt_allsignal_t; +/** @} */ /* end_addtogroup all_signal_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_init + Initializes an all-signal object.\n + The all-signal object is initially cleared. + + @datatypes + #qurt_allsignal_t + + @param[out] signal Pointer to the all-signal object to initialize. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_init(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_destroy + Destroys the specified all-signal object.\n + @note1hang All-signal objects must be destroyed when they are no longer in use. + Failure to do this causes resource leaks in the QuRT kernel. \n + @note1cont All-signal objects must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_destroy(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_get + Gets signal values from the all-signal object. + + Returns the current signal values of the specified all-signal object. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to access. + + @return + Bitmask with current signal values. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_allsignal_get(qurt_allsignal_t *signal) +{ return signal->X.signals_in; } + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_wait + Waits on the all-signal object.\n + Suspends the current thread until all of the specified signals are set. + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 that it is not to be waited on. + + If a signal is set in an all-signal object, and a thread is waiting on the all-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + Unlike any-signals, all-signals do not need to explicitly clear any set signals in an all-signal + object before waiting on them again -- clearing is done automatically by the wait + operation. + + @note1hang At most, one thread can wait on an all-signal object at any given time. + Because signal clearing is done by the wait operation, no clear operation is + defined for all-signals. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to wait on. + @param[in] mask Signal mask value, which identifies the individual signals in the all-signal object + to wait on. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_wait(qurt_allsignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_set + Set signals in the specified all-signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit + value of 1 indicates that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the all-signal object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_set(qurt_allsignal_t *signal, unsigned int mask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLSIGNAL_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_anysignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_anysignal.h new file mode 100755 index 0000000000000..9619e2de562b4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_anysignal.h @@ -0,0 +1,225 @@ +#ifndef QURT_ANYSIGNAL_H +#define QURT_ANYSIGNAL_H +/** + @file qurt_anysignal.h + Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +Copyright (c) 2021 Qualcomm Technologies, Inc. +All rights reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== +Typedefs +======================================================================*/ + +/**@ingroup anysignals_types + qurt_signal_t supersedes qurt_anysignal_t. This type definition was added for backwards compatibility. */ +typedef qurt_signal_t qurt_anysignal_t; + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_init + Initializes an any-signal object.\n + The any-signal object is initially cleared. + + @datatypes + #qurt_anysignal_t + + @param[out] signal Pointer to the initialized any-signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_init(qurt_anysignal_t *signal) +{ + qurt_signal_init(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_destroy + Destroys the specified any-signal object. + + @note1hang Any-signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Any-signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_destroy(qurt_anysignal_t *signal) +{ + qurt_signal_destroy(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait + Wait on the any-signal object. \n + Suspends the current thread until any one of the specified signals is set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread is waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + + @return + Bitmask of current signal values. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_wait(qurt_anysignal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_set + Sets signals in the specified any-signal object. \n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be set, and 0 indicates not to set the sigmal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the any-signal object. + + @return + Bitmask of old signal values (before set). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_set(qurt_anysignal_t *signal, unsigned int mask); + + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_get + Gets signal values from the any-signal object.\n + Returns the current signal values of the specified any-signal object. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to access. + + @return + A bitmask with the current signal values of the specified any-signal object. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_get(qurt_anysignal_t *signal) +{ + return qurt_signal_get(signal); +} + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_clear + @xreflabel{sec:anysignal_clear} + Clears signals in the specified any-signal object.\n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object, which specifies the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + clear in the any-signal object. + + @return + Bitmask -- Old signal values (before clear). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_clear(qurt_anysignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait_timed + Waits on the any-signal object. \n + Suspends the current thread until any of the specified signals is set or timeout expires. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread was waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + @param[out] signals Bitmask of current signal values. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- timeout + #QURT_EINVALID -- Duration out of range + + @dependencies + None. + */ +/* ======================================================================*/ + +int qurt_anysignal_wait_timed(qurt_anysignal_t *signal, unsigned int mask, unsigned int *signals, unsigned long long int duration); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ANYSIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_api_version.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_api_version.h new file mode 100755 index 0000000000000..dfe53ae755054 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_api_version.h @@ -0,0 +1,77 @@ +#ifndef QURT_API_VERSION_H +#define QURT_API_VERSION_H +/*============================================================================== + +qurt_api_version.h + +GENERAL DESCRIPTION + API version file + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +/*============================================================================== + CONSTANTS AND DEFINITIONS +==============================================================================*/ +/** + * Each field of the QURT_API_VERSION definitions is an 8-bit unsigned integer. + * Main release has first 3 fields updated - Major, Minor and Release. + * - QURT_API_VERSION = Major, Minor, Release. + * Patch releases are supported by adding the extra field. + * - QURT_API_VERSION = Major, Minor, Release, Patch. + */ +// Major version is incremented for incompatible API changes. +#define QURT_API_VER_MAJOR 1 + +// Minor version is incremented for backward-compatible enhancements in the API +// set. +#define QURT_API_VER_MINOR 4 + +// RELEASE version is incremented for each release within a `MAJOR.MINOR` +// release. +#define QURT_API_VER_RELEASE 1 + +// Patch version is incremented when new API content is introduced on older LTS +// release. +#define QURT_API_VER_PATCH 0 + +/* Update the QURT_API_VERSION function macro. */ +#define QURT_API_VERSION_ENCODE(major, minor, release, patch) \ + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | \ + (((release) & 0xFF) << 8) | ((patch) & 0xFF)) + +/* Update the QURT_API_VERSION Macro. */ +#define QURT_API_VERSION \ + QURT_API_VERSION_ENCODE(QURT_API_VER_MAJOR, QURT_API_VER_MINOR, \ + QURT_API_VER_RELEASE, QURT_API_VER_PATCH) + +/** Usage: + * + * #if QURT_API_VERSION >= QURT_API_VERSION_ENCODE(1,4,0,0) + * qurt_func_2(a,b,c); + * #else + * qurt_func(a); + * #endif + * + */ +/* + Gets the QuRT API version. + + @return + QuRT API version. + + @dependencies + None. + */ +unsigned int qurt_api_version(void); + +#endif /* QURT_API_VERSION_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_assert.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_assert.h new file mode 100755 index 0000000000000..13cc2afd2e973 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_assert.h @@ -0,0 +1,51 @@ +#ifndef QURT_ASSERT_H +#define QURT_ASSERT_H +/** + @file qurt_assert.h + @brief Prototypes of qurt_assert API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@ingroup func_qurt_assert_error + Writes diagnostic information to the debug buffer, and raises an error to the QuRT kernel. + + @datatypes + None. + + @param[in] filename Pointer to the file name string. + @param[in] lineno Line number. + + @return + None. + + @dependencies + None. + */ +void qurt_assert_error(const char *filename, int lineno) __attribute__((noreturn)); + +#define qurt_assert(cond) ((cond)?(void)0:qurt_assert_error(__QURTFILENAME__,__LINE__)) + +/** @} */ /* end_ingroup func_qurt_assert */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ASSERT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_atomic_ops.h new file mode 100755 index 0000000000000..d9b2cff7d737c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_atomic_ops.h @@ -0,0 +1,1298 @@ +#ifndef QURT_ATOMIC_OPS_H +#define QURT_ATOMIC_OPS_H +/** + @file qurt_atomic_ops.h + @brief Prototypes of kernel atomic operations API. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * + * This file is only included by the main atomic_ops.h, so all of that + * file's definitions are available. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +///* Sanity check to ensure the smp flag is set in machines.py */ +//#if defined(__ATOMIC_OPS_IN_KERNEL__) && !defined(MACHINE_SMP) && CONFIG_NUM_UNITS > 1 +//#error CONFIG_NUM_UNITS > 1 but smp not defined in machines.py. +//#endif +#define QURT_INLINE __attribute__((always_inline)) + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_atomic_set + Sets the atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value Value to set. + + @return + Value successfuly set. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_set(unsigned int* target, unsigned int value) +{ + unsigned long tmp; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " memw_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic_and + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + None + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_and(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_and_return + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + AND result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_and_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_or + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_or(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_or_return + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + Returns the OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_or_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_xor + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_xor(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_xor_return + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_xor_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_set_bit + Sets a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_set_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_clear_bit + Clears a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_clear_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_change_bit + Toggles a bit in a atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_change_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1fU; + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_add(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add_return + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_add_unless + Adds the delta value to an atomic variable unless the current value in the target + matches the unless variable. + + @note1hang The function retries until load lock and store conditional + are successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] delta Value to add to the current value. + @param[in] unless Perform the addition only when the current value is not + equal to this unless value. + @return + TRUE -- 1 - Addition was performed. \n + FALSE -- 0 - Addition was not done. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_unless(unsigned int* target, + unsigned int delta, + unsigned int unless) +{ + unsigned int current_val; + unsigned int new_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%3)\n" + " p0 = cmp.eq(%0, %5)\n" + " if p0 jump 2f\n" + " %1 = add(%0, %4)\n" + " memw_locked(%3, p0) = %1\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"=&r" (new_val),"+m" (*target) + : "r" (target), "r" (delta), "r" (unless) + : "p0"); + + return (unsigned int)(current_val != unless); +} + +/**@ingroup func_qurt_atomic_sub + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_sub(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_sub_return + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_sub_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_inc + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_inc(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_inc_return + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_inc_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_dec + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_dec(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_dec_return + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_dec_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_compare_and_set + Compares the current value of the atomic variable with the + specified value and set to a new value when compare is successful. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val Old value to compare. + @param[in] new_val New value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE --Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_compare_and_set(unsigned int* target, + unsigned int old_val, + unsigned int new_val) +{ + unsigned int current_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memw_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (unsigned int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic_barrier + Allows the compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_barrier(void) +{ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); +} + + +/**@ingroup func_qurt_atomic64_set + Sets the 64-bit atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value 64-bit value to set. + + @return + Successfuly set value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_set(unsigned long long* target, unsigned long long value) +{ + unsigned long long tmp; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " memd_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic64_and_return + Bitwise AND operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise AND. + + @return + AND result of 64-bit atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_and_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_or + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_or(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_or_return + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_or_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_xor_return + Bitwise XOR operation of 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_xor_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_set_bit + Sets a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_set_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_clear_bit + Clears a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_clear_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_change_bit + Toggles a bit in a 64-bit atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_change_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_add(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add_return + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_add_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_sub_return + Subtracts a 64-bit integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_sub_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_inc + Increments a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_inc(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_inc_return + Increments a 64-bit atomic variable by one + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_inc_return(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_dec_return + Decrements a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_dec_return(unsigned long long *target) +{ + unsigned long long result; + long long minus1 = 0xFFFFFFFFFFFFFFFFLL; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (minus1) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_compare_and_set + Compares the current value of an 64-bit atomic variable with + the specified value and sets to a new value when compare is successful. + + @note1hang The function keep retrying until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val 64-bit old value to compare. + @param[in] new_val 64-bit new value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE -- Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE int +qurt_atomic64_compare_and_set(unsigned long long *target, + unsigned long long old_val, + unsigned long long new_val) +{ + unsigned long long current_val; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memd_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic64_barrier + Allows compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_barrier(void) +{ + /** @cond */ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); + /** @endcond */ +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_barrier.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_barrier.h new file mode 100755 index 0000000000000..7c6f787d43bc2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_barrier.h @@ -0,0 +1,140 @@ +#ifndef QURT_BARRIER_H +#define QURT_BARRIER_H + +/** + @file qurt_barrier.h + @brief Prototypes of Kernel barrier API functions. + + EXTERNALIZED FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup barrier_types +@{ */ +/*===================================================================== + Constants and macros +======================================================================*/ +#define QURT_BARRIER_SERIAL_THREAD 1 /**< Serial thread. */ +#define QURT_BARRIER_OTHER 0 /**< Other. */ + +#ifndef ASM +#include + +/*===================================================================== +Typedefs +======================================================================*/ + +/** QuRT barrier type. + */ +typedef union { + /** @cond */ + struct { + unsigned short threads_left; + unsigned short count; + unsigned int threads_total; + unsigned int queue; + unsigned int reserved; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_barrier_t; + +/** @} */ /* end_addtogroup barrier_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_init + Initializes a barrier object. + + @datatypes + #qurt_barrier_t + + @param[out] barrier Pointer to the barrier object to initialize. + @param[in] threads_total Total number of threads to synchronize on the barrier. + + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_init(qurt_barrier_t *barrier, unsigned int threads_total); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_destroy + Destroys the specified barrier. + + @note1hang Barriers must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Barriers must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to destroy. + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_destroy(qurt_barrier_t *barrier); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_wait + Waits on the barrier.\n + Suspends the current thread on the specified barrier. \n + The function return value indicates whether the thread was the last one to + synchronize on the barrier. + When a thread waits on a barrier, it is suspended on the barrier: \n + - If the total number of threads waiting on the barrier is less than the assigned value + of the barrier, no other action occurs. \n + - If the total number of threads waiting on the barrier equals the assigned value of the + barrier, all threads currently waiting on the barrier are awakened, allowing them to + execute past the barrier. + + @note1hang After its waiting threads are awakened, a barrier is automatically reset + and can be used again in the program without the need for re-initialization. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to wait on. + + @return + #QURT_BARRIER_OTHER -- Current thread awakened from barrier. \n + #QURT_BARRIER_SERIAL_THREAD -- Current thread is last caller of barrier. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_wait(qurt_barrier_t *barrier); + + +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BARRIER_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_busywait.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_busywait.h new file mode 100755 index 0000000000000..a4dab80a2520a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_busywait.h @@ -0,0 +1,62 @@ +#ifndef QURT_BUSYWAIT_H +#define QURT_BUSYWAIT_H + +/** + @file qurt_busywait.h + @brief Implementation of the busywait() function for + hardware based blocking waits that use the QTIMER as a reference. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ============================================================================*/ +/*============================================================================= + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Changes are listed in reverse chronological + * order. + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------------- + * 2018-03-20 pg Add Header file + ============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_busywait + Pauses the execution of a thread for a specified time.\n + Use for small microsecond delays. + + @note1hang The function does not return to the caller until + the time duration has expired. + + @param[in] pause_time_us Time to pause in microseconds. + + @return + None. + + @dependencies + None. + */ +void qurt_busywait (unsigned int pause_time_us); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BUSYWAIT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_callback.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_callback.h new file mode 100755 index 0000000000000..dc9b896c63454 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_callback.h @@ -0,0 +1,235 @@ +#ifndef QURT_CALLBACK_H +#define QURT_CALLBACK_H + +/** + @file qurt_callback.h + Definitions, macros, and prototypes for QuRT callback framework. + + QDI framework allows the development of root process drivers and services that + a user process client can interact with in a secure manner. QDI framework does + this by elevating the priviledge of user process thread, temporarily allowing + the thread execute in root context and letting it fall back to user context once + the QDI invocation is finished. + + The QuRT callback framework provides a safe mechanism for root process drivers + to execute callback functions in a user process. The framework hosts + dedicated worker threads in corresponding processes that handle the execution + of the callback function. This ensures that the callbacks occur in context of + the appropriate process thread, in result maintaining privilege boundaries. + + Prerequisites for use of this framework are: + 1. Driver is a QDI driver and client communicates with drivers using QDI + invocations. + 2. Appropriate callback configuration is specified in cust_config.xml for + the user process that intends to use this framework. + + qurt_cb_data_t is the public data structure that allows client to store all + the required information about the callback, including the callback function + and the arguments to pass to this function when it executes. + The client uses QDI interface to register this structure with root driver. + + Callback framework provides following APIs that a root driver can use to invoke callback. + These functions are described in qurt_qdi_driver.h header file. + + qurt_qdi_cb_invoke_async() triggers an asynchronous callback wherein the + invoking thread does not wait for the callback to finish executing. + + qurt_qdi_cb_invoke_sync() triggers a synchronous callback. Upon invocation + the invoking thread gets suspended till the callback function finishes execution. + + qurt_qdi_cb_invoke_sync_with_data() invokes a synchronous callback similar to + qurt_qdi_cb_invoke_sync(). It allows user to pass large data along with + the callback invocation to be utlized during the callback execution. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int qurt_cb_result_t; + +/* Callback framework error codes. + Callback framework returns a nonzero value if callback invocation is unsuccessful. + Following macros highlight cause of failure in more detail. +*/ +#define QURT_CB_ERROR -1 /* Callback registration failed.\n*/ +#define QURT_CB_OK 0 /* Success.\n*/ +#define QURT_CB_MALLOC_FAILED -2 /* QuRTOS malloc failure.\n*/ +#define QURT_CB_WAIT_CANCEL -3 /* Process exit cancelled wait operation.\n*/ +#define QURT_CB_CONFIG_NOT_FOUND -4 /* Callback configuration for process was not found.\n*/ +#define QURT_CB_QUEUE_FULL -5 /* Callback queue is serving at maximum capacity.*/ +/** @addtogroup cb_types +@{ */ +/** Callback registration data structure. + This data structure is used by a client attempting to register a callback with a QDI driver. + It holds the address of callback function and the argument supplied to the callback + function when it executes. +*/ +typedef struct { + /** @cond */ + void* cb_func; /*< Pointer to the callback function. */ + unsigned cb_arg; /*< Not interpreted by the framework.*/ + /** @endcond */ +} qurt_cb_data_t; + +/** @cond */ +/* Defines used as default if cust_config does not specify them. */ +#define CALLBACK_WORKER_STACK_SIZE 0x2000 +/** @endcond */ +/** @} */ /* end_addtogroup cb_typess */ +/**@ingroup func_qurt_cb_data_init + Initializes the callback data structure. + Entity registering a callback with the root process driver must call this function + to initialize callback registration data structure to the default value. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_init (qurt_cb_data_t* cb_data){ + cb_data->cb_func = NULL; + cb_data->cb_arg = 0; +} + +/**@ingroup func_qurt_cb_data_set_cbfunc + Sets up the callback function in the callback registration data structure. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_func Pointer to the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbfunc (qurt_cb_data_t* cb_data, void* cb_func){ + cb_data->cb_func = cb_func; +} + +/**@ingroup func_qurt_cb_data_set_cbarg + Sets up the callback argument. + This function sets up the argument passed to the callback function when it executes. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_arg Argument for the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbarg (qurt_cb_data_t* cb_data, unsigned cb_arg){ + cb_data->cb_arg = cb_arg; +} + +/** @cond */ +/**@ingroup driver_support_functions + Invokes an asynchronous callback for a specified process. + A driver that resides in the root process calls this API to launch a callback in + a process described by the client_handle. + After the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is not suspended during the callback execution period. + The API returns immediately with a success/failure error code. + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_async(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process. + A driver that resides in a root process calls this API to launch a sync callback in + a process described by the client_handle. + AFter the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is suspended during the callback execution period. + If the process in which to execute the callback exits or terminates, the caller is + woken up with error code #QURT_CB_WAIT_CANCEL (refer to qurt_callback.h). + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process, passing driver data to the user PD. + This function is similar to qurt_qdi_cb_invoke_sync() and allows the driver to pass arbitrary data to + the user process as part of the callback invocation. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @param data Driver arbitrary data to pass to the user process. Memory pointed to by data + must be accessible to the user PD. The root driver can allocate such memory by + using qurt_mem_mmap(). + @param data_len Driver arbitrary data length. + + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync_with_data( int client_handle, + qurt_cb_data_t* cb_data, + int prio, + void *data, + unsigned data_len + ); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_clade.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_clade.h new file mode 100755 index 0000000000000..d7442cf98dd94 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_clade.h @@ -0,0 +1,62 @@ +#ifndef QURT_CLADE_H +#define QURT_CLADE_H +/** + @file qurt_clade.h + @brief Prototypes of Cache Line Accelerated Decompression Engine (CLADE) API. + CLADE is a cache line level memory compression system that is used to + decrease DRAM usage. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_clade2_get + Reads the value of the clade2 register. + + @param[in] offset Offset from the clade2 cfg base. + @param[out] *value Pointer to the register value read from the offset. + + @return + #QURT_EOK - Successfully read the value from the register at offset \n + #QURT_EINVALID - Offset passed is incorrect + + @dependencies + None. + */ +int qurt_clade2_get(unsigned short offset, unsigned int *value); + +/**@ingroup func_qurt_clade2_set + Sets the PMU register; only PMU_SEL register can be set. + + @param[in] offset Offset from the QURTK_clade2_cfg_base. + @param[in] value Value to set at offset. + + @return + #QURT_EOK -- Successfully set the value at offset. \n + #QURT_ENOTALLOWED -- Set operation performed at an offset other than CLADE2_PMU_SELECTION_REG. + + @dependencies + None. + */ +int qurt_clade2_set(unsigned short offset, unsigned int value); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CLADE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cond.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cond.h new file mode 100755 index 0000000000000..6e65ed82a8393 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cond.h @@ -0,0 +1,219 @@ +#ifndef QURT_COND_H +#define QURT_COND_H +/** + @file qurt_cond.h + @brief Prototypes of kernel condition variable object API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup condition_variables_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** QuRT condition variable type. */ +typedef union { + /** @cond */ + unsigned long long raw; + struct { + unsigned int count; + unsigned int n_waiting; + unsigned int queue; + unsigned int reserved; + }X; + /** @endcond */ +} qurt_cond_t; + +/** @} */ /* end_addtogroup condition_variables_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_cond_init + Initializes a conditional variable object. + + @datatypes + #qurt_cond_t + + @param[out] cond Pointer to the initialized condition variable object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_init(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_destroy + Destroys the specified condition variable. + + @note1hang Conditions must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Conditions must not be destroyed while they are still in use. If this occurs, + the behavior of QuRT is undefined. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to destroy. + + @return + None. + + */ +/* ======================================================================*/ +void qurt_cond_destroy(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_signal + Signals a waiting thread that the specified condition is true. \n + + When a thread wishes to signal that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the signal condition operation. \n + -# Unlock the mutex. + + @note1hang Failure to properly lock and unlock a mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_signal(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_broadcast + Signals multiple waiting threads that the specified condition is true.\n + When a thread wishes to broadcast that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the broadcast condition operation. \n + -# Unlock the mutex.\n + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_broadcast(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable (suspends the thread and unlocks the mutex). + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t \n + #qurt_mutex_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait(qurt_cond_t *cond, qurt_mutex_t *mutex); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait2 + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable, which suspends the thread and unlocks the mutex. + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @note1cont This is the same API as qurt_cond_wait(), use this version + when using mutexes of type #qurt_rmutex2_t. + + @datatypes + #qurt_cond_t \n + #qurt_rmutex2_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with the condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait2(qurt_cond_t *cond, qurt_rmutex2_t *mutex); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_COND_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_consts.h new file mode 100755 index 0000000000000..b1e35998e73b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_consts.h @@ -0,0 +1,315 @@ +#ifndef QURT_CONSTS_H +#define QURT_CONSTS_H + +/** + @file qurt_consts.h + @brief QuRT constants and definitions + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* Definitions of system events. System events suspend + a thread and put it into suspending_list. + The system event number is saved in CONTEXT::error::cause field + of the suspended thread. An event handler thread such as + page fault handler or system error handler can wake up the suspended + thread. + */ +#define QURT_EVENT_PAGEFAULT 0x1 /* Page fault event. */ +#define QURT_EVENT_SYSTEM_ERR 0x2 /* System error event. */ +#define QURT_EVENT_SUSPEND 0x3 +#define QURT_EVENT_PROCESS_EXIT 0x4 /* Process termination event.*/ + +#define QURT_SYSENV_MAX_THREADS_TYPE 1 /* Maximum threads object. */ +#define QURT_SYSENV_PROCNAME_TYPE 2 /* Process name object. */ +#define QURT_SYSENV_MAX_PI_PRIO_TYPE 3 /* Maximum pi priority object. */ +#define QURT_SYSENV_ARCH_REV_TYPE 4 /* Architecture version object. */ +#define QURT_SYSENV_APP_HEAP_TYPE 5 /* Application heap object. */ +#define QURT_SYSENV_REGION_ATTR_DEFAULT 7 /* Default region attributes. */ +#define QURT_SYSENV_STACK_PROFILE_COUNT_TYPE 8 /* Stack profile count type. */ +#define QURT_SYSENV_ISLAND_CONFIG_TYPE 9 /*island configuration check*/ +#define QURT_SYSENV_HTHREADS_TYPE 10 /* Active threads objec */ +#define QURT_SYSENV_CONFIG_IMAGE_START_LO 11 /* Config image start address for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_START_HI 12 /* Config Image start address for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_LO 13 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_HI 14 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_PLATPARAMS 15 /* Platformparams for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_SIZE 16 /* Config image Size for DTB parsing */ +#define QURT_SYSENV_L2_CACHE_LINE_SIZE 17 /*L2 cache line size*/ + +/* Get q6 regs */ +#define QURT_GET_SSR 1 +#define QURT_GET_CCR 2 +#define QURT_GET_CFGBASE 3 +#define QURT_GET_SYSCFG 4 +#define QURT_GET_REV 5 + + +/** @cond rest_reg_dist */ +/** @addtogroup performance_monitor_macros +@{ */ + +/* PMU */ +#define QURT_PMUCNT0 0 /**< */ +#define QURT_PMUCNT1 1 /**< */ +#define QURT_PMUCNT2 2 /**< */ +#define QURT_PMUCNT3 3 /**< */ +#define QURT_PMUCFG 4 /**< */ +#define QURT_PMUEVTCFG 5 /**< */ + +/* new since V55 */ +#define QURT_PMUCNT4 6 /**< */ +#define QURT_PMUCNT5 7 /**< */ +#define QURT_PMUCNT6 8 /**< */ +#define QURT_PMUCNT7 9 /**< */ +#define QURT_PMUEVTCFG1 10 /**< */ + +/* new since V61 */ +#define QURT_PMUSTID0 11 /**< */ +#define QURT_PMUSTID1 12 /**< */ + +#define QURT_PMUCNTSTID0 13 /**< */ +#define QURT_PMUCNTSTID1 14 /**< */ +#define QURT_PMUCNTSTID2 15 /**< */ +#define QURT_PMUCNTSTID3 16 /**< */ +#define QURT_PMUCNTSTID4 17 /**< */ +#define QURT_PMUCNTSTID5 18 /**< */ +#define QURT_PMUCNTSTID6 19 /**< */ +#define QURT_PMUCNTSTID7 20 /**< */ + +/** @} */ /* end_addtogroup performance_monitor_macros */ +/** @endcond */ + +/* + Power collapse operation +*/ +#define QURT_POWER_SHUTDOWN 0 /**< */ +#define QURT_TCXO_SHUTDOWN 1 /**< */ +#define QURT_POWER_CMD_PREPARE 0 /**< */ +#define QURT_POWER_CMD_PERFORM 1 /**< */ +#define QURT_POWER_CMD_EXIT 2 /**< */ +#define QURT_POWER_CMD_FAIL_EXIT 3 /**< */ +#define QURT_POWER_CMD_PERFORM_L2_RETENTION 4 /**< */ +#define QURT_POWER_CMD_PERFORM_SAVE_TCM 5 /**< */ +#define QURT_POWER_CMD_DEEP_SLEEP 6 /**< */ + + +/** @addtogroup thread_macros +@{ */ +#define QURT_MAX_HTHREAD_LIMIT 8U /**< Limit on the maximum number of hardware threads supported by QuRT for any + Hexagon version. Use this definition to define arrays, and so on, in + target independent code. */ +/** @} */ /* end_addtogroup thread_macros */ + +/** @cond internal_only */ +/** @addtogroup power_management_macros +@{ */ +/** + L2 cache retention mode +*/ +#define QURT_POWER_SHUTDOWN_TYPE_L2NORET QURT_POWER_CMD_PERFORM /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_L2RET QURT_POWER_CMD_PERFORM_L2_RETENTION /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_SAVETCM QURT_POWER_CMD_PERFORM_SAVE_TCM /**< */ +/** @} */ /* end_addtogroup power_management_macros */ +/** @endcond */ + +/* + QURT_system_state + Use for debugging the shutdown/startup process. + + State transition for cold boot: + QURT_BOOT_SETUP_ISDB --> QURT_CBOOT_BSP_INIT --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT --> + QURT_CBOOT_KERNEL_INIT_DONE --> QURT_CBOOT_PLAT_CONFIG_DONE --> + QURT_CBOOT_ROOT_TASK_STARTED + + State transition for power collapse: + QURT_PREPARE_SINGLE_MODE --> QURT_PERFORM_IPEND --> + QURT_PERFORM_SAVE_TLB --> QURT_PERFORM_SWITCH_PC --> + cache flush states (dependent on L2 retention config) + + State transition for warm boot: + QURT_BOOT_SETUP_ISDB --> QURT_WBOOT_INIT_TLB --> + QURT_WBOOT_SET_1TO1_MAP --> QURT_WBOOT_REMOVE_1TO1_MAP --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT +*/ +#define QURT_PREPARE_SINGLE_MODE 1 /**< */ +#define QURT_PREPARE_END 2 /**< */ +#define QURT_PERFORM_IPEND 3 /**< */ +#define QURT_PERFORM_SAVE_ISDP 4 /**< */ +#define QURT_PERFORM_SAVE_PMU 5 /**< */ +#define QURT_PERFORM_SAVE_TLB 6 /**< */ +#define QURT_PERFORM_SWITCH_PC 7 /**< */ +#define QURT_PERFORM_EXIT 8 /**< */ +#define QURT_FLUSH_L1CACHE 9 /**< */ +#define QURT_FLUSH_L2CACHE 0xA /**< */ +#define QURT_FLUSH_CACHE_DONE 0xB /**< */ +#define QURT_SWITCH_PC_DONE 0xC /**< */ +#define QURT_BOOT_SETUP_ISDB 0xD /**< */ +#define QURT_WBOOT_INIT_TLB 0xE /**< */ +#define QURT_WBOOT_SET_1TO1_MAP 0xF /**< */ +#define QURT_WBOOT_CFG_ADV_SYSCFG 0x10 /**< */ +#define QURT_WBOOT_REMOVE_1TO1_MAP 0x11 /**< */ +#define QURT_CBOOT_BSP_INIT 0x12 /**< */ +#define QURT_CBOOT_END_CLEAN_L1CACHE 0x13 /**< */ +#define QURT_CBOOT_END_CLEAN_INIT 0x14 /**< */ +#define QURT_CBOOT_END_OS_INIT 0x15 /**< */ +#define QURT_CBOOT_TLB_DUMP_LOAD 0x16 /**< */ +#define QURT_CBOOT_TLB_STATIC_LOAD 0x17 /**< */ +#define QURT_CBOOT_KERNEL_INIT_DONE 0x18 /**< */ +#define QURT_CBOOT_PLAT_CONFIG_DONE 0x19 /**< */ +#define QURT_CBOOT_ROOT_TASK_STARTED 0x1A /**< */ +#define QURT_IMPRECISE_EXCEPTION 0x1B /**< */ +#define QURT_WBOOT_DEBUG_L2_START 0x1C /**< */ +#define QURT_WBOOT_DEBUG_L2_END 0x1D /**< */ +#define QURT_NMI_SAVE_L2VIC_COMPLETE 0x1E /**< */ +#define QURT_NMI_HANDLER_COMPLETE 0x1F /**< */ +#define QURT_NMI_AFTER_SAVE_GLOBAL 0x20 /**< */ +#define QURT_WBOOT_START 0x21 /**< */ +#define QURT_ENTER_ISLAND 0x22 /**< */ +#define QURT_EXIT_ISLAND 0x23 /**< */ +#define QURT_LOAD_NOTIFIER_TCB 0x24 /**< */ +#define QURT_ABNORMAL_RESET 0x25 /**< */ +/* + Thread attributes +*/ + +#define QURT_THREAD_ATTR_GP 0x00000002 /*< */ +#define QURT_THREAD_ATTR_UGP 0x00000003 /*< User general pointer (UGP)*/ +#define QURT_THREAD_ATTR_PREFETCH 0x00000004 /*< */ +#define QURT_THREAD_ATTR_TID 0x00000005 /*< */ +#define QURT_THREAD_ATTR_CACHE_PART 0x00000007 /*< */ +#define QURT_THREAD_ATTR_COPROCESSOR 0x00000008 /*< */ +#define QURT_THREAD_ATTR_GET_L2CACHE_PART 0x00000009 /*< */ +#define QURT_THREAD_ATTR_SET_FRML 0x0000000A /*< */ +#define QURT_THREAD_ATTR_STID_GET 0x0000000B /*< */ +#define QURT_THREAD_ATTR_STID_SET 0x0000000C /*< */ +#define QURT_THREAD_ATTR_AUTOSTACK 0x0000000D /*< */ +#define QURT_THREAD_ATTR_SYSTEM_THREAD 0x0000000E /*< */ +#define QURT_THREAD_ATTR_STID_SET2 0x0000000F /*< */ +#define QURT_THREAD_ATTR_STID_SET2_ACKNOWLEDGE 0x00000010 /*< */ +#define QURT_THREAD_ATTR_STID_GET2 0x00000011 /*< */ + +/** Cache operations*/ +#define QURT_DCCLEAN 0U /* Clean Dcache. */ +#define QURT_DCINV 1U /* Invalidate Dcache. */ +#define QURT_DCCLEANINV 2U /* Clean and invalidate Dcache. */ +#define QURT_ICINV 3U /* Invalidate Icache. */ +#define QURT_DUMP_DCTAGS 4U /* For testing purpose. */ +#define QURT_FLUSH_ALL 5U /* Flush entire L1 and L2 cache. */ +#define QURT_TABLE_FLUSH 6U /* Flush based on table of physical pages */ +#define QURT_CLEAN_INVALIDATE_ALL 7U /* Flush and invalidate entire L1 and L2 cache. */ +#define QURT_L2CACHE_LOCK_LINES 8U /* l2 cache lock lines */ +#define QURT_L2CACHE_UNLOCK_LINES 9U /* l2 cache unlock lines */ +#define QURT_CLEAN 10U /* Flush L1 and L2 cache */ +#define QURT_CLEAN_INVALIDATE 11U /* Flush and invalidate L1 and L2 cache. */ +#define QURT_CLEAN_INVALIDATE_L2 12U /* Flush and invalidate entire L2 cache. */ + +/**@ingroup chapter_prefined_symbols */ +/**@xreflabel{hdr:QURT_API_VERSION}*/ + + +/* Process state. */ +#define QURT_UPDATE_PROCESS_STATE 0 /**< */ +#define QURT_MP_INIT 1 /*< */ +#define QURT_MP_RUNNING 2 /*< */ +#define QURT_MP_STOPPED 3 /*< */ + +/* QuRT reset reason. */ +#define QURT_NORMAL_BOOT 0 /* Normal boot. */ +#define QURT_WARM_BOOT 1 /* Power collapse warm boot. */ +#define QURT_WARM_BOOT_L2_RETENTION 2 /* Power collapse with L2 retention warm boot. */ +#define QURT_WARM_BOOT_SAVE_TCM 3 /* Power collapse with saving TCM. */ +#define QURT_QUICK_BOOT 4 /* Deep sleep. */ + +/* QuRT Wait for Idle command */ +#define QURT_WAIT_FOR_IDLE_DISABLE 0 /*< */ +#define QURT_WAIT_FOR_IDLE_ENABLE 1 /*< */ +#define QURT_WAIT_FOR_IDLE 2 /*< */ +#define QURT_WAIT_FOR_IDLE_CANCEL 3 /*< */ + +/*QuRT island exit stages */ +#define QURT_ISLAND_EXIT_STAGE1 1 /*< */ +#define QURT_ISLAND_EXIT_STAGE2 2 /*< */ + +#define QURT_MAX_NAME_LEN 64 /*< */ + +#define MAX_POOL_RANGES 16 /*< */ + +/* key definitions for debug thread info */ +//#define MAX_TCB_KEY 40 //whatever is a good number or makes debug thread structure be 1K +#define KEY_SCHDULER_STATE 1 /*< */ +#define KEY_PRIORITY 2 /*< */ +#define KEY_PRIORITY_ORIG 3 /*< */ +#define KEY_STACK_BOTTOM 4 // Currently not populated +#define KEY_STACK_TOP 5 // Currently not populated +#define KEY_HVX_STATE 6 /*< */ +#define KEY_FUTEX_OBJECT 7 /*< */ +#define KEY_THREAD_ID 8 /*< */ +#define KEY_PROFILE_CYCLE_LO 9 // Currently not populated +#define KEY_PROFILE_CYCLE_HI 10 // Currently not populated +#define KEY_ERROR_ADDRESS 11 // This holds the BADVA +#define KEY_ERROR_CAUSE 12 // This is the same as QURT_error_info.cause +#define KEY_ERROR_CAUSE2 13 // This is the same as QURT_error_info.cause2 +#define KEY_ERROR_SSR 14 /*< Holds the SSR value */ +#define QURT_RESERVED -1 + +/* VTLB method IDs. */ +#define QURT_VTLB_ENTRY_CREATE 0U +#define QURT_VTLB_ENTRY_DELETE 1U +#define QURT_VTLB_ENTRY_READ 2U +#define QURT_VTLB_ENTRY_WRITE 3U +#define QURT_VTLB_ENTRY_PROBE 4U +#define QURT_VTLB_ENTRY_SPLIT 5U +#define QURT_VTLB_ENTRY_MERGE 6U +#define QURT_VTLB_ENTRY_STATISTICS 7U +#define QURT_VTLB_ENTRY_SET_SPECIAL 8U +#define QURT_VTLB_QUEUE_PPAGE 9U +#define QURT_VTLB_RECLAIM_STACK_PAGES 10U +#define QURT_VTLB_ASID_SET_STATE_FAST 11U +#define QURT_VTLB_ASID_SET_STATE 12U +#define QURT_VTLB_ENTRY_SET_EXTENSION 13U +#define QURT_VTLB_ENTRY_CLEAR_EXTENSION 14U + +/* VTCM window access control HWIO programming. */ +#define QURT_VTCM_WINDOW_ENABLE 1U +#define QURT_VTCM_WINDOW_DISABLE 0U +#define QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT 0xFFFU +#define QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT 0U + +/** @cond */ +/* ETM source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< Memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< Memory source of SAC* is data. */ + +/* ETM PID status flags */ +#define QURT_ETM_NO_PID 0xFFFFFFFF /**< No PID is selected. */ +/** @endcond */ + +/* execution context */ +#define QURT_CTX_USER 1 +#define QURT_CTX_GUEST 2 + +/* Profiling STID */ +#define QURT_STID_DEFAULT 0U + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cycles.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cycles.h new file mode 100755 index 0000000000000..b599493f5d563 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_cycles.h @@ -0,0 +1,301 @@ + +#ifndef QURT_CYCLES_H +#define QURT_CYCLES_H 1 +/** + @file qurt_cycles.h + Prototypes of kernel pcycle API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ + +/**@ingroup func_qurt_profile_reset_idle_pcycles + @xreflabel{hdr:qurt_profile_reset_idle_pcycles} + Sets the per-hardware-thread idle cycle counts to zero. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_idle_pcycles (void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_thread_pcycles + @xreflabel{hdr:qurt_profile_get_thread_pcycles} + Gets the count of the running processor cycles for the current thread.\n + Returns the current running processor cycle count for the current QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @return + Integer -- Running processor cycle count for current thread. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_profile_get_thread_pcycles(void); + + +/*======================================================================*/ +/**@ingroup func_qurt_get_core_pcycles + @xreflabel{hdr:qurt_get_core_pcycles} + Gets the count of core processor cycles executed.\n + Returns the current number of running processor cycles executed since the Hexagon + processor was last reset. + + This value is based on the hardware core clock, which varies in speed according to the + processor clock frequency. + + @note1hang Because the hardware core clock stops running when the processor shuts + down (due to all of the hardware threads being idle), treat the cycle values returned + by this operation as relative rather than absolute. + + @note1cont Thread cycle counts are valid only in the V4 Hexagon processor version. + + @return + Integer -- Current count of core processor cycles. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_get_core_pcycles(void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles + + @deprecated use #qurt_profile_get_idle_pcycles2 instead + + Gets the current idle processor cycle counts for a maximum of 6 hardware threads. Use + #qurt_profile_get_idle_pcycles2 for reading pcycles without limitation on maximum hardware threads. + + This operation accepts a pointer to a user-defined array, and writes to the array the current + idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling is enabled or not, + and resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be a minimum of the number of hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_idle_pcycles (unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles2 + Gets the current idle processor cycle counts for maximum available hardware threads. + + This operation accepts a pointer to a user-defined array with length in bytes, and writes + to the array the current idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling enable status, and + resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be equivalent to the number of hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, + it returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_idle_pcycles2 (unsigned long long *pcycles, unsigned int length_in_bytes); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles + + @deprecated use #qurt_profile_get_threadid_pcycles2 instead + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for a maximum of 6 hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Valid thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be a minimum of the number of + hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_threadid_pcycles (int thread_id, unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles2 + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for maximum available hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be equivalent to the number of + hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, it + returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + #QURT_ENOTHREAD -- Operation failed due to invalid #thread_id + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_threadid_pcycles2 (int thread_id, unsigned long long *pcycles, unsigned int length_in_bytes); + + +/*======================================================================*/ +/**@ingroup func_qurt_profile_reset_threadid_pcycles + @xreflabel{hdr:qurt_profile_reset_threadid_pcycles} + Sets the per-hardware-thread running cycle counts to zero for the specified QuRT thread. + + @param[in] thread_id Thread identifier. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_threadid_pcycles (int thread_id); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_enable + @xreflabel{hdr:qurt_profile_enable} + Enables profiling.\n + Enables or disables cycle counting of the running and idle processor cycles. + Profiling is disabled by default. \n + + @note1hang Enabling profiling does not automatically reset the cycle counts -- this must be + done explicitly by calling the reset operations before starting cycle counting. + Cycle counting starts from the instant of it was enabled using this API, and + halts on profiling disable. + + @param[in] enable Profiling. Values: \n + - 0 -- Disable profiling \n + - 1 -- Enable profiling @tablebulletend + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_enable (int enable); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_pcycles + @xreflabel{hdr:qurt_get_hthread_pcycles} + Reads the GCYCLE_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values are 1 through . + + + @return + Value read from GCYCLE_nT register. This value indicates the total number of pcycles that got executed + from reset to current point of execution when n threads are in run mode + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_pcycles(int n); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_commits + @xreflabel{hdr:qurt_get_hthread_commits} + Reads the GCOMMIT_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values: 1 through . + + @return + Value read from the GCOMMIT_nT register. This value indicates the total number of packets + committed from reset to current point of execution when n threads are in run mode. + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_commits(int n); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_devtree.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_devtree.h new file mode 100755 index 0000000000000..4adee45bb44a2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_devtree.h @@ -0,0 +1,161 @@ +#ifndef QURT_DEVTREE_H +#define QURT_DEVTREE_H +/** + @file qurt_devtree.h + @brief Prototypes and structures for device tree aware QuRT library function. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +*/ +/*qurt_callback is included by qurt_qdi_driver.h and depends on NULL being def. + callback is not used here, so define NULL here to avoid including the world*/ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "libfdt.h" +#include "DTBExtnLib.h" +#include "qurt_qdi_ext.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_BLOB_ID (-1) +#define DEFAULT_BLOB_ID 0 + +/** QURT Device Tree Mapping Macros */ +#define QURT_DT_MAPPING_FAILED (-1) +#define QURT_DT_FLAG_ISLAND 0x1 +#define QURT_DT_FLAG_PHYSADDR 0x2 + +/** Device Tree type for Root PD Device tree. +    Root PD Device Tree will typically describe the hardware in the subsystem. +    This is the /soc portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_ROOT 0 + +/** Device Tree type for Local Device tree. +    Local Device Tree will typically contain the software settings. +    This is the /sw portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_LOCAL 1 + +int qurt_devtree_init(void); + +/**@ingroup func_qurt_dt_mapping_create + Creates a memory mapping from the specified property of the specified device + tree node. Returns virtual addresses and sizes. + + @param[in] offset Device tree node offset. + @param[in] flags Flags to configure memory. Overloaded as property + index if reg_name is NULL. + @param[in] reg_name Identifies property to use for mapping, should + resemble a region. + @param[out] vaddr Return pointer for the virtual region address. + @param[out] size Return pointer for the virtual region size. + + @return + Result code indicating success or failure \n +*/ +int qurt_dt_mapping_create(fdt_node_handle *devtreeNode, int flags, char *regionName, int regionIdx, + unsigned long long *vaddr, unsigned long long *size); + +/**@ingroup func_qurt_dt_mapping_create2 + + Creates a memory mapping from the specified property of the specified device + tree node. + + Returns virtual addresses and sizes according to architecture (i.e either 32 bit or 64 bit). + + @param[in] devtreeNode Device Tree node + + @param[in] dt_map_flags Flags to configure memory mapping and are reserved for future purpose. + (0) - Default value assumes details from DT node are phys address, size. + QURT_DT_FLAG_ISLAND + + NOTE: The PA needs to be added to corresponding island spec to create an island mapping + + @param[in] regionName NULL or name of index in range to return, should + resemble a region. Ex.reg-names = "base", "rx", "tx"; + + @param[in] regionIdx Index of range to return. Ex reg = <0x1000 0x20>, <0x10000 0x100>, <0x18000 0x100 >; + + NOTE: If client specifies both re_name & regionIdx. The precedence of + region name is taken over and region index is ignored. + + @param[in] dt_map_perm Mapping access permissions(R/W), + QURT_PERM_READ + QURT_PERM_WRITE + + @param[in] cache_attr QuRT cache mode type's : + QURT_MEM_CACHE_DEVICE + QURT_MEM_CACHE_WRITEBACK + Other required cache type enums in qurt_types.h can also be passed. + + NOTE: No default value for cache & perm is present. + Client always needs to pass any of defined the flags. + + @param[out] vaddr Return pointer to the variable that holds the virtual address + @param[out] size Return pointer for the virtual region size. + + @return + #QURT_EOK Success indicating mapping created properly. + #QURT_DT_MAPPING_FAILED Failed to create mapping. + #QURT_EINVALID Mismatch in the architecture. + + else FdtLib or thirdparty error code. + +*/ +int qurt_dt_mapping_create2(fdt_node_handle *devtreeNode, unsigned int dt_map_flags, + char *regionName, int regionIdx, unsigned int dt_map_perm, int cache_attr, void **vaddr, size_t *size); + +/**@ingroup func_qurt_dt_isr_register + Device tree aware registration of an interrupt service routine (ISR) to an ISR thread. + The interrupt defined in the specified device tree node is enabled when this function returns success. + + @datatypes + #qurt_thread_t \n + #fdt_node_handle + + @param[in] dt_node Device tree node that specifies the interrupt property. + @param[in] dt_int_index Index of the specific interrupt to use within the device tree node structure. + Specify either this or int_name, use -1 if string is used. + @param[in] dt_int_name Name of the specific interrupt to use within the device tree node structure. + Either this or int_index should be specified, use NULL if index is used + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create(), defined by qurt_isr_register2(). + @param[in] prio Priority of the ISR, defined by qurt_isr_register2(). + @param[in] flags Defines ACK type. Values : \n + #QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the kernel. + #QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + Defined by qurt_isr_register2(). + @param[in] isr ISR with proto type void isr (void *arg, int int_num), defined by qurt_isr_register2(). + @param[in] arg First argument of the ISR when it is called to service the interrupt, defined by qurt_isr_register2(). + + @return + #QURT_EOK -- Successfully registered the ISR for the interrupt \n + #QURT_EINT -- Interrupt not configured \n + #QURT_EINVALID -- Invalid thread ID \n + #QURT_EDISABLED -- The feature is disabled \n + #QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Create the thread ID qurt_isr_create(). + ISR registration completed with qurt_isr_register2(). + */ +int qurt_dt_isr_register(fdt_node_handle *dt_node, int dt_int_index, char * dt_int_name, qurt_thread_t isr_thread_id, + unsigned short prio, unsigned short flags, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_dt_blob_id_get + Returns the Blob ID for the Blob type passed. + The value returned from this API can be passed as Blob ID parameter to DTBExtnLib APIs. + + @param[in] blob_type  Blob type to look up. + @return Blob ID for the passed Blob Type. +*/ +int qurt_dt_blob_id_get(unsigned int blob_type); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ecc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ecc.h new file mode 100755 index 0000000000000..09312684e99af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ecc.h @@ -0,0 +1,168 @@ +#ifndef QURT_ECC_H +#define QURT_ECC_H + + +/*===================================================================== + + @file qurt_ecc.h + @brief Prototypes of QuRT memory ECC API functions + + Copyright (c) 2018, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup exception_handling_types +@{ */ +// ECC memory definition +typedef enum { + QURT_ECC_MEM_L1_ICACHE = 0, /**< ECC memory L1 ICache. */ + QURT_ECC_MEM_L1_DCACHE = 1, /**< ECC memory L1 DCache.*/ + QURT_ECC_MEM_L2_CACHE = 2, /**< ECC memory L2 Cache.*/ + QURT_ECC_MEM_VTCM = 3 /**< ECC memory VTCM.*/ +} qurt_ecc_memory_t; +/** @} */ /* end_addtogroup exception_handling_types */ + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup exception_handling_macros +@{ */ + +#define QURT_ECC_ERR_DETECTED_STATUS 0 /**< ECC error detected. */ +#define QURT_ECC_ERR_TYPE 1 /**< ECC error type.*/ +// ECC status type + +#define QURT_ECC_CORRECTABLE_COUNT (1<<0) /**< ECC correctable count.*/ +#define QURT_ECC_UNCORRECTABLE_COUNT (1<<1) /**< ECC uncorrectable count.*/ +#define QURT_ECC_REGION_LOGGING (1<<2) /**< ECC region logging.*/ +// ECC enable/disable definition + +#define QURT_ECC_PROTECTION_DISABLE (0<<0) /**< Bit 0. */ +#define QURT_ECC_PROTECTION_ENABLE (1<<0) /**< Bit 0. */ +/** @} */ /* end_addtogroup exception_handling_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_ecc_enable + Enables or disables ECC protection on a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] enable Set to one of the following values: + - #QURT_ECC_PROTECTION_ENABLE + - #QURT_ECC_PROTECTION_DISABLE @tablebulletend + + @return + - #QURT_EOK -- ECC enabling or disabling setup is performed successfully + - Others -- Failure + + @dependencies + None. + */ +int qurt_ecc_enable( qurt_ecc_memory_t memory, unsigned int enable ); + + +/**@ingroup func_qurt_ecc_get_error_status + Gets ECC error status for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following: + - #QURT_ECC_ERR_DETECTED_STATUS + - #QURT_ECC_ERR_TYPE @tablebulletend + + @return + Returns the following when the type is #QURT_ECC_ERR_DETECTED_STATUS: + - 0 -- No error detected \n + - 1 -- At least one error detected \n + Returns the following when the type is #QURT_ECC_ERR_TYPE: \n + - 0 through 1 -- Correctable error \n + - 2 -- Uncorrectable error + + @dependencies + None. + */ +int qurt_ecc_get_error_status( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_get_error_count + Gets the ECC error count for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values:\n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT @tablebulletend + + @return + Error count for the specified error type. + + @dependencies + None. + */ +int qurt_ecc_get_error_count( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_clear_error_count + Clears ECC error count or region logging for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: \n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one or multiple OR'ed of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT \n + - #QURT_ECC_REGION_LOGGING @tablebulletend + + @return + #QURT_EOK -- Error count successfully cleared \n + Others -- Failure at clearing the error count + + @dependencies + None. + */ +int qurt_ecc_clear_error_count( qurt_ecc_memory_t memory, unsigned int type ); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ECC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_error.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_error.h new file mode 100755 index 0000000000000..f4666b396c378 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_error.h @@ -0,0 +1,149 @@ +#ifndef QURT_ERROR_H +#define QURT_ERROR_H + +/** + @file qurt_error.h + Error results- QURT defines a set of standard symbols for the error result values. This file lists the + symbols and their corresponding values. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021-2022 , 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ +#include "qurt_except.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup chapter_error +@{ */ + +/*===================================================================== +Constants and macros +======================================================================*/ +#define QURT_EOK 0 /**< Operation successfully performed. */ +#define QURT_EVAL 1 /**< Wrong values for the parameters. The specified page does not exist. */ +#define QURT_EMEM 2 /**< Not enough memory to perform the operation.*/ + +#define QURT_EINVALID 4 /**< Invalid argument value; invalid key. */ +/** @cond */ +#define QURT_EUNKNOWN 6 /**< Defined but never used in QuRT. */ +#define QURT_ENOMSGS 7 /**< Message queue is empty. */ +#define QURT_EBADF 9 /**< Bad message queue descriptor. */ +/** @endcond */ +#define QURT_EFAILED 12 /**< Operation failed. */ + +#define QURT_ENOTALLOWED 13 /**< Operation not allowed. */ + +/** @cond */ +#define QURT_EDUPCLSID 14 /*< Duplicate class ID. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOREGISTERED 20 /**< No registered interrupts.*/ +/** @endcond */ + + +/** @cond */ +#define QURT_EISDB 21 /*< Power collapse failed due to ISDB being enabled. */ +#define QURT_ESTM 22 /*< Power collapse failed in a Single-threaded mode check. */ +/** @endcond */ + + +/** @cond rest_reg_dist */ +#define QURT_ETLSAVAIL 23 /**< No free TLS key is available. */ +#define QURT_ETLSENTRY 24 /**< TLS key is not already free. */ +/** @endcond */ + +#define QURT_EINT 26 /**< Invalid interrupt number (not registered). */ +/** @cond rest_reg_dist */ +#define QURT_ESIG 27 /**< Invalid signal bitmask (cannot set more than one signal at a time). */ +/** @endcond */ + +/** @cond */ +#define QURT_EHEAP 28 /**< No heap space is available. */ +#define QURT_ENOSPC 28 /**< No space to create another queue in the system. */ +#define QURT_EMEMMAP 29 /**< Physical address layout is not supported by the kernel. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOTHREAD 30 /**< Thread no longer exists. */ +/** @endcond */ +/** @cond */ +#define QURT_EL2CACHE 31 /**< L2cachable is not supported in kernel invalidate/cleaninv. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_EALIGN 32 /**< Not aligned. */ +#define QURT_EDEREGISTERED 33 /**< Interrupt is already deregistered.*/ +/** @endcond */ + +/** @cond internal_only */ + +#define QURT_ETLBCREATESIZE 34 /**< TLB create error -- Incorrect size.*/ +#define QURT_ETLBCREATEUNALIGNED 35 /**< TLB create error -- Unaligned address.*/ +/** @endcond */ +/** @cond rest_reg_dist*/ +#define QURT_EEXISTS 35 /**< File or message queue already exists. */ +#define QURT_ENAMETOOLONG 36 /**< Name too long for message queue creation. */ +#define QURT_EPRIVILEGE 36 /**< Caller does not have privilege for this operation.*/ + +#define QURT_ECANCEL 37 /**< A cancellable request was canceled because the associated process was asked to exit.*/ +/** @endcond */ + +/** @cond */ +#define QURT_EISLANDTRAP 38 /*< Unsupported TRAP is called in Island mode.*/ + +#define QURT_ERMUTEXUNLOCKNONHOLDER 39 /*< Rmutex unlock by a non-holder.*/ +#define QURT_ERMUTEXUNLOCKFATAL 40 /*< Rmutex unlock error, all except the non-holder error.*/ +#define QURT_EMUTEXUNLOCKNONHOLDER 41 /*< Mutex unlock by a non-holder.*/ +#define QURT_EMUTEXUNLOCKFATAL 42 /*< Mutex unlock error, all except the non-holder error.*/ +#define QURT_EINVALIDPOWERCOLLAPSE 43 /*< Invalid power collapse mode requested. */ +/** @endcond */ +#define QURT_EISLANDUSEREXIT 44 /**< User call has resulted in island exit.*/ +#define QURT_ENOISLANDENTRY 45 /**< Island mode had not yet been entered.*/ +#define QURT_EISLANDINVALIDINT 46 /**< Exited Island mode due to an invalid island interrupt.*/ +/** @cond rest_reg_dist */ +#define QURT_ETIMEDOUT 47 /**< Operation timed-out. */ +#define QURT_EALREADY 48 /**< Operation already in progress. */ +/** @endcond */ + +#define QURT_ERETRY 49 /*< Retry the operation. */ +#define QURT_EDISABLED 50 /*< Resource disabled. */ +#define QURT_EDUPLICATE 51 /*< Duplicate resource. */ +#define QURT_EBADR 53 /*< Invalid request descriptor. */ +#define QURT_ETLB 54 /*< Exceeded maximum allowed TLBs. */ +#define QURT_ENOTSUPPORTED 55 /*< Operation not supported. */ +/** @cond rest_reg_dist */ +#define QURT_ENORESOURCE 56 /**< No resource. */ +/** @endcond */ + +#define QURT_EDTINIT 57 /**< Problem with device tree intialization. */ +#define QURT_EBUFLOCK 58 /*< Buffer lock failed because it was already locked many times. */ +#define QURT_ELOCKED 59 /**< Current operation failed as the buffer is locked. */ +#define QURT_EMSGSIZE 90 /*< Message queue msg_len is greater than mq_msgsize attribute of the message queue. */ + + +#define QURT_ENOTCONFIGURED 91 /*< Interrupt is NOT configured. */ + +#define QURT_EBANDWIDTHLIMIT 92 /*< Message queue send exceed the bandwidth limit. */ + +#define QURT_ECFIVIOLATION 93 /*< CFI violation detected. */ + +#define QURT_EDESTROY 94 /**< A destroy request was made to waiting threads.*/ + +#define QURT_EHMXNOTAVAIL 95 /**< HMX is not available to target thread.*/ +#define QURT_EHMXNOTDETACHABLE 96 /**< HMX is not detachable from target thread.*/ + +#define QURT_EFATAL -1 /**< Fatal error. */ + +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ERROR_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_event.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_event.h new file mode 100755 index 0000000000000..987f0fe79f227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_event.h @@ -0,0 +1,452 @@ +#ifndef QURT_EVENT_H +#define QURT_EVENT_H +/** + @file qurt_event.h + @brief Prototypes of kernel event API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "qurt_consts.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System environment object type. + */ +/**@addtogroup sys_env_types +@{ */ +/** QuRT swap pool information type. */ +typedef struct qurt_sysenv_swap_pools { + /** @cond */ + unsigned int spoolsize; /* Swap pool size.*/ + unsigned int spooladdr; /* Swap pool start address.*/ + /** @endcond */ +}qurt_sysenv_swap_pools_t; + +/**QuRT application heap information type. */ +typedef struct qurt_sysenv_app_heap { + /** @cond */ + unsigned int heap_base; /* Heap base address.*/ + unsigned int heap_limit; /* Heap end address.*/ + /** @endcond */ +} qurt_sysenv_app_heap_t ; + +/** QuRT architecture version information type. */ +typedef struct qurt_sysenv_arch_version { + /** @cond */ + unsigned int arch_version; /*Architecture version.*/ + /** @endcond */ +}qurt_arch_version_t; + +/** QuRT maximum hardware threads information type. */ +typedef struct qurt_sysenv_max_hthreads { + /** @cond */ + unsigned int max_hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_max_hthreads_t; + +/** QuRT active hardware threads information type. */ +typedef struct qurt_sysenv_hthreads { + /** @cond */ + unsigned int hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_hthreads_t; + +/** QuRT maximum pi priority information type. */ +typedef struct qurt_sysenv_max_pi_prio { + /** @cond */ + unsigned int max_pi_prio; /*Maximum pi priority.*/ + /** @endcond */ +}qurt_sysenv_max_pi_prio_t; + +/** QuRT process name information type. */ +typedef struct qurt_sysenv_procname { + /** @cond */ + union { + unsigned int asid; /*Address space ID.*/ + unsigned int pid; /*Process ID.*/ + }; + char name[QURT_MAX_NAME_LEN]; /* Process name.*/ + /** @endcond */ +}qurt_sysenv_procname_t; + +/** QuRT stack profile count information type. */ +typedef struct qurt_sysenv_stack_profile_count { + /** @cond */ + unsigned int count; /*Stack profile count for usage.*/ + unsigned int count_watermark; /*Stack profile count for watermark.*/ + /** @endcond */ +}qurt_sysenv_stack_profile_count_t; + +/** + QuRT system error event type. + */ +typedef struct _qurt_sysevent_error_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + } qurt_sysevent_error_t ; + +typedef struct _qurt_sysevent_error_1_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + unsigned int fkey; /**< Framekey.*/ + unsigned int reserved1; /**< Reserved.*/ + unsigned int reserved2; /**< Reserved.*/ + unsigned int reserved3; /**< Reserved.*/ + } qurt_sysevent_error_1_t ; + +/** QuRT page fault error event information type. */ +typedef struct qurt_sysevent_pagefault { + qurt_thread_t thread_id; /**< Thread ID of the page fault thread. */ + unsigned int fault_addr; /**< Accessed address that caused the page fault. */ + unsigned int ssr_cause; /**< SSR cause code for the page fault. */ +} qurt_sysevent_pagefault_t ; +/** @} */ /* @endaddtogroup sys_env_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/*======================================================================*/ +/** + Gets the environment swap pool 0 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool0 (qurt_sysenv_swap_pools_t *pools ); + +/* + Gets the environment swap pool 1 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool1(qurt_sysenv_swap_pools_t *pools ); + +/**@ingroup func_qurt_sysenv_get_app_heap + Gets information on the program heap from the kernel. + + @datatypes + #qurt_sysenv_app_heap_t + + @param[out] aheap Pointer to information on the program heap. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_app_heap(qurt_sysenv_app_heap_t *aheap ); + +/**@ingroup func_qurt_sysenv_get_arch_version + Gets the Hexagon processor architecture version from the kernel. + + @datatypes + #qurt_arch_version_t + + @param[out] vers Pointer to the Hexagon processor architecture version. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter + + @dependencies + None. +*/ +int qurt_sysenv_get_arch_version(qurt_arch_version_t *vers); + +/**@ingroup func_qurt_sysenv_get_max_hw_threads + Gets the maximum number of hardware threads supported in the Hexagon processor. + The API includes the disabled hardware threads to reflect the maximum + hardware thread count. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, only HW0 and HW2 are initialized by QuRT. + HW1 and HW3 are not used at all. Under such a scenario, + qurt_sysenv_get_max_hw_threads() still returns four. + + @datatypes + #qurt_sysenv_max_hthreads_t + + @param[out] mhwt Pointer to the maximum number of hardware threads supported in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_hw_threads(qurt_sysenv_max_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_hw_threads + Gets the number of hardware threads initialized by QuRT in Hexagon processor. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, QuRT only initializes HW0 and HW2. + HW1 and HW3 are not used. In this scenario, qurt_sysenv_get_hw_threads() returns 2. + + @datatypes + #qurt_sysenv_hthreads_t + + @param[out] mhwt Pointer to the number of hardware threads active in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_hw_threads(qurt_sysenv_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_max_pi_prio + Gets the maximum priority inheritance mutex priority from the kernel. + + @datatypes + #qurt_sysenv_max_pi_prio_t + + @param[out] mpip Pointer to the maximum priority inheritance mutex priority. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_pi_prio(qurt_sysenv_max_pi_prio_t *mpip ); + +/**@ingroup func_qurt_sysenv_get_process_name2 + Gets information on the system environment process names based on the client_handle argument. + + @datatypes + #qurt_sysenv_procname_t + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name2(int client_handle, qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_process_name + Gets information on the system environment process names from the kernel. + + @datatypes + #qurt_sysenv_procname_t + + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name(qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_stack_profile_count + Gets information on the stack profile count from the kernel. + + @datatypes + #qurt_sysenv_stack_profile_count_t + + @param[out] count Pointer to information on the stack profile count. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_stack_profile_count(qurt_sysenv_stack_profile_count_t *count ); + +/**@ingroup func_qurt_exception_wait + Registers the program exception handler. + This function assigns the current thread as the QuRT program exception handler and suspends the + thread until a program exception occurs. + + When a program exception occurs, the thread is awakened with error information + assigned to the parameters of this operation. + + @note1hang If no program exception handler is registered, or if the registered handler + calls exit, QuRT raises a kernel exception. + If a thread runs in Supervisor mode, any errors are treated as kernel + exceptions. + + @param[out] ip Pointer to the instruction memory address where the exception occurred. + @param[out] sp Stack pointer. + @param[out] badva Pointer to the virtual data address where the exception occurred. + @param[out] cause Pointer to the QuRT error result code. + + @return + Registry status: \n + Thread identifier -- Handler successfully registered. \n + #QURT_EFATAL -- Registration failed. + + @dependencies + None. +*/ +unsigned int qurt_exception_wait (unsigned int *ip, unsigned int *sp, + unsigned int *badva, unsigned int *cause); + +unsigned int qurt_exception_wait_ext (qurt_sysevent_error_t * sys_err); + +/**@ingroup func_qurt_exception_wait3 + Registers the current thread as the QuRT program exception handler, and suspends the thread until a + program exception occurs. + When a program exception occurs, the thread is awakened with error information assigned to the specified + error event record. + If a program exception is raised when no handler is registered (or when a handler is registered, but it calls + exit), the exception is treated as fatal.\n + @note1hang If a thread runs in Monitor mode, all exceptions are treated as kernel exceptions.\n + @note1cont This function differs from qurt_exception_wait() by returning the error information in a data + structure rather than as individual variables. It also returns additional information (for example, SSR, FP, and LR). + + @param[out] sys_err Pointer to the qurt_sysevent_error_1_t type structure. + @param[in] sys_err_size Size of the qurt_sysevent_error_1_t structure. + + @return + Registry status: \n + - #QURT_EFATAL -- Failure. \n + - Thread ID -- Success. + + @dependencies + None. +*/ + +unsigned int qurt_exception_wait3(void * sys_err, unsigned int sys_err_size); + +/**@ingroup func_qurt_exception_raise_nonfatal + Raises a nonfatal program exception in the QuRT program system. + + For more information on program exceptions, see Section @xref{dox:exception_handling}. + + This operation never returns -- the program exception handler is assumed to perform all + exception handling before terminating or reloading the QuRT program system. + + @note1hang The C library function abort() calls this operation to indicate software + errors. + + @param[in] error QuRT error result code (Section @xref{dox:error_results}). + + @return + Integer -- Unused. + + @dependencies + None. +*/ +int qurt_exception_raise_nonfatal (int error) __attribute__((noreturn)); + + +/**@ingroup func_qurt_exception_raise_fatal + Raises a fatal program exception in the QuRT system. + + Fatal program exceptions terminate the execution of the QuRT system without invoking + the program exception handler. + + For more information on fatal program exceptions, see Section @xref{dox:exception_handling}. + + This operation always returns, so the calling program can perform the necessary shutdown + operations (data logging, on so on). + + @note1hang Context switches do not work after this operation has been called. + + @return + None. + + @dependencies + None. +*/ +void qurt_exception_raise_fatal (void); + +unsigned int qurt_enable_floating_point_exception(unsigned int mask); + +/**@ingroup func_qurt_exception_enable_fp_exceptions + Enables the specified floating point exceptions as QuRT program exceptions. + + The exceptions are enabled by setting the corresponding bits in the Hexagon + control user status register (USR). + + The mask argument specifies a mask value identifying the individual floating + point exceptions to set. The exceptions are represented as defined symbols + that map into bits 0 through 31 of the 32-bit flag value. + Multiple floating point exceptions are specified by OR'ing together the individual + exception symbols.\n + @note1hang This function must be called before performing any floating point operations. + + @param[in] mask Floating point exception types. Values: \n + - #QURT_FP_EXCEPTION_ALL \n + - #QURT_FP_EXCEPTION_INEXACT \n + - #QURT_FP_EXCEPTION_UNDERFLOW \n + - #QURT_FP_EXCEPTION_OVERFLOW \n + - #QURT_FP_EXCEPTION_DIVIDE0 \n + - #QURT_FP_EXCEPTION_INVALID @tablebulletend + + @return + Updated contents of the USR. + + @dependencies + None. +*/ + +static inline unsigned int qurt_exception_enable_fp_exceptions(unsigned int mask) +{ + return qurt_enable_floating_point_exception(mask); +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EVENT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_except.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_except.h new file mode 100755 index 0000000000000..e1684c80e3d50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_except.h @@ -0,0 +1,185 @@ +#ifndef QURT_EXCEPT_H +#define QURT_EXCEPT_H + +/** + @file qurt_except.h + @brief Defines Cause and Cause2 codes for error-handling. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. + + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + QuRT supports error handling to handle CPU detected exceptions and software errors. + QuRT treats all errors as either fatal errors or nonfatal errors. + + @section sec1 Fatal errors + All supervisor mode exceptions are treated as fatal errors. + If a registered exception handler calls qurt_exit(), it is treated as a fatal error. + Fatal errors result in saving the context of primary hardware thread to QURT_error_info and the rest of the thread contexts to the corresponding TCBs. + All hardware threads are eventually stopped and the cache is flushed. + NMI exception is treated little differently from other fatal errors. QuRT saves the contexts of all the hardware threads into QURT_error_info.\n + + @subsection subsection1 Debugging fatal errors + - QURT_error_info.status.status -- Indicates that an error occured. + - QURT_error_info.status.cause -- Cause code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.cause2 -- Cause2 code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.fatal -- Indicates whether a fatal error occurred. A user error can result in a fatal error if the exceptional handler is not registered. + - QURT_error_info.status.hw_tnum -- Indicates the index of QURT_error_info.locregs[], where the context is saved when the error is fatal error. + - QURT_error_info.global_regs -- Contains the values of the global registers of Q6 + - QURT_error_info.local_regs[QURT_error_info.status.hw_tnum] -- Provides the CPU context when the error is a supervisor error. + + + + @subsection subsection2 Debugging nonfatal errors + - QURT_error_info.user_errors -- All user errors are logged here. + - QURT_error_info.user_errors.counter -- Index to last logged error. + - QURT_error_info.user_errors.entry[0...counter] -- Structure for logged error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb -- TCB for the user error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb.error -- Information about the error; Cause, Cause2, Badva and hardware thread ID. + - QURT_error_info.user_errors.entry[0...counter].error_code -- ((cause2 << 8) 'Logical Or' (cause) ); Cause and Cause 2 details are listed below. + - QURT_error_info.user_errors.entry[0...counter].hw_thread -- Hardware thread ID for error. + - QURT_error_info.user_errors.entry[0...counter].pcycle -- Pcycle for error. + +@note + Important usage note: + Cause and Cause2 are error codes to distinguish multiple errors. + SSR and BADAVA are inconclusive without the vector number. + All cause and cause2 can range from 1 to 255 and every cause can have 1 to 255 error code. + Hence the system can have up to 255 * 255 unique error codes. + The cominations is representated as ((cause2 << 8) 'Logical OR' (cause) ) + Some Cause2 codes are statically defined, whereas some are obtaned from SSR[7:0] cause codes. It depends on cause codes. + SSR cause codes are defined in Hexagon reference manual. + All possible combinations are listed below. +*/ +/** @addtogroup chapter_error +@{ */ +/* cause - error type - 8-bits*/ +#define QURT_EXCEPT_PRECISE 0x01U /**< Precise exception occurred. For this cause code, Cause2 is SSR[7:0].*/ +#define QURT_EXCEPT_NMI 0x02U /**< NMI occurred; Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS 0x03U /**< TLBMISS RW occurred; for this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_RSVD_VECTOR 0x04U /**< Interrupt raised on a reserved vector, which must never occur. Cause2 is not defined. */ +#define QURT_EXCEPT_ASSERT 0x05U /**< Kernel assert. Cause2 QURT_ABORT_* are listed below. */ +#define QURT_EXCEPT_BADTRAP 0x06U /**< trap0(num) called with unsupported num. Cause2 is 0. */ +#define QURT_EXCEPT_UNDEF_TRAP1 0x07U /**< Trap1 is not supported. Using Trap1 causes this error. Cause2 is not defined. */ +#define QURT_EXCEPT_EXIT 0x08U /**< Application called qurt_exit() or qurt_exception_raise_nonfatal(). Can be called from C library. Cause2 is "[Argument passed to qurt_exception_raise_nonfatal() & 0xFF]". */ +#define QURT_EXCEPT_TLBMISS_X 0x0AU /**< TLBMISS X (execution) occurred. Cause2 is not defined. */ +#define QURT_EXCEPT_STOPPED 0x0BU /**< Running thread stopped due to fatal error on other hardware thread. Cause2 is not defined. */ +#define QURT_EXCEPT_FATAL_EXIT 0x0CU /**< Application called qurt_fatal_exit(). Cause2 is not defined. */ +#define QURT_EXCEPT_INVALID_INT 0x0DU /**< Kernel received an invalid L1 interrupt. Cause2 is not defined. */ +#define QURT_EXCEPT_FLOATING_POINT 0x0EU /**< Kernel received an floating point error. Cause2 is not defined. */ +#define QURT_EXCEPT_DBG_SINGLE_STEP 0x0FU /**< Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS_RW_ISLAND 0x10U /**< Read write miss in Island mode. Cause2 QURT_TLB_MISS_RW_MEM* are listed below. */ +#define QURT_EXCEPT_TLBMISS_X_ISLAND 0x11U /**< Execute miss in Island mode. For this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_SYNTHETIC_FAULT 0x12U /**< Synthetic fault with user request that kernel detected. Cause2 QURT_SYNTH_* are listed below. */ +#define QURT_EXCEPT_INVALID_ISLAND_TRAP 0x13U /**< Invalid trap in Island mode. Cause2 is trap number. */ +#define QURT_EXCEPT_UNDEF_TRAP0 0x14U /**< trap0(num) was called with unsupported num. Cause2 is trap number. */ +#define QURT_EXCEPT_PRECISE_DMA_ERROR 0x28U /**< Precise DMA error. Cause2 is DM4[15:8]. Badva is DM5 register. */ + +#define QURT_ECODE_UPPER_LIBC (0U << 16) /**< Upper 16 bits is 0 for libc. */ +#define QURT_ECODE_UPPER_QURT (0U << 16) /**< Upper 16 bits is 0 for QuRT. */ +#define QURT_ECODE_UPPER_ERR_SERVICES (2U << 16) /**< Upper 16 bits is 2 for error service. */ +/** @cond */ +#define QURT_ECODE_ISLAND_INVALID_QDI 3U /**< Passing invalid QDI method in island. */ +/** @endcond */ + +/* Cause2 for QURT_EXCEPT_SYNTHETIC_FAULT cause- 8bits */ +#define QURT_SYNTH_ERR 0x01U /**< */ +#define QURT_SYNTH_INVALID_OP 0x02U /**< */ +#define QURT_SYNTH_DATA_ALIGNMENT_FAULT 0x03U /**< */ +#define QURT_SYNTH_FUTEX_INUSE 0x04U /**< */ +#define QURT_SYNTH_FUTEX_BOGUS 0x05U /**< */ +#define QURT_SYNTH_FUTEX_ISLAND 0x06U /**< */ +#define QURT_SYNTH_FUTEX_DESTROYED 0x07U /**< */ +#define QURT_SYNTH_PRIVILEGE_ERR 0x08U /**< */ + +/* Cause2 - Abort cause reason - 8 bits */ +/* ERR_ASSERT cause */ +#define QURT_ABORT_FUTEX_WAKE_MULTIPLE 0x01U /**< Abort cause - futex wake multiple. */ +#define QURT_ABORT_WAIT_WAKEUP_SINGLE_MODE 0x02U /**< Abort cause - thread waiting to wake up in Single Threaded mode. */ +#define QURT_ABORT_TCXO_SHUTDOWN_NOEXIT 0x03U /**< Abort cause - call TCXO shutdown without exit. */ +#define QURT_ABORT_FUTEX_ALLOC_QUEUE_FAIL 0x04U /**< Abort cause - futex allocation queue failure - QURTK_futexhash_lifo empty. */ +#define QURT_ABORT_INVALID_CALL_QURTK_WARM_INIT 0x05U /**< Abort cause - invalid call QURTK_warm_init() in NONE CONFIG_POWER_MGMT mode. */ +#define QURT_ABORT_THREAD_SCHEDULE_SANITY 0x06U /**< Abort cause - sanity schedule thread is not supposed to run on the current hardware thread. */ +#define QURT_ABORT_REMAP 0x07U /**< Remap in the page table; the correct behavior must remove mapping if necessary. */ +#define QURT_ABORT_NOMAP 0x08U /**< No mapping in page table when removing a user mapping. */ +#define QURT_ABORT_OUT_OF_SPACES 0x09U +#define QURT_ABORT_INVALID_MEM_MAPPING_TYPE 0x0AU /**< Invalid memory mapping type when creating qmemory. */ +#define QURT_ABORT_NOPOOL 0x0BU /**< No pool available to attach. */ +#define QURT_ABORT_LIFO_REMOVE_NON_EXIST_ITEM 0x0CU /**< Cannot allocate more futex waiting queue. */ +#define QURT_ABORT_ARG_ERROR 0x0DU +#define QURT_ABORT_ASSERT 0x0EU /**< Assert abort. */ +#define QURT_ABORT_FATAL 0x0FU /**< Fatal error; must never occur. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_QUEUE 0x10U /**< Abort cause - invalid queue ID in futex resume. */ +#define QURT_ABORT_FUTEX_WAIT_INVALID_QUEUE 0x11U /**< Abort cause - invalid queue ID in futex wait. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_FUTEX 0x12U /**< Abort cause - invalid futex object in hashtable. */ +#define QURT_ABORT_NO_ERHNDLR 0x13U /**< No registered error handler. */ +#define QURT_ABORT_ERR_REAPER 0x14U /**< Exception in the reaper thread. */ +#define QURT_ABORT_FREEZE_UNKNOWN_CAUSE 0x15U /**< Abort in thread freeze operation. */ +#define QURT_ABORT_FUTEX_WAIT_WRITE_FAILURE 0x16U /**< During futex wait processing, could not perform a necessary write operation to userland data; most likely due to a DLPager eviction. */ +#define QURT_ABORT_ERR_ISLAND_EXP_HANDLER 0x17U /**< Exception in Island exception handler task. */ +#define QURT_ABORT_L2_TAG_DATA_CHECK_FAIL 0x18U /**< Detected error in L2 tag/data during warm boot. The L2 tag/data check is done when CONFIG_DEBUG_L2_POWER_COLLAPSE is enabled. */ +#define QURT_ABORT_ERR_SECURE_PROCESS 0x19U /**< Abort error in secure process. */ +#define QURT_ABORT_ERR_EXP_HANDLER 0x20U /**< No exception handler, or the handler caused an exception. */ +#define QURT_ABORT_ERR_NO_PCB 0x21U /**< PCB of the thread context failed initialization, PCB was NULL. */ +#define QURT_ABORT_NO_PHYS_ADDR 0x22U /**< Unable to find the physical address for the virtual address. */ +#define QURT_ABORT_OUT_OF_FASTINT_CONTEXTS 0x23U /**< Fast interrupt contexts exhausted. */ +#define QURT_ABORT_CLADE_ERR 0x24U /**< Fatal error seen with CLADE interrupt. */ +#define QURT_ABORT_ETM_ERR 0x25U /**< Fatal error seen with ETM interrupt. */ +#define QURT_ABORT_ECC_DED_ASSERT 0x26U /**< ECC two-bit DED error. */ +#define QURT_ABORT_VTLB_ERR 0x27U /**< Fatal error in the VTLB layer. */ +#define QURT_ABORT_TLB_ENCODE_DECODE_FAILURE 0x28U /**< Failure during the TLB encode or decode operation. */ +#define QURT_ABORT_VTLB_WALKOBJS_BOUND_FAILURE 0x29U /**< Failure to lookup entry in the page table. */ +#define QURT_ABORT_PHY_MEMORY_OWNERSHIP_FAILURE 0x30U /**< Failure to claim phy memory ownership. */ +#define QURT_ABORT_JTLB_SIZE_CHECK_FAIL 0x31U /**< JTLB size configured is more than actual size in hardware */ +#define QURT_ABORT_AUTOSTACK_ASSERT 0x32U /**< Error while handling stack flimit exception. */ + +/* Cause2 - TLB-miss_X - 8bits */ +#define QURT_TLB_MISS_X_FETCH_PC_PAGE 0x60U /**< */ +#define QURT_TLB_MISS_X_2ND_PAGE 0x61U /**< */ +#define QURT_TLB_MISS_X_ICINVA 0x62U /**< */ + +/* Cause2 - TLB-miss_RW - 8bits */ +#define QURT_TLB_MISS_RW_MEM_READ 0x70U /**< */ +#define QURT_TLB_MISS_RW_MEM_WRITE 0x71U /**< */ + +/** @cond rest_reg_dist */ +/* Cause2 - Floating point exception - 8 bits */ +#define QURT_FLOATING_POINT_EXEC_ERR 0xBFU /**< Execute floating-point. */ +/** @endcond */ + +/** Cause2 - autostackv2 - 8 bits */ +#define QURT_AUTOSTACKV2_CANARY_NOT_MATCH 0xC1U +#define QURT_AUTOSTACKV2_POOL_IDX_OFF_RANGE 0xC2U + +/** Cause2 - CFI violation - 8 bits */ +#define QURT_CFI_VIOLATION 0xC3U + +/** @cond rest_reg_dist*/ +/* Enable floating point exceptions */ +#define QURT_FP_EXCEPTION_ALL 0x1FU << 25 /**< */ +#define QURT_FP_EXCEPTION_INEXACT 0x1U << 29 /**< */ +#define QURT_FP_EXCEPTION_UNDERFLOW 0x1U << 28 /**< */ +#define QURT_FP_EXCEPTION_OVERFLOW 0x1U << 27 /**< */ +#define QURT_FP_EXCEPTION_DIVIDE0 0x1U << 26 /**< */ +#define QURT_FP_EXCEPTION_INVALID 0x1U << 25 /**< */ + +/** @endcond */ +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EXCEPT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fastint.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fastint.h new file mode 100755 index 0000000000000..ea65dc0917fc0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fastint.h @@ -0,0 +1,71 @@ +#ifndef QURT_FASTINT_H +#define QURT_FASTINT_H + +/** + @file qurt_fastint.h + @brief QuRT fast interrupt functions + + Copyright (c) 2013-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_fastint_register + Register fast interrupt callback function + + Fast interrupt callback should be designed to perform the minimal necessary + actions for the interrupt, and/or perform some operations, such as signaling + another regular software thread to start any additional processing. + The callback should be a fast and short function. When a fast interrupt callback + is running, the corresponding interrupt cannot be re-enabled until the callback + returns. + + The fast interrupt callback must not use any system blocking calls, such as + mutex lock or signal wait. Otherwise, it results in errors. + + The fast interrupt callback function has a single integer argument and the + function ends with no return. The argument value passed in is the interrupt + number, and therefore a single callback function can handle + multiple fast interrupts. + + @param[in] intno Interrupt number to register. + @param[in] fn Interrupt callback function. + + @return + #QURT_EOK -- Fast interrupt registration is successful. \n + #QURT_EINVALID -- Interrupt is already registered. \n + #QURT_EINT -- Invalid interrupt number. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_register(int intno, void (*fn)(int)); + + +/*======================================================================*/ +/**@ingroup func_qurt_fastint_deregister + Deregisters the fast interrupt callback function. + + @param[in] intno Level-one interrupt number to deregister. Valid range is 1 and 10 through 31 + (simulator only). + + @return + #QURT_EOK -- Interrupt deregistration is successful. \n + #QURT_EINT -- Invalid interrupt number (not registered). \n + #QURT_EINVALID -- Invalid interrupt number (already deregistered). + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_deregister(int intno); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FASTINT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fs_hub.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fs_hub.h new file mode 100755 index 0000000000000..aaa050a6c838b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_fs_hub.h @@ -0,0 +1,58 @@ +#ifndef QURT_FS_HUB_H +#define QURT_FS_HUB_H + +/** + @file qurt_fs_hub.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver that provides file-system functionality. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + This structure tracks a file-designator for a FS-hub QDI driver. + File system's QDI interface should use this object to encapsulate + true file-descriptor and return back a QDI handle. This QDI handle + will be used as file-descriptor by File-systm-hub. + */ + +typedef struct qurt_qdi_fs_obj +{ + qurt_qdi_obj_t qdi_obj; + int client_handle; + int fd; +}qurt_qdi_fs_obj_t; + + +/**@ingroup fs_hub_support_functions + This function allows a file-system to register it's QDI interface with file-system-hub. + Once registered, all file open operations for any filenames containing the mountpoint will + be forwarded to the QDI inteface. + + Mountpoint string must be encased in two forward slashes e.g. "/mountpoint/" + + @param mtpoint mount point for the file-system being registered. + @param opener opener structure for the QDI driver interface + + @return + QURT_EOK -- Successfully registered QDI driver with file-system-hub. + Negative error code -- Failed to register with file-system-hub + */ +int qurt_fs_hub_mtpoint_register(const char *mtpoint, qurt_qdi_obj_t *opener); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_futex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_futex.h new file mode 100755 index 0000000000000..1fdcc79a43f01 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_futex.h @@ -0,0 +1,82 @@ +#ifndef QURT_FUTEX_H +#define QURT_FUTEX_H +/** + @file qurt_futex.h + + @brief Prototypes of QuRT futex API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Functions +======================================================================*/ + + +/**@ingroup func_qurt_futex_wait + Moves the caller thread into waiting state when a memory object address + contains a value that is the same as a specified value. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait(void *lock, int val); + + +/**@ingroup func_qurt_futex_wait_cancellable + If a memory object address contains a value that is same as a specified + value, move the caller thread into waiting state. + The kernal can cancel the waiting state when there is a special need. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait_cancellable(void *lock, int val); + + +/**@ingroup func_qurt_futex_wake + Wakes up a specified number of threads that have been waiting + for the object change with qurt_futex_wait(). + + @param[in] lock Pointer to the object memory. + @param[in] n_to_wake Maximum number of threads to wake up. + + @return + number of threads to be woken up by this function + + @dependencies + None. + */ +int qurt_futex_wake(void *lock, int n_to_wake); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hmx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hmx.h new file mode 100755 index 0000000000000..e4037dbeae514 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hmx.h @@ -0,0 +1,226 @@ +#ifndef QURT_HMX_H +#define QURT_HMX_H +/** + @file qurt_hmx.h + @brief Prototypes of Qurt HMX API. + +Copyright (c) 2019-2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + + +/** @addtogroup hmx_types +@{ */ +/* HMX locking type */ +#define QURT_HMX_NON_SHARED_LOCK 0U /**< HMX locking type.*/ +#define QURT_HMX_SHARED_LOCK 1U /**< HMX locking type.*/ + +/* HMX unlocking type */ +#define QURT_HMX_NON_SHARED_UNLOCK 0U /**< HMX unlocking type.*/ +#define QURT_HMX_SHARED_UNLOCK 1U /**< HMX unlocking type.*/ + +/* HMX hardware context */ +#define QURT_HMX_UNIT_0 0U /**< HMX hardware context #0 */ +#define QURT_HMX_UNIT_1 1U /**< HMX hardware context #1 */ + /** @} */ /* end_addtogroup hmx_types */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_hmx_lock2 + Locks a HMX unit with the specified locking type. + + #QURT_HMX_NON_SHARED_LOCK: + - If a HMX unit is available, lock the unit and return success of #QURT_EOK. + - If the HMX unit is already locked by another thread, the caller thread is suspended + until the HMX is available and gets locked by this function. + - If there is no HMX hardware supported, returns #QURT_EVAL; + + #QURT_HMX_SHARED_LOCK: + - If a HMX unit is available, enables HMX access for the caller thread, and returns + success of #QURT_EOK. + - If the HMX is enabled on the caller thread, return #QURT_EFAILED. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_SHARED_LOCK, enable HMX access for the caller + thread, and return success of #QURT_EOK. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_NON_SHARED_LOCK, return #QURT_EFAILED. + - If the HMX is locked by a thread from another user process different from the + user process of the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX lock successful.\n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_lock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_unlock2 + Unlocks a HMX unit with the unlocking type. + + #QURT_HMX_NON_SHARED_UNLOCK: + - If there is a HMX unit locked by the caller thread, unlock the HMX unit and clear the + HMX accumulators (assuming a fixed point type). + - If there is no HMX unit locked by the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + #QURT_HMX_SHARED_UNLOCK: + - If the caller thread has locked HMX with type #QURT_HMX_SHARED_LOCK, disable the + HMX access on the caller thread, and return success of #QURT_EOK. + Note: If the caller thread is the last thread that unlocks for #QURT_HMX_SHARED_LOCK + in its user process, the unlock function clears the HMX accumulators. + - If the caller thread has locked HMX with type #QURT_HMX_NON_SHARED_LOCK, return + failure of #QURT_EFAILED. + - If the caller thread has not locked HMX, return failure of #QURT_EFAILED. + - If there is no HMX hardware supported, returns #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX is unlocked successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_unlock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_lock + Locks a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away. + If there is no HMX unit available, the caller is blocked until a HMX is available + and is locked by the function. + + @return + #QURT_EOK -- HMX lock successful. \n + #QURT_EFAILED -- Failure due to wrong locking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_lock(void); + + +/**@ingroup func_qurt_hmx_unlock + Unlocks a HMX unit. + If a HMX unit is locked by the caller thread, unlock the HMX unit and clear its + accumulators(assuming fixed point type). + If there is no HMX unit locked by the caller thread, return failure. + + @return + #QURT_EOK -- HMX unlock successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_unlock(void); + + +/**@ingroup func_qurt_hmx_try_lock + Tries to lock a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away; + if there is no HMX unit available, the function returns failure without blocking the caller. + + @return + #QURT_EOK -- HMX lock successful \n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_try_lock(void); + + +/**@ingroup func_qurt_hmx_assign + Assign a HMX unit to a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + If the requested hmx_unit is already assigned to another thread with QURT_HMX_NON_SHARED_LOCK, + kernel will detach it from the thread, and re-assign it to the target thread. + If the target thread has HVX enabled, it cannot have HMX enabled. + + Locking type + #QURT_HMX_NON_SHARED_LOCK: + - If the HMX unit is available, lock the HMX unit and return success of #QURT_EOK. + - If the HMX unit is already enabled on the target thread, return #QURT_EOK. + - If the HMX unit is already locked by another thread, detach the HMX from the thread. + Re-assign the HMX unit to the target thread, and return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] type Locking type + #QURT_HMX_NON_SHARED_LOCK -- non-shared lock + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is assigned successfully. This includes the case that \n + the target thread already has HMX assigned. \n + #QURT_EFAILED -- Failure due to wrong assigning conditions. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_assign ( unsigned int thread_id, unsigned int type, unsigned int hmx_unit ); + + +/**@ingroup func_qurt_hmx_release + Release a HMX unit from a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + + Qurt detaches the specified HMX unit from the target thread, and return success of + #QURT_EOK. If the HMX unit is already released from the target thread, return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is released successfully. This includes the case that \n + the target thread already has the HMX released. \n + #QURT_EFAILED -- Failure due to wrong assigning condition. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_release ( unsigned int thread_id, unsigned int hmx_unit ); + + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HMX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hvx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hvx.h new file mode 100755 index 0000000000000..13c213d49ac84 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_hvx.h @@ -0,0 +1,421 @@ +#ifndef QURT_HVX_H +#define QURT_HVX_H +/** + @file qurt_hvx.h + @brief Prototypes of QuRT HVX API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @cond */ + +typedef enum { + QURT_HVX_MODE_64B = 0, /**< HVX mode of 64 bytes */ + QURT_HVX_MODE_128B = 1 /**< HVX mode of 128 bytes */ +} qurt_hvx_mode_t; +/** @endcond */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @cond internal_only*/ +/** @addtogroup hvx_macros +@{ */ +#define QURT_HVX_HW_UNITS_2X128B_4X64B 0x00000204 /**< Bits 15 through 8 are for the number of 128B units. */ + /**< Bits 7 through 0 are for the number of 64B units. */ +#define QURT_HVX_HW_UNITS_4X128B_0X64B 0x00000400 +#define QURT_HVX_HW_UNITS_6X128B_0X64B 0x00000600 + +/* HVX locking status */ + +#define QURT_HVX_UNLOCKED (0) /* Has not locked HVX unit */ +#define QURT_HVX_LOCKED (1) /* Has locked HVX unit */ +#define QURT_HVX_ERROR (-1) /* Error, no HVX support */ + +/* Input value for HVX reservation */ + +#define QURT_HVX_RESERVE_ALL (4) /* All the HVX units in terms of 64B_MODE are requested to be reserved */ +#define QURT_HVX_RESERVE_ALL_AVAILABLE (0xff) /* All remaining unlocked HVX units in terms of 64B_MODE are requested to be reserved */ + +/* Return values for HVX reservation */ + +#define QURT_HVX_RESERVE_NOT_SUPPORTED (-1) /* There is no HVX hardware, or less units in the hardware than requested */ +#define QURT_HVX_RESERVE_NOT_SUCCESSFUL (-2) /* Some HVX units are already locked/reserved by other PD, thus not enough units left for the reservation. */ +#define QURT_HVX_RESERVE_ALREADY_MADE (-3) /* There is already a HVX reservation made. */ +#define QURT_HVX_RESERVE_CANCEL_ERR (-4) /* The action of cancling the reservation fails because this protection domain has no reservation made before. */ + +// HVX set requests + +#define QURT_HVX_64B 0 /**< */ +#define QURT_HVX_128B 1 /**< */ +#define QURT_HVX_NO_USE 2 /**< */ +#define QURT_HVX_RELEASE_CONTEXT 3 /**< */ +#define QURT_HVX_IMMEDIATE_USE 4 /**< */ + +// HVX set masks + +#define QURT_HVX_64B_PREFERRED (1<<(QURT_HVX_64B + 8))/**< */ +#define QURT_HVX_128B_PREFERRED (1<<(QURT_HVX_128B + 8))/**< */ +#define QURT_HVX_64B_ACCEPTABLE (1<<(QURT_HVX_64B + 12))/**< */ +#define QURT_HVX_128B_ACCEPTABLE (1<<(QURT_HVX_128B + 12))/**< */ + +// HVX set return "result" + +#define QURT_EOK 0 /**< */ +#define QURT_HVX_SET_ERROR 0xFF /**< */ + +// hvx_mode_assigned for QURT_HVX_IMMEDIATE_USE +#define QURT_HVX_64B_ASSIGNED (1<<(QURT_HVX_64B + 8)) /**< */ +#define QURT_HVX_128B_ASSIGNED (1<<(QURT_HVX_128B + 8)) /**< */ + +// Sizes of HVX dump buffer + +#define QURT_HVX_V65_64B_VSIZE 2084U /**< 64 x 32 + 8 x 4 + 4 (version). */ +#define QURT_HVX_V65_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V66_128B_VSIZE 4420U /**< 128 x (32 +2) + 16 x 4 + 4 (version). */ +#define QURT_HVX_V68_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V79_128B_VSIZE 4740U /**< 128 x (32+4+1) + 4 (version). */ +#define QURT_HVX_VREG_BUF_SIZE QURT_HVX_V79_128B_VSIZE /**< */ + +// HVX dump versions + +#define QURT_HVX_DUMP_V65_64B 1U /**< */ +#define QURT_HVX_DUMP_V65_128B 2U /**< */ +#define QURT_HVX_DUMP_V66_128B 3U /**< */ +#define QURT_HVX_DUMP_V68_128B 4U /**< */ +#define QURT_HVX_DUMP_V79_128B 5U /**< */ +/** @} */ /* end_addtogroup hvx_macros */ +/** @endcond */ +/** @cond */ +// Qurt data struct for hvx_set input +typedef struct qurt_hvx_set_struct_ { + unsigned char set_req; // LSB + struct { + unsigned char preferred_mask:4; + unsigned char acceptable_mask:4; + }; + unsigned short resvd; // MSB +} qurt_hvx_set_struct_t; // 4 bytes + + +// Qurt data struct for hvx_set return +typedef struct qurt_hvx_set_return_str_ { + unsigned char result; // LSB + unsigned char hvx_mode_assigned; + unsigned short resvd; // MSB +} qurt_hvx_set_return_struct_t; // 4 bytes +/** @endcond */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_hvx_lock + Locks one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns right away. + If the current HVX mode is different from the requested mode, the current + thread is blocked. When all HVX units become idle, QuRT changes + the mode, locks the HVX unit, and returns. + + Starting from Q6v65 with HVX context switch support, qurt_hvx_lock() is + mapped as qurt_hvx_set(64_BYTE or 128_BYTE). + + @datatypes + #qurt_mode_t + + @param[in] lock_mode #QURT_HVX_MODE_64B or #QURT_HVX_MODE_128B. + + @return + #QURT_EOK -- Success \n + Other value -- Failure + + @dependencies + None. + + */ +int qurt_hvx_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_unlock + Unlocks the HVX unit held by this software thread. + + @note1hang Starting from Q6v65 with HVX context switch support, qurt_hvx_unlock() + maps as qurt_hvx_set(QURT_HVX_RELEASE_CONTEXT). + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_unlock(void); + +/**@ingroup func_qurt_hvx_try_lock + Tries to lock one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns #QURT_EOK; Otherwise, + the function returns a failure, but does not block the current software + thread to wait for the HVX unit. + Starting from Q6v65 with HVX context switch support, qurt_hvx_try_lock() + maps to qurt_hvx_set(FOR_IMMEDIATE_USE| preferred_mask | acceptable_mask); + + @datatypes + #qurt_mode_t + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_try_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_get_mode + Gets the current HVX mode configured by QuRT. + + @note1hang Returns #QURT_HVX_MODE_128B or #QURT_HVX_MODE_64B, based on + the current HVX configuration. + + @param[out] + None. + + @return + #QURT_HVX_MODE_128B \n + #QURT_HVX_MODE_64B \n + -1 -- Not available. + + @dependencies + None. + */ +int qurt_hvx_get_mode(void); + + +/**@ingroup func_qurt_hvx_get_units + Gets the HVX hardware configuration that the chipset supports. + + @note1hang The function returns the HVX hardware configuration supported by the chipset. + + @return + Bitmask of the units: 1X64, 2X64, 4X64, 1X128, 2X128, and so on.\n + - QURT_HVX_HW_UNITS_2X126B_4X64B -- V60, V62, or V65 HVX \n + - QURT_HVX_HW_UNITS_4X128B_0X64B -- V66 CDSP or newer \n + - 0 -- not available + + @dependencies + None. + + */ +int qurt_hvx_get_units(void); + + +/**@ingroup func_qurt_hvx_reserve + Reserves HVX units in terms of 64-byte mode for the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + If one HVX unit is already locked by the application in the same PD, the unit is + added to the returned count as one reserved unit for the PD. + Starting from Q6v65 with HVX context switch support, qurt_hvx_reserve() + only does basic sanity checks on HVX units. + + @datatypes + None. + + @param[in] num_units Number of HVX units in terms of 64B_MODE to reserve for the PD. + QURT_HVX_RESERVE_ALL to reserve all the HVX units. + QURT_HVX_RESERVE_ALL_AVAILABLE to reserve the remaining unlocked units. + + @return + Number of units successfully reserved, including the units already locked in the same PD. \n + #QURT_HVX_RESERVE_NOT_SUPPORTED \n + #QURT_HVX_RESERVE_NOT_SUCCESSFUL \n + #QURT_HVX_RESERVE_ALREADY_MADE + + + @dependencies + None. + + */ +int qurt_hvx_reserve(int num_units); + + +/**@ingroup func_qurt_hvx_cancel_reserve + Cancels the HVX reservation in the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + + @return + 0 -- Success \n + #QURT_HVX_RESERVE_CANCEL_ERR -- Failure + + @dependencies + None. + + */ +int qurt_hvx_cancel_reserve(void); + + +/**@ingroup func_qurt_hvx_get_lock_val + Gets the HVX locking status value of the thread of the caller. + + @note1hang Returns the status of whether the thread of the caller already locks a HVX unit or not. + + @datatypes + None. + + @return + #QURT_HVX_UNLOCKED \n + #QURT_HVX_LOCKED \n + #QURT_HVX_ERROR + + @dependencies + None. + */ +int qurt_hvx_get_lock_val(void); + +/** @cond internal_only*/ +/**@ingroup func_qurt_hvx_set + Sets the HVX configuration for the software thread of the caller. + + @datatypes + None. + + @param[in] input_arg Composed of set_request | hvx_preferred_mode_mask + | hvx_acceptable_mode_mask where set_request can be set to: \n + - #QURT_HVX_64B \n + - #QURT_HVX_128B \n + - #QURT_HVX_NO_USE \n + - #QURT_HVX_RELEASE_CONTEXT \n + - #QURT_HVX_IMMEDIATE_USE \n + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_preferred_mode_mask can be set to: \n + - #QURT_HVX_64B_PREFERRED \n + - #QURT_HVX_128B_PREFERRED + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_acceptable_mode_mask can be set to: \n + - #QURT_HVX_64B_ACCEPTABLE \n + - #QURT_HVX_128B_ACCEPTABLE @tablebulletend + + @return + Result of the HVX setting in the least significant 8 bits of the returned data. \n + #QURT_EOK -- 0 \n + #QURT_HVX_SET_ERROR -- 0xFF \n + When #QURT_HVX_IMMEDIATE_USE has a result of #QURT_EOK, + bit 8 to bit 15 of the returned data contain hvx_mode_assigned:\n + - #QURT_HVX_64B_ASSIGNED \n + - #QURT_HVX_128B_ASSIGNED + + @dependencies + None. + */ +unsigned int qurt_hvx_set(unsigned int input_arg); + + +/**@ingroup func_qurt_system_hvx_regs_get_maxsize + Returns the maximum buffer size for saving HVX registers. + + @datatypes + None. + + @return + 0 -- No HVX supported in the target. \n + #QURT_HVX_VREG_BUF_SIZE -- Maximum buffer size for saving HVX registers. + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get_maxsize(void); + + +/**@ingroup func_qurt_system_hvx_regs_get_size + Returns the buffer size for saving HVX registers for a specified thread. + + @param[in] thread_id Thread ID of the target thread. + + @return + 0 -- No HVX assgined to the thread. \n + size -- Size of the buffer in bytes for saving HVX registers for the specified thread: \n + - #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + - #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + - #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + + @dependencies + None. + + */ +unsigned int qurt_system_hvx_regs_get_size(unsigned int thread_id); + + + +/**@ingroup func_qurt_system_hvx_regs_get + Saves the HVX registers into the specified buffer. + Returns the size of the data saved into the buffer. + After calling this function for the first time on a specified thread_id, the QuRT kernel removes the internal HVX saving buffer + from the specified thread. When calling the function on the same thread_id for the second time, this function returns 0. + + @param[in] thread_id Thread ID of the target thread. + @param[in] pBuf Pointer to the buffer for HVX register saving. + The first four bytes of the buffer are for saving the HVX version. HVX registers are saved from + the fifth byte of the buffer. The address of the fifth byte should be 256 bytes aligned. + For example, a buffer can be declared at first as: \n + unsigned char vbuf[QURT_HVX_VREG_BUF_SIZE+256];\n + unsigned char *pBuf; \n + then align the buffer pointer to: \n + pBuf = vbuf; \n + pBuf += (256 - 4 - (unsigned)pBuf%256); + @param[in] size Size of the buffer provided, which is pointed by *pBuf. The buffer size should not be smaller than that + returned from qurt_system_hvx_regs_get_size(), and pBuf should be aligned as described above. + @param[out] pBuf Buffer returned with the saved HVx registers (unsigned char hvx_regs[];), which are saved from the fith + byte of the buffer, and the HVX version (unsigned int hvx_version;), which in the first four bytes + contain one of the HVX dump versions:\n + - #QURT_HVX_DUMP_V65_64B \n + - #QURT_HVX_DUMP_V65_128B \n + - #QURT_HVX_DUMP_V66_128B \n + - #QURT_HVX_DUMP_V68_128B \n + - #QURT_HVX_DUMP_V79_128B \n + @tablebulletend + + @return + Total bytes of the data saved in the provided buffer. \n + 0 -- No HVX assigned to the thread \n + #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get(unsigned int thread_id, void *pBuf, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HVX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_int.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_int.h new file mode 100755 index 0000000000000..386aeda1051eb --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_int.h @@ -0,0 +1,509 @@ +#ifndef QURT_INT_H +#define QURT_INT_H +/** + @file qurt_int.h + @brief QuRT interrupt functions. + + + + Copyright (c) 2013-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/** @cond rest_reg_dist */ +/** @addtogroup interrupts_constants +@{ */ +#define SIG_INT_ABORT 0x80000000 /**< */ +#define QURT_INT_NON_DELAYED_ACK 0 +#define QURT_INT_DELAYED_ACK 1 +#define QURT_INT_ACK_DEFAULT QURT_INT_NON_DELAYED_ACK +#define QURT_INT_DRV_DEFAULT 0 +#define QURT_INT_PRIORITY_DEFAULT 0xFF + +/** QuRT interrupt property. */ +#define QURT_INT_CONFIGID_POLARITY 0x1U /**< */ +#define QURT_INT_CONFIGID_LOCK 0x2U /**< */ + +/** QuRT interrupt lock.*/ +#define QURT_INT_LOCK_DEFAULT 0x0 /**< Default. */ +#define QURT_INT_LOCK_DISABLE 0x0 /**< Interrupt can be enabled or disabled or deregistered. */ +#define QURT_INT_LOCK_ENABLE 0x1 /**< Interrupt is locked and cannot be enabled, disabled, or deregistered.*/ +/** @} */ /* end_addtogroup interrupts_constants */ + +/** @addtogroup Qurt_interrupt_type +@{ */ +/** Trigger type bit fields for a PDC interrupt:\n + @verbatim + Polarity Edge Output\n + 0 00 Level sensitive active low + 0 01 Rising edge sensitive + 0 10 Falling edge sensitive + 0 11 Dual edge sensitive + 1 00 Level sensitive active high + 1 01 Falling edge sensitive + 1 10 Rising edge sensitive + 1 11 Dual edge sensitive + @endverbatim +*/ +#define QURT_INT_TRIGGER_TYPE_SET(pol, edge) ((((pol) & 0x01U) << 2) | ((edge) & 0x03U)) /**< */ + +#define QURT_INT_TRIGGER_LEVEL_LOW QURT_INT_TRIGGER_TYPE_SET(0U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_LEVEL_HIGH QURT_INT_TRIGGER_TYPE_SET(1U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_RISING_EDGE QURT_INT_TRIGGER_TYPE_SET(1U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_FALLING_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_DUAL_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x03U) /**< */ +#define QURT_INT_TRIGGER_USE_DEFAULT 0xffU /**< */ +/** @} */ /* end_addtogroup Qurt_interrupt_type */ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_interrupt_register + @xreflabel{sec:interrupt_register} + Registers the interrupt.\n + Enables the specified interrupt and associates it with the specified QuRT signal object and + signal mask. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register(int int_num, qurt_anysignal_t *int_signal, int signal_mask); + +/**@ingroup func_qurt_interrupt_register2 + @xreflabel{sec:interrupt_register2} + Registers the interrupt.\n + Enables the specified interrupt, associates it with the specified QuRT signal object and + signal mask, and sets interrupt flags. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals that the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value #QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value #QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + #QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + @param[in] flags Defines interrupt property, supported property is interrupt lock enable/disable. + Possible values for flags: \n + - #QURT_INT_LOCK_ENABLE + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register2(int int_num, qurt_anysignal_t *int_signal, int signal_mask, unsigned int flags); +/* + * Waits for registered interrupt signal + + * Suspend the current thread until one of its registered interrupts occurs. The second input mask, + * contains the interrupt signals the IST expects to receive. The interrupt signals are registered + * with interrupts via qurt_register_interrupt API. + * + * The signals returned in the signal variable indicate which interrupts occurred. Use function + * qurt_anysignal_get to read the signals. IST must locally maintain a table that maps a signal to + * a specific interrupt. IST also checks if signal #SIG_INT_ABORT is received. If so, the IST + * must quit from interrupt receiving loop. + * + * For detail information on this API, see QuRT User Manual Section 4.2.5 + * + * Prototype + * + * unsigned int qurt_anysignal_wait(qurt_anysignal_t *int_signal, unsigned int mask) + */ + +/**@ingroup func_qurt_interrupt_acknowledge + Acknowledges an interrupt after it has been processed.\n + Re-enables an interrupt and clears its pending status. This is done after an interrupt is + processed by an IST. + + Interrupts are automatically disabled after they occur. To re-enable an interrupt, an IST + performs the acknowledge operation after it has finished processing the interrupt and + just before suspending itself (such as by waiting on the interrupt signal). + + @note1hang To prevent losing or reprocessing subsequent occurrences of the interrupt, + an IST must clear the interrupt signal (Section @xref{sec:anysignal_clear}) before + acknowledging the interrupt. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Interrupt acknowledge was successful. \n + #QURT_EDEREGISTERED -- Interrupt is already de-registered. + + @dependencies + None. +*/ +int qurt_interrupt_acknowledge(int int_num); + +/**@ingroup func_qurt_interrupt_deregister + Disables the specified interrupt and disassociates it from a QuRT signal object. + If the specified interrupt was never registered (Section @xref{sec:interrupt_register}), the deregister operation + returns the status value #QURT_EINT. + + @note1hang If an interrupt is deregistered while an IST waits + to receive it, the IST might wait indefinitely for the interrupt to occur. To avoid + this problem, the QuRT kernel sends the signal #SIG_INT_ABORT to awaken an + IST after determining that it has no interrupts registered. + + @param[in] int_num L2VIC to deregister; valid range is 0 to 1023. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number (not registered). + + @dependencies + None. + +*/ +unsigned int qurt_interrupt_deregister(int int_num); +/** @endcond */ + +/**@ingroup func_qurt_interrupt_disable + Disables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + After qurt_interrupt_disable() returns, the Hexagon subsystem + can no longer send the corresponding interrupt to the Hexagon + core, until qurt_interrupt_enable() is called + for the same interrupt. + + Avoid calling qurt_interrupt_disable() and qurt_interrupt_enable() frequently within + a short period of time.\n + - A pending interrupt can already be in the Hexagon core when qurt_interrupt_disable() + is called. Therefore, some time later, the pending interrupt is received on a Hexagon + hardware thread.\n + - After the Hexagon subsystem sends an interrupt to the Hexagon core, the Hexagon + hardware automatically disables the interrupt until kernel software re-enables the interrupt + at the interrupt acknowledgement stage. If qurt_interrupt_enable() is called from a certain + thread at an ealier time, the interrupt is re-enabled earlier and can trigger + sending a new interrupt to the Hexagon core while kernel software is still processing + the previous interrupt. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully disabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_disable(int int_num); + + +/**@ingroup func_qurt_interrupt_enable + Enables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully enabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. + +*/ + unsigned int qurt_interrupt_enable(int int_num); + + +/**@ingroup func_qurt_interrupt_status + Returns a value that indicates the pending status of the specified interrupt. + + @param[in] int_num Interrupt number that is being checked. + @param[out] status Interrupt status; 1 indicates that an interrupt is + pending, 0 indicates that an interrupt is not pending. + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_status(int int_num, int *status); + + +/**@ingroup func_qurt_interrupt_get_status + Gets the status of the specified interrupt in L2VIC. + + @param[in] int_num Interrupt number that is being checked. + @param[in] status_type 0 -- interrupt pending status \n + 1 -- interrupt enabling status + @param[out] status 0 -- OFF \n + 1 -- ON + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_status(int int_num, int status_type, int *status); + +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_interrupt_clear + Clears the pending status of the specified interrupt. + + @note1hang This operation is intended for system-level use, and must be used with care. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_clear(int int_num); + + +/**@ingroup func_qurt_interrupt_get_config + Gets the L2VIC interrupt configuration. \n + This function returns the type and polarity of the specified L2VIC interrupt. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[out] int_type Pointer to an interrupt type. \n + 0 -- Level-triggered interrupt \n + 1 -- Eedge-triggered interrupt + @param[out] int_polarity Pointer to interrupt polarity.\n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt. + + @return + #QURT_EOK -- Configuration successfully returned.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_config(unsigned int int_num, unsigned int *int_type, unsigned int *int_polarity); + +/**@ingroup func_qurt_interrupt_set_config + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang Deregister L2VIC interrupts before reconfiguring them. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Interrupt type. \n + 0 -- Level-triggered interrupt\n + 1 -- Edge-triggered interrupt + @param[in] int_polarity Interrupt polarity. \n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config(unsigned int int_num, unsigned int int_type, unsigned int int_polarity); + +/**@ingroup func_qurt_interrupt_set_config2 + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Notified to the hardware configuration callback function and used to + modify the L2VIC type. Possible values: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config2(unsigned int int_num, unsigned int int_type); + +/**@ingroup func_ qurt_interrupt_set_config3 + Sets the specified configuration value for the specified property of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured for polarity. + + @param[in] int_num L2VIC interrupt to re-enable. + @param[in] config_id Property to configure: \n + - #QURT_INT_CONFIGID_POLARITY \n + - #QURT_INT_CONFIGID_LOCK @tablebulletend + @param[in] config_val Dependent on the second argument config_id, specifies the value to set. \n + Values for #QURT_INT_CONFIGID_POLARITY: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE \n + + Values for #QURT_INT_CONFIGID_LOCK: \n + - #QURT_INT_LOCK_ENABLE\n + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered or is locked for enable/disable.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. +*/ +unsigned int qurt_interrupt_set_config3(unsigned int int_num, unsigned int config_id, unsigned int config_val); + + +/**@ingroup func_qurt_interrupt_raise + Raises the interrupt. \n + This function triggers a level-triggered L2VIC + interrupt, and accepts interrupt numbers in the range of 0 to 1023. + + @param[in] interrupt_num Interrupt number. + + @return + #QURT_EOK -- Success \n + -1 -- Failure; the interrupt is not supported. + + @dependencies + None. + */ +int qurt_interrupt_raise(unsigned int interrupt_num); + +/**@ingroup func_qurt_interrupt_raise2 + Raises the interrupt and returns the current pcycle value. + + @param[in] interrupt_num Interrupt number. + + @return + 0xFFFFFFFFFFFFFFFF -- Failure; the interrupt is not supported.\n + Other value -- pcycle count at the time the interrupt is raised. + + @dependencies + None. + */ +unsigned long long qurt_interrupt_raise2(unsigned int interrupt_num); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_isr_subcall + Indicates whether the current function is called from a callback procedure (either short or long). + + @return + #QURT_EOK -- TRUE \n + #QURT_EVAL -- FALSE. + + @dependencies + None. + */ +int qurt_isr_subcall(void); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_INT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_island.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_island.h new file mode 100755 index 0000000000000..f0c8ee27cf8b0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_island.h @@ -0,0 +1,122 @@ +#ifndef QURT_ISLAND_H +#define QURT_ISLAND_H + +/** + @file qurt_island.h + @brief Prototypes of power API + The APIs allow entering and exiting island mode where the memory + accesses are limited to local memory. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_island_get_status + Gets Island mode status. + + Returns a value that indicates whether the QuRT system executes in Island mode. + + @return + 0 - Normal mode. \n + 1 - Island mode. + + @dependencies + None. +*/ +unsigned int qurt_island_get_status (void); + +/**@ingroup func_qurt_island_get_status2 + Gets Island mode status especially that differentiates between island partial exit and complete exit. + + Returns a value that indicates the current state. + + @note1hang Transition from NORMAL mode to ISLAND mode happens in single + threaded mode. Whereas transition from ISLAND mode to other modes + happen in multi-threaded mode. So, a thread that gets island mode + status as NORMAL can assume the same status till it continues to + run. A thread that gets island mode status as ISLAND should + assume that the status may change to EXITING or NORMAL while it + runs. A thread that gets island mode status as EXITING should + assume that the status may change to NORMAL while it runs. If + the thread goes to wait state in after reading the status, it should get + the island mode state again and not assume the previous state. + @note2hang This api returns more intrinsic states than qurt_island_get_status, + when qurt_island_get_status returns 0, this api could return + QURT_ISLAND_MODE_EXITING or QURT_ISLAND_MODE_ISLAND + + @param[in/out] data field is reserved for future use. If NULL pointer is passed, + the field will be ignored. If a valid pointer is passed, + QuRT will return back a bitmask which can be interpreted as follows: + data[31] - Valid bit. Set to 1 to indicate data[30:0] are valid. + Otherwise set to 0. + data[30:0] – Reserved for future definition. + + @return + QURT_ISLAND_MODE_NORMAL - Main mode \n + QURT_ISLAND_MODE_ISLAND - Island mode \n + QURT_ISLAND_MODE_EXITING - Exiting Island mode \n + + @dependencies + None. +*/ +unsigned int qurt_island_get_status2 (unsigned int *data); + + + +/**@ingroup func_qurt_island_get_exit_status + Gets the reason for the last Island mode exit status. + + @param[out] cause_code Pointer that returns the cause code of the last + island exit reason. \n + - #QURT_EISLANDUSEREXIT -- Island exit due to user call for island exit.\n + - #QURT_ENOISLANDENTRY -- API called before exiting island. \n + - #QURT_EISLANDINVALIDINT -- Island exit due to an invalid interrupt in Island mode. @tablebulletend + + @param[out] int_num Pointer that holds the invalid interrupt number that caused + island exit when the cause code is #QURT_EISLANDINVALIDINT. + For other cases, it is -1. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_exit_status(unsigned int *cause_code, int *int_num); + +/**@ingroup func_qurt_island_get_enter_timestamp + Gets the recent timestamp when the system exits STM during island enter. + + @param[out] island_enter_timestamp Returns a pointer to the recent timestamp + recorded after the system exits STM during island enter. If the system never + attempts to enter island, the island_enter_timestamp return pointer holds a value + of zero. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_enter_timestamp(unsigned long long *island_enter_timestamp); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISLAND_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_isr.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_isr.h new file mode 100755 index 0000000000000..db29ea2f265d7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_isr.h @@ -0,0 +1,177 @@ +#ifndef QURT_ISR_H +#define QURT_ISR_H + +/*===================================================================== + + @file qurt_isr.h + + @brief Prototypes of Qurt ISR API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2017, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + Functions +=============================================================================*/ + + +/**@ingroup func_qurt_isr_set_hw_config_callback + Set callback function for the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_config_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_enable_callback + Set callback function for enabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_enable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_disable_callback + Set callback function for disabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_disable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_create + Creates an ISR thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + + @return + #QURT_EVAL -- Invalid arguments + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_isr_create (qurt_thread_t *thread_id, qurt_thread_attr_t *pAttr); + +/**@ingroup func_qurt_isr_register2 + Registers an Interrupt Service Routine to an ISR thread. ISR callback with the specified attributes. + The interrupt is enabled when this function returns success. + + @datatypes + qurt_thread_t + + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create() + @param[in] int_num The interrupt number + @param[in] prio Priority of the ISR + @param[in] flags Defines ACK type. Values : \n + QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the Kernel. + QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + @param[in] int_type. Notifies it to registered function. Values: \n + - QURT_INT_TRIGGER_USE_DEFAULT + - QURT_INT_TRIGGER_LEVEL_HIGH + - QURT_INT_TRIGGER_LEVEL_LOW + - QURT_INT_TRIGGER_RISING_EDGE + - QURT_INT_TRIGGER_FALLING_EDGE + - QURT_INT_TRIGGER_DUAL_EDGE + @param[in] isr Interrupt Service Routine with proto type void isr (void *arg, int int_num) + @param[in] arg 1st argument of the ISR when it is called to service the interrupt + + @return + QURT_EOK -- Successfully registered the ISR for the interrupt + QURT_EINT -- Interrupt not configured + QURT_EINVALID -- Invalid Thread ID + QURT_EDISABLED -- The feature is disabled + QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_register2 (qurt_thread_t isr_thread_id, int int_num, unsigned short prio, unsigned short flags, unsigned int int_type, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_isr_deregister2 + De-registers the ISR for the specified interrupt. + The interrupt is disabled when this function returns success. + + @param[in] int_num The interrupt number + + @return + QURT_EOK -- ISR deregistered successfully + QURT_ENOREGISTERED -- Interrupt with int_num is not registered + + @dependencies + None. + */ +int qurt_isr_deregister2 (int int_num); + +/**@ingroup func_qurt_isr_delete + ISR thread will exit and releases Kernel resources + + @note1hang The ISR thread shouldn't be actively processing interrupts, + otherwise the call will fail and return an error. + + @param[in] thread-id of the ISR thread that needs to be deleted. + + @return + QURT_ENOTALLOWED -- ISR thread is processing an interrupt + QURT_EINVALID -- Invalid ISR thread ID + QURT_EOK -- Success + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_delete (qurt_thread_t isr_tid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISR_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_l2cfg.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_l2cfg.h new file mode 100755 index 0000000000000..7e26b30a580d9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_l2cfg.h @@ -0,0 +1,98 @@ +#ifndef QURT_L2CFG_H +#define QURT_L2CFG_H +/** + @file qurt_l2cfg.h + @brief QuRT APIs for L2 configuration and system configuration + +EXTERNAL FUNCTIONS + qurt_l2cfg_set + qurt_l2cfg_get + qurt_system_config_get + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +/* Definition for system configuration */ +/** @addtogroup l2cfg_macros +@{ */ +#define QURT_CORE_CFG_HMX_INT8_SPATIAL 0x78 /**< HMX fixed-point spatial size */ +#define QURT_CORE_CFG_HMX_INT8_DEPTH 0x7C /**< HMX fixed-point output depth */ +/** @} */ /* end_addtogroup l2cfg_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_l2cfg_set + Sets the value of a L2 configuration register. A register can be set *IFF* its + initial value is configured. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[in] value Value to set the register to. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; likely + a configuration problem. \n + #QURT_EINVALID -- Argument error. \n + #QURT_ENOTALLOWED -- Setting this register is prohibited. + + @dependencies + None. + */ +int qurt_l2cfg_set (unsigned short offset, unsigned int value); + +/**@ingroup func_qurt_l2cfg_get + Gets the value of a L2 configuration register. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[out] value Pointer to value of the register. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; + likely a configuration problem. \n + #QURT_EINVALID -- Argument error. + + @dependencies + None. + + */ +int qurt_l2cfg_get (unsigned short offset, unsigned int * value); + + +/**@ingroup func_qurt_system_config_get + Gets the system configuration information. + + @param[in] index Index to system configuration. Values:\n + - #QURT_CORE_CFG_HMX_INT8_SPATIAL \n + - #QURT_CORE_CFG_HMX_INT8_DEPTH @tablebulletend + + @param[out] data Pointer to a word for returned data. + + @return + #QURT_EOK -- Get the configuration data successful. \n + Other values -- Failure (no such configuration available). + + @dependencies + None. + + */ +int qurt_system_config_get(int index, unsigned int *data); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_L2CFG_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_lifo.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_lifo.h new file mode 100755 index 0000000000000..dc399fccc5f0f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_lifo.h @@ -0,0 +1,71 @@ +#ifndef QURT_LIFO_H +#define QURT_LIFO_H +/** + @file qurt_lifo.h + + @brief + Provide lock free LastInFirstOut algorithm, which can be used in a + variety of situations for allocation/free fixed size buffer + This implementation touches the first word of your FREED buffer. Even + though it does not matter how you use it when it is allocated, you might want + to be a bit careful not to put your MAGIC number as the first field. + Because it will not hold the magic value for "freed" + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ +/** + Pops an element out of the LIFO. + + @param[in] freelist Pointer to the head of your list. + + @return + Top object from the list + + @dependencies + None. +*/ +/* ======================================================================*/ +void * qurt_lifo_pop(void *freelist); + + +/*======================================================================*/ +/** + Pushes an element into the LIFO. + + @param[in] freelist Pointer to the head of your list. + @param[in] buf Pointer to your buffer to push into the list. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_lifo_push(void *freelist, void *buf); + +void qurt_lifo_remove(void *freelist, void *buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_LIFO_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mailbox.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mailbox.h new file mode 100755 index 0000000000000..a6cd91c611782 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mailbox.h @@ -0,0 +1,176 @@ +#ifndef QURT_MAILBOX_H +#define QURT_MAILBOX_H + +/** + @file qurt_mailbox.h + @brief Definitions, macros, and prototypes used for QuRT mailbox + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* Definitions on typedef and return values */ + +#define QURT_MAILBOX_ID_NULL 0 +#define QURT_MAILBOX_ERROR -1 +#define QURT_MAILBOX_ID_ERROR -2 +#define QURT_MAILBOX_NON_VALID_DATA -3 +#define QURT_MAILBOX_FULL -4 +#define QURT_MAILBOX_DELETED -5 +#define QURT_MAILBOX_RECEIVE_HALTED -6 +#define QURT_MAILBOX_BANDWIDTH_LIMIT -7 + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ + +#define QURT_MAILBOX_AT_QURTOS 0U // Receiver is QurtOS +#define QURT_MAILBOX_AT_ROOTPD 1U // Receiver is RootPD (ASID=0) +#define QURT_MAILBOX_AT_USERPD 2U // Receiver is User PD (ASID!=0) +#define QURT_MAILBOX_AT_SECUREPD 3U // Receiver is Secure PD + +typedef unsigned char qurt_mailbox_receiver_cfg_t; + +#define QURT_MAILBOX_SEND_OVERWRITE 0U // When there is already valid content, overwrite it +#define QURT_MAILBOX_SEND_NON_OVERWRITE 1U // When there is already valid content, return failure + +typedef unsigned char qurt_mailbox_send_option_t; + + +#define QURT_MAILBOX_RECV_WAITING 0U // When there is no valid content, wait for it +#define QURT_MAILBOX_RECV_NON_WAITING 1U // When there is no valid content, return failure immediately +#define QURT_MAILBOX_RECV_PEEK_NON_WAITING 2U // Read the content, but doesn't remove it from the mailbox. No waiting. + +typedef unsigned char qurt_mailbox_recv_option_t; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/* Function prototype */ + +/**@ingroup qurt_mailbox_create + Creates a QuRT mailbox. + + @param name Mailbox name up to 8 characters. + @param recv_opt Configuration on the receiver process. + + @return + Mailbox ID -- Mailbox Identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at creating mailbox + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_create(char *name, qurt_mailbox_receiver_cfg_t recv_opt); + + +/**@ingroup qurt_mailbox_get_id + Gets a QuRT mailbox identifier. + + @param name Mailbox name up to 8 characters. + + @return + Mailbox ID -- Mailbox identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at getting mailbox ID + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_get_id(char *name); + + +/**@ingroup qurt_mailbox_send + Sends data to a QuRT mailbox. + + @param mailbox_id Mailbox identifier. + @param send_opt Option for mailbox send. + @param data Data to send. + + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors.\n + #QURT_MAILBOX_FULL Valid data already exists, non-overwriting.\n + #QURT_MAILBOX_BANDWIDTH_LIMIT Reached the bandwidth limitation. + + @dependencies + None. +*/ +int qurt_mailbox_send(unsigned long long mailbox_id, qurt_mailbox_send_option_t send_opt, unsigned long long data); + + +/**@ingroup qurt_mailbox_receive + Receive data from QuRT mailbox + + @param mailbox_id Mailbox Identifier + @param send_opt Option for mailbox receiving + @param data Pointer to data buffer for receiving + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. \n + #QURT_MAILBOX_NON_VALID_DATA No current valid data, put the previous content in the buffer. \n + #QURT_MAILBOX_RECEIVE_HALTED Receive halted, the waiting thread is woken up. \n + #QURT_MAILBOX_DELETED Mailbox is deleted, and the waiting thread is woken up. + + @dependencies + None. +*/ +int qurt_mailbox_receive(unsigned long long mailbox_id, qurt_mailbox_recv_option_t recv_opt, unsigned long long *data); + + +/**@ingroup qurt_mailbox_delete + Deletes a QuRT mailbox. + + A mailbox can only be deleted from the process that created the mailbox. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_delete(unsigned long long mailbox_id); + + +/**@ingroup qurt_mailbox_receive_halt + Halts a QuRT mailbox receiving and wakes up waiting threads. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_receive_halt(unsigned long long mailbox_id); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_MAILBOX_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_memory.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_memory.h new file mode 100755 index 0000000000000..90ce2586fec50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_memory.h @@ -0,0 +1,1487 @@ +#ifndef QURT_MEMORY_H +#define QURT_MEMORY_H +/** + @file qurt_memory.h + @brief Prototypes of kernel memory API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup memory_management_macros +@{ */ +#define QURT_SYSTEM_ALLOC_VIRTUAL 1 /**< Allocates available virtual memory in the address space of all + processes.*/ +/** @} */ /* end_addtogroup memory_management_macros */ +/**@cond rest_reg_dist */ +/** @addtogroup memory_management_types +@{ */ +/** @xreflabel{hdr:qurt_mem_default_pool} */ +extern qurt_mem_pool_t qurt_mem_default_pool __attribute__((section(".data"))); /**< Memory pool object.*/ +/** @} */ /* end_addtogroup memory_management_types */ + +/** @cond rest_reg_dist */ +/** Mapping attribute information*/ +typedef struct{ + qurt_paddr_64_t paddr; + qurt_size_t size ; + qurt_mem_cache_mode_t cache_mode; + qurt_perm_t perms ; +}qurt_mapping_attr_t; +/** @endcond */ +/** @} */ /* end_addtogroup mapping_attribute_types*/ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_mem_cache_clean + Performs a cache clean operation on the data stored in the specified memory area. + Peforms a syncht on all the data cache operations when the Hexagon processor version is V60 or greater. + + @note1hang Perform the flush all operation only on the data cache. + + @note1cont This operation flushes and invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed and invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_ALL\n + @note1 #QURT_MEM_CACHE_FLUSH_ALL is valid only when the type is #QURT_MEM_DCACHE @tablebulletend + @param[in] type Cache type. Values: + - #QURT_MEM_ICACHE + - #QURT_MEM_DCACHE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type.\n + + @dependencies + None. +*/ +int qurt_mem_cache_clean(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_clean2 + Performs a data cache clean operation on the data stored in the specified memory area. + + This API only performs the following data cache operations:\n + - #QURT_MEM_CACHE_FLUSH\n + - #QURT_MEM_CACHE_INVALIDATE\n + - #QURT_MEM_CACHE_FLUSH_INVALIDATE -- flushes/invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed/invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values:\n #QURT_MEM_CACHE_FLUSH\n #QURT_MEM_CACHE_INVALIDATE\n + #QURT_MEM_CACHE_FLUSH_INVALIDATE + @param[in] type Cache type. Values: \n #QURT_MEM_DCACHE + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type. + + @dependencies + None. +*/ +int qurt_mem_cache_clean2(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_phys_clean + Performs a cache clean operation on the data stored in the specified memory area based on address match and mask. + Operate on a cache line when (LINE.PhysicalPageNumber & mask) == addrmatch. + + @note1hang The addrmatch value should be the upper 24-bit physical address to match against. + + @datatypes + #qurt_mem_cache_op_t \n + + @param[in] mask 24-bit address mask. + @param[in] addrmatch Physical page number (24 bits) of memory to use as an address match. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid operation + + @dependencies + None. +*/ + +int qurt_mem_cache_phys_clean(unsigned int mask, unsigned int addrmatch, qurt_mem_cache_op_t opcode); + +/**@ingroup func_qurt_mem_l2cache_line_lock + Performs an L2 cache line locking operation. This function locks selective lines in the L2 cache memory. + + @note1hang Perform the line lock operation only on the 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to lock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of L2 cache memory to line lock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success.\n + #QURT_EALIGN -- Data alignment or address failure. + #QURT_EINVALID -- Improper addr and size passed (e.g. integer overflow due to addr + size) + #QURT_EFAILED -- Failed to lock cache line as all the ways were locked for the corresponding set of an address + in the range of addr and addr+size or the address range is not L2 cacheable + @dependencies + None. +*/ +int qurt_mem_l2cache_line_lock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_l2cache_line_unlock + Performs an L2 cache line unlocking operation. This function unlocks selective lines in the L2 cache memory. + + @note1hang Perform the line unlock operation only on a 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to unlock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of the L2 cache memory line to unlock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success. \n + #QURT_EALIGN -- Aligning data or address failure. \n + #QURT_EFAILED -- Operation failed, cannot find the matching tag. + + @dependencies + None. +*/ +int qurt_mem_l2cache_line_unlock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_region_attr_init + @xreflabel{sec:qurt_mem_region_attr_init} + Initializes the specified memory region attribute structure with default attribute values: \n + - Mapping -- #QURT_MEM_MAPPING_VIRTUAL \n + - Cache mode -- #QURT_MEM_CACHE_WRITEBACK \n + - Physical address -- -1 \n + - Virtual address -- -1 \n + - Memory type -- #QURT_MEM_REGION_LOCAL \n + - Size -- -1 + + @note1hang The memory physical address attribute must be explicitly set by calling the + qurt_mem_region_attr_set_physaddr() function. The size and pool attributes are set directly + as parameters in the memory region create operation. + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the destination structure for the memory region attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attach + Initializes a memory pool object to attach to a pool predefined in the system + configuration file. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. They are specified in memory region create operations + (Section @xref{sec:mem_region_create}). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool attach + operation is necessary only when allocating memory regions in nonstandard + memory units such as TCM. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach(char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_attach2 + Gets the identifier that corresponds to a pool object created specifically for a client, for example, HLOS_PHYSPOOL. + The client_handle is used to look up the client specific pool. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. Memory pool objects are specified during mapping creation operations + (qurt_mem_mmap() and qurt_mem_region_create()). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool_attach2 + operation is necessary only when allocating memory regions in memory units specific to the client. + + @datatypes + #qurt_mem_pool_t + + @param[in] client_handle Client identifier used by the OS to lookup the identifier + for client specific pool + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach2(int client_handle, char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_create + @xreflabel{hdr:qurt_mem_pool_create} + Dynamically creates a memory pool object from a physical address range. + + The pool is assigned a single memory region with the specified base address and size. + + The base address and size values passed to this function must be aligned to 4K byte + boundaries, and must be expressed as the actual base address and size values divided by 4K. + + For example, the function call: + @code + qurt_mem_pool_create ("TCM_PHYSPOOL", 0xd8020, 0x20, &pool) + @endcode + ... is equivalent to the following static pool definition in the QuRT system configuration file: + @code + + + + @endcode + + @cond rest_dist For more information on the system configuration file, see @xhyperref{80VB41979,80-VB419-79}. @endcond + + @note1hang Dynamically created pools are not identical to static pools. In particular, + qurt_mem_pool_attr_get() is not valid with dynamically created pools. + + @note1cont Dynamic pool creation permanently consumes system resources, and cannot be undone. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[in] base Base address of the memory region (divided by 4K). + @param[in] size Size (in bytes) of the memory region (divided by 4K). + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_mem_pool_create(char *name, unsigned base, unsigned size, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_add_pages + Adds a physical address range to the specified memory pool object.\n + + @note1hang Call this operation only with root privileges (guest OS mode). + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_mem_pool_add_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages); + +/**@ingroup func_qurt_mem_pool_remove_pages + Removes a physical address range from the specified memory pool object. + + If any part of the address range is in use, this operation returns an + error without changing the state. + + @note1hang Call this operation only with root privileges (guest-OS mode). + + @note1cont In the future, this operation will support (via the flags parameter) the + removal of a physical address range when part of the range is in use. + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + @param[in] flags Remove options. Values: \n + - 0 -- Skip holes in the range that are not part of the pool (default) \n + - #QURT_POOL_REMOVE_ALL_OR_NONE -- Pages are removed only if the specified + physical address range is entirely contained (with no holes) in the + pool free space. @tablebulletend + @param[in] callback Callback procedure called when pages were successfully removed. + Not called if the operation failed. Passing 0 as the parameter + value causes the callback to not be called. + @param[in] arg Value passed as an argument to the callback procedure. + + @return + #QURT_EOK -- Pages successfully removed. + + @dependencies + None. +*/ +int qurt_mem_pool_remove_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages, + unsigned flags, + void (*callback)(void *), + void *arg); +/**@ingroup memory_management_types*/ +#define QURT_POOL_REMOVE_ALL_OR_NONE 1 /**< */ + +/**@ingroup func_qurt_mem_pool_attr_get + Gets the memory pool attributes. \n + Retrieves pool configurations based on the pool handle, and fills in + the attribute structure with configuration values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_attr_t + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[out] attr Pointer to the memory region attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_attr_get (qurt_mem_pool_t pool, qurt_mem_pool_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attr_get_size + Gets the size of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] size Pointer to the destination variable for the range size. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_size (qurt_mem_pool_attr_t *attr, int range_id, qurt_size_t *size){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*size) = 0; + return QURT_EINVALID; + } + else { + (*size) = attr->ranges[range_id].size; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr + Gets the start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_t *addr){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; + } + else { + (*addr) = (attr->ranges[range_id].start)<<12; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr_64 + Gets the 64 bit start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_64_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr_64 (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_64_t *addr){ +if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; +} +else { + (*addr) = ((qurt_addr_64_t)attr->ranges[range_id].start)<<12; + } + return QURT_EOK; + } + + +/**@ingroup func_qurt_mem_pool_status_get + Gets the memory pool status. \n + Based on the pool handle, retrieves largest contiguous free memory, + total free memory, and total memory declared for the pool in bytes. Fills in + the memory status structure with the values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_status_t + + @param[in] pool Pool handle. + @param[out] status Pointer to the memory pool status structure. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_status_get (qurt_mem_pool_t pool, qurt_mem_pool_status_t *status); + + +/**@ingroup func_qurt_mem_pool_is_available + Checks whether the number of pages that the page_count argument indicates + can be allocated from the specified pool. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_mem_mapping_t \n + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[in] page_count Number of 4K pages. + @param[in] mapping_type Variable of type qurt_mem_mapping_t. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Mapping_type is invalid. \n + #QURT_EMEM -- Specified pages cannot be allocated from the pool. + + @dependencies + None. +*/ +int qurt_mem_pool_is_available(qurt_mem_pool_t pool, int page_count, qurt_mem_mapping_t mapping_type); + + +/**@ingroup func_qurt_mem_region_create + @xreflabel{sec:mem_region_create} + Creates a memory region with the specified attributes. + + The application initializes the memory region attribute structure with + qurt_mem_region_attr_init() and qurt_mem_region_attr_set_bus_attr(). + + If the virtual address attribute is set to its default value + (Section @xref{sec:qurt_mem_region_attr_init}), the virtual address of the memory region is + automatically assigned any available virtual address value. + + If the memory mapping attribute is set to virtual mapping, the physical address of the memory region + is also automatically assigned.\n + + @note1hang The physical address attribute is explicitly set in the attribute structure only + for memory regions with physical-contiguous-mapped mapping. + + Memory regions are always assigned to memory pools. The pool value specifies the memory pool + that the memory region is assigned to. + + @note1hang If attr is specified as NULL, the memory region is created with default + attribute values (Section @xref{sec:qurt_mem_region_attr_init}). + QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}), which allocates memory regions in SMI memory. + + @datatypes + #qurt_mem_region_t \n + #qurt_size_t \n + #qurt_mem_pool_t \n + #qurt_mem_region_attr_t + + @param[out] region Pointer to the memory region object. + @param[in] size Memory region size (in bytes). If size is not an integral multiple of 4K, + it is rounded up to a 4K boundary. + @param[in] pool Memory pool of the region. + @param[in] attr Pointer to the memory region attribute structure. + + @return + #QURT_EOK -- Memory region successfully created.\n + #QURT_EMEM -- Not enough memory to create region. + #QURT_EINVALID -- Invalid cache attributes / permissions provided in attribute. + + @dependencies + None. +*/ +int qurt_mem_region_create(qurt_mem_region_t *region, qurt_size_t size, qurt_mem_pool_t pool, qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_region_delete + Deletes the specified memory region. + + If the caller application creates the memory region, it is removed and the system reclaims its + assigned memory. + + If a different application creates the memory region (and is shared with the caller + application), only the local memory mapping to the region is removed; the system does + not reclaim the memory. + + @datatypes + #qurt_mem_region_t + + @param[in] region Memory region object. + + @returns + #QURT_EOK -- Region successfully deleted. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. +*/ +int qurt_mem_region_delete(qurt_mem_region_t region); + + +/**@ingroup func_qurt_mem_region_attr_get + @xreflabel{sec:mem_region_attr_get} + Gets the memory attributes of the specified message region. + After a memory region is created, its attributes cannot be changed. + + @datatypes + #qurt_mem_region_t \n + #qurt_mem_region_attr_t + + @param[in] region Memory region object. + @param[out] attr Pointer to the destination structure for memory region attributes. + + @return + #QURT_EOK -- Operation successfully performed. \n + Error code -- Failure. + + @dependencies + None. +*/ +int qurt_mem_region_attr_get(qurt_mem_region_t region, qurt_mem_region_attr_t *attr); + + +/**@ingroup func_qurt_mem_region_attr_set_type + Sets the memory type in the specified memory region attribute structure. + + The type indicates whether the memory region is local to an application or shared between + applications. + @cond rest_dist For more information, see @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in,out] attr Pointer to memory region attribute structure. + @param[in] type Memory type. Values: \n + - #QURT_MEM_REGION_LOCAL \n + - #QURT_MEM_REGION_SHARED @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t type){ + attr->type = type; +} + +/**@ingroup func_qurt_mem_region_attr_get_size + Gets the memory region size from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] size Pointer to the destination variable for memory region size. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_size(qurt_mem_region_attr_t *attr, qurt_size_t *size){ + (*size) = attr->size; +} + +/**@ingroup func_qurt_mem_region_attr_get_type + Gets the memory type from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] type Pointer to the destination variable for the memory type. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t *type){ + (*type) = attr->type; +} + +/**@ingroup func_qurt_mem_region_attr_set_physaddr + Sets the memory region 32-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise QuRT automatically sets it + when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr(qurt_mem_region_attr_t *attr, qurt_paddr_t addr){ + attr->ppn = (unsigned)(((unsigned)(addr))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr + Gets the memory region physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for memory region physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned)(((unsigned) (attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_region_attr_set_virtaddr + Sets the memory region virtual address in the specified memory attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_addr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_virtaddr(qurt_mem_region_attr_t *attr, qurt_addr_t addr){ + attr->virtaddr = addr; +} + +/**@ingroup func_qurt_mem_region_attr_get_virtaddr + Gets the memory region virtual address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for the memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_virtaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned int)(attr->virtaddr); +} + +/**@ingroup func_qurt_mem_region_attr_set_mapping + Sets the memory mapping in the specified memory region attribute structure. + + The mapping value indicates how the memory region is mapped in virtual memory. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mapping Mapping. Values: + - #QURT_MEM_MAPPING_VIRTUAL + - #QURT_MEM_MAPPING_PHYS_CONTIGUOUS + - #QURT_MEM_MAPPING_IDEMPOTENT + - #QURT_MEM_MAPPING_VIRTUAL_FIXED + - #QURT_MEM_MAPPING_NONE + - #QURT_MEM_MAPPING_VIRTUAL_RANDOM + - #QURT_MEM_MAPPING_INVALID @tablebulletend + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t mapping){ + attr->mapping_type = mapping; +} + +/**@ingroup func_qurt_mem_region_attr_get_mapping + Gets the memory mapping from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mapping Pointer to the destination variable for memory mapping. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t *mapping){ + (*mapping) = attr->mapping_type; +} + +/**@ingroup func_qurt_mem_region_attr_set_cache_mode + Sets the cache operation mode in the specified memory region attribute structure. + + @cond rest_dist For more information on the cache, see @xhyperref{80VB41992,80-VB419-92}.@endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mode Cache mode. Values: \n + - #QURT_MEM_CACHE_WRITEBACK \n + - #QURT_MEM_CACHE_WRITETHROUGH\n + - #QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE\n + - #QURT_MEM_CACHE_NONE @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t mode){ + QURT_PGATTR_C_SET(attr->pga, (unsigned)mode); +} + +/**@ingroup func_qurt_mem_region_attr_get_cache_mode + Gets the cache operation mode from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t *mode){ + unsigned int mode_temp = QURT_PGATTR_C_GET(attr->pga); + (*mode) = (qurt_mem_cache_mode_t)mode_temp; +} + +/**@ingroup func_qurt_mem_region_attr_set_bus_attr + Sets the (A1, A0) bus attribute bits in the specified memory region attribute structure. + + @cond rest_dist For more information on the bus attribute bits, see the @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] abits The (A1, A0) bits to use with the memory region, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_bus_attr(qurt_mem_region_attr_t *attr, unsigned abits){ + QURT_PGATTR_A_SET(attr->pga, abits); +} + +/**@ingroup func_qurt_mem_region_attr_get_bus_attr + Gets the (A1, A0) bus attribute bits from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] pbits Pointer to an unsigned integer that is filled in with + the (A1, A0) bits from the memory region attribute structure, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_bus_attr(qurt_mem_region_attr_t *attr, unsigned *pbits){ + (*pbits) = QURT_PGATTR_A_GET(attr->pga); +} + +void qurt_mem_region_attr_set_owner(qurt_mem_region_attr_t *attr, int handle); +void qurt_mem_region_attr_get_owner(qurt_mem_region_attr_t *attr, int *p_handle); +void qurt_mem_region_attr_set_perms(qurt_mem_region_attr_t *attr, unsigned perms); +void qurt_mem_region_attr_get_perms(qurt_mem_region_attr_t *attr, unsigned *p_perms); + +/**@ingroup func_qurt_mem_map_static_query + Determines whether a memory page is statically mapped. + Pages are specified by the following attributes: physical address, page size, cache mode, + and memory permissions. \n + - If the specified page is statically mapped, vaddr returns the virtual + address of the page. \n + - If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + The system configuration file defines QuRT memory maps. + + @datatypes + #qurt_addr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr Physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped, vaddr returns the virtual address. \n + #QURT_EMEM -- Specified page is not statically mapped, vaddr returns -1. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query(qurt_addr_t *vaddr, qurt_addr_t paddr, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + + +/**@ingroup func_qurt_mem_region_query + Queries a memory region. \n + This function determines whether a dynamically-created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. + When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns #QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_paddr_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr Physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Query successfully performed. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_t paddr); + + +/**@ingroup func_qurt_mapping_create + @xreflabel{hdr:qurt_mapping_create} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Mapping created. \n + #QURT_EMEM -- Failed to create mapping. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove + @xreflabel{hdr:qurt_mapping_remove} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Mapping created. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr + Translates a virtual memory address to the physical memory address to which it maps. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the + physical address of another process. + + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- Physical address to which the virtual address is mapped.\n + 0 -- Virtual address not mapped. + + @dependencies + None. +*/ +qurt_paddr_t qurt_lookup_physaddr (qurt_addr_t vaddr); + +/**@ingroup func_qurt_mem_region_attr_set_physaddr_64 + Sets the memory region 64-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise it is automatically set by + QuRT when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr_64 Memory region 64-bit physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t addr_64){ + attr->ppn = (unsigned)(((unsigned long long)(addr_64))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr_64 + Gets the memory region 64-bit physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr_64 Pointer to the destination variable for the memory region 64-bit physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t *addr_64){ + (*addr_64) = (unsigned long long)(((unsigned long long)(attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_map_static_query_64 + Determines if a memory page is statically mapped. + The following attributes specify pages: 64-bit physical address, page size, cache mode, + and memory permissions. \n + If the specified page is statically mapped, vaddr returns the virtual + address of the page. + If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + QuRT memory maps are defined in the system configuration file. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr_64 64-bit physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped; a virtual address is returned in vaddr. \n + #QURT_EMEM -- Specified page is not statically mapped; -1 is returned in vaddr. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query_64(qurt_addr_t *vaddr, qurt_paddr_64_t paddr_64, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mem_region_query_64 + Determines whether a dynamically created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr_64 64-bit physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query_64(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64); + +/**@ingroup func_qurt_mapping_create_64 + @xreflabel{hdr:qurt_mapping_create_64} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Failure. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove_64 + @xreflabel{hdr:qurt_mapping_remove_64} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Success. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr_64 + Translates a virtual memory address to the 64-bit physical memory address it is mapped to. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the physical + address of another process. + + @datatypes + #qurt_paddr_64_t \n + #qurt_addr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address has not been mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr_64 (qurt_addr_t vaddr); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_mapping_reclaim + Deallocates all QuRT resources associated with the specified virtual + memory area, making it available for user memory management:\n + - The associated physical memory areas are freed and added to the + specified physical pool.\n + - The associated TLB entries are deleted and made available for TLB + management.\n + - The virtual memory area is not freed -- it is left in + place as allocated, but unmapped virtual memory. Access to this + memory area generates an exception.\n + + The virtual memory area must be statically allocated. + If no pool is specified, the freed physical memory is not added to any pool. + + @note1hang The virtual memory area is restricted to being filled with locked + TLB entries that are contiguous within the memory area, and contained by it. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_pool_t + + @param[in] vaddr Virtual address of the memory area to free. + @param[in] vsize Size (in bytes) of the memory area to free. + @param[in] pool Handle to the physical pool where freed physical memory is added. + If set to 0, freed physical memory is not added to any pool. + + @return + 0 -- Success. \n + Nonzero -- Failure that indicates a partial success, or that the request was malformed. \n @note1hang The expected behavior is that + QuRT logs messages related to the failure, and callers are free to ignore the return value. + + @dependencies + None. +*/ +int qurt_mapping_reclaim(qurt_addr_t vaddr, qurt_size_t vsize, qurt_mem_pool_t pool); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_mem_configure_cache_partition + Configures the Hexagon cache partition at the system level. + + A partition size value of #SEVEN_EIGHTHS_SIZE is applicable only to the L2 cache. + + The L1 cache partition is not supported in Hexagon processor version V60 or greater. + + @note1hang Call this operation only with QuRT OS privilege. + + @datatypes + #qurt_cache_type_t \n + #qurt_cache_partition_size_t + + @param[in] cache_type Cache type for partition configuration. Values: \n + - #HEXAGON_L1_I_CACHE \n + - #HEXAGON_L1_D_CACHE \n + - #HEXAGON_L2_CACHE @tablebulletend + + @param[in] partition_size Cache partition size. Values: \n + - #FULL_SIZE \n + - #HALF_SIZE \n + - #THREE_QUARTER_SIZE \n + - #SEVEN_EIGHTHS_SIZE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Error. + + @dependencies + None. + */ +int qurt_mem_configure_cache_partition(qurt_cache_type_t cache_type, qurt_cache_partition_size_t partition_size); + + +/**@ingroup func_qurt_mem_syncht + @xreflabel{hdr:qurt_mem_syncht} + Performs heavy-weight synchronization of memory transactions. + + This operation does not return until all previous memory transactions (cached and uncached load/store, + mem_locked, and so on) that originated from the current thread are complete and globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon syncht instruction. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_syncht(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" SYNCHT \n"); + #endif +} + +/**@ingroup func_qurt_mem_barrier + @xreflabel{hdr:qurt_mem_barrier} + Creates a barrier for memory transactions. + + This operation ensures that all previous memory transactions are globally observable before any + future memory transactions are globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon barrier instruction. + @return + None + + @dependencies + None. + */ +static inline void qurt_mem_barrier(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" BARRIER \n"); + #endif +} +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_system_mem_alloc + Requests that the kernel allocates memory from the kernel-owned pool. + + @param[in] size Size in bytes (aligned to 4K) to allocate. + @param[in] align Any alignment that must be considered for the allocation. + @param[in] flags Supports the #QURT_SYSTEM_ALLOC_VIRTUAL flag; allocates + available virtual memory in the address space of all processes. + + @return + #QURT_EFATAL -- Allocation failed \n + Start address of the successful allocation. + + @dependencies + None. +*/ +unsigned qurt_system_mem_alloc(unsigned size, unsigned align, unsigned flags); +/** @endcond */ +/** @cond rest_reg_dist*/ +/**@ingroup func_qurt_lookup_physaddr2 + Translates the virtual memory address of the specified process to the 64-bit + physical memory address to which it is mapped. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[in] vaddr Virtual address. + @param[in] pid PID. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address is not mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr2(qurt_addr_t vaddr, unsigned int pid); +/** @endcond */ + +/**@ingroup func_qurt_mapping_attr_get + Gets the mapping attributes for a given virtual address and PID + + @datatypes + #qurt_addr_t \n + #qurt_mapping_attr_t + + @param[in] vaddr virtual address for which the attributes are required. + @param[in] pid process id for the target process + @param[out] attr Pointer to the mapping attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Incorrect virtual address or pid +*/ +int qurt_mapping_attr_get(qurt_addr_t vaddr, unsigned int pid, qurt_mapping_attr_t *attr); + + +/**@ingroup func_qurt_mapping_attr_get_cache_mode + Gets the cache operation mode in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] cache_mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_cache_mode(qurt_mapping_attr_t *attr, qurt_mem_cache_mode_t *cache_mode) +{ + (*cache_mode) = attr->cache_mode; +} + +/**@ingroup func_qurt_mapping_attr_get_physaddr + Gets the physical memory address in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] physaddr Pointer to the destination variable for physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_physaddr(qurt_mapping_attr_t *attr, qurt_paddr_64_t *physaddr) +{ + (*physaddr) = attr->paddr; +} + +/**@ingroup func_qurt_mapping_attr_get_perms + Gets the permissions in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_perm_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] perms Pointer to the destination variable for permissions. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_perms(qurt_mapping_attr_t *attr, qurt_perm_t *perms) +{ + (*perms) = attr->perms; +} + +/**@ingroup func_qurt_mapping_attr_get_size + Gets the size in the specified memory mapping attribute structure.This represents size of the + TLB entry which covers the virtual address. + + + @datatypes + #qurt_mapping_attr_t \n + #unsigned int + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] size Pointer to the destination variable for size. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_mapping_attr_get_size(qurt_mapping_attr_t *attr, unsigned int *size) +{ + (*size) = attr->size; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MEMORY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mmap.h new file mode 100755 index 0000000000000..c3bd875910af7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mmap.h @@ -0,0 +1,359 @@ +#ifndef QURT_MMAP_H +#define QURT_MMAP_H +/** + @file qurt_mmap.h + @brief Prototypes of memory mapping/unmapping APIs. + The APIs allow the user to map, un-map, and change permissions + on memory regions. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2022, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_mem_mmap + Creates a memory mapping with the specified attributes. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that specifies a pool handle + if the user wants to allocate memory from a specific pool. + The default value for this argument is NULL. + @param[in] pRegion Map region. This argument is unused, and the default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + @param[in] flags Mapping modes.\n + - #QURT_MAP_NAMED_MEMSECTION + - #QURT_MAP_FIXED \n + - #QURT_MAP_NONPROCESS_VPOOL \n + - #QURT_MAP_TRYFIXED \n + - #QURT_MAP_ANON \n + - #QURT_MAP_PHYSADDR \n + - #QURT_MAP_VA_ONLY @tablebulletend + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap2 + Creates a memory mapping with the specified attributes. Returns a more descriptive + error code in case of failure. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that allows the user to specify a pool handle + when the user wants to allocate memory from a specific pool. + Default value for this argument is NULL. + @param[in] pRegion Map region (unused argument); default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode. + @param[in] flags Mapping modes; + Shared, Private, or Anonymous. + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_EMEM -- Physical address is not available. \n + #QURT_EFAILED -- VA is not available or mapping failed.\n + #QURT_EINVALID -- Invalid argument was passed (for example, an unaligned VA/PA). + */ +void *qurt_mem_mmap2(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap_by_name + Creates a memory mapping for a named-memsection using the specified attributes. + The named memsection should be specified in cust_config.xml. + + @note1hang If the specified attributes are not valid or the named memsection is not found, + an error result is returned. + + @param[in] name Name of the memsection in cust_config.xml that specifies + this mapping. Should be less than 25 characters. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode + @param[in] flags Mapping modes, such as + Shared, Private, or Anonymous. + @param[in] offset Offset relative to the physical address range specified in memsection. + If offset + length exceeds size of memsection, failure is + returned. + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap_by_name(const char* name, + void *addr, + size_t length, + int prot, + int flags, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mprotect2 + Changes access permissions and attributes on an existing mapping based on the client_handle argument. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned. + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping.\n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect2(int client_handle, const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_mprotect + Changes access permissions and attributes on an existing mapping. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned.\n + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect(const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_munmap + Removes an existing mapping. + + @note1hang If the specified mapping is not found in the context of the caller process + or invalid attributes are passed, an error code is returned. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap(void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap2 + Removes an existing mapping for a specified process. + + @note1hang This API allows a root process entity, such as a driver, to remove mapping + that was created for a user process. If the specified mapping is not found in the context + of client handle or invalid attributes are passed, an error code is returned. + + @param[out] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap2(int client_handle, + void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap3 + Removes an existing mapping or reservation for a specified process. + + @param[in] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Pointer to a virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] flags Specifies the flag. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap3(int client_handle, + void *addr, + size_t length, + int flags); + +/* +|| The macros here follow the style of the standard mmap() macros, but with +|| QURT_ prepended to avoid name conflicts, and to avoid having a dependency +|| on sys/mman.h. +|| +|| Wherever possible, any values here that are also present in sys/mman.h +|| should have the same value in both places so that we can accept "mmap" +|| calls without having to remap parameters to new values. +|| +|| In the future, it would be desirable to have a regression test that +|| checks, for instance, that these macros match. Example: +|| +|| assert(QURT_MAP_FAILED == MAP_FAILED); +|| ... repeat as needed ... +*/ + +/** @addtogroup memory_mapping_macros +@{ */ +/** @cond */ +#define QURT_PROT_NONE 0x00U /**< */ +#define QURT_PROT_READ 0x01U /**< */ +#define QURT_PROT_WRITE 0x02U /**< */ +#define QURT_PROT_EXEC 0x04U /**< */ +#define QURT_PROT_NODUMP 0x08U /**< Skip dumping the mapping. During PD dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and the DSP process + crashes before the mapping is removed.*/ +#define QURT_PROT_ISLAND 0x10U /**< Island mapping. */ + +#define QURT_MAP_SHARED 0x0001U /**< Shared. */ +#define QURT_MAP_PRIVATE 0x0002U /**< Private. */ +/** @endcond */ +#define QURT_MAP_NAMED_MEMSECTION 0x0004U /**< Named memsection. */ +#define QURT_MAP_FIXED 0x0010U /**< Fixed virtual address. */ +#define QURT_MAP_RENAME 0x0020U /**< Rename. */ +#define QURT_MAP_NORESERVE 0x0040U /**< No reserve. */ +#define QURT_MAP_INHERIT 0x0080U /**< Inherit. */ +#define QURT_MAP_NONPROCESS_VPOOL 0x0100U /**< Use a virtual address outside of the default range of the + processes. This option is only supported in the root process + and only when virtual memory split is enabled in the XML. + The root process can use this flag to create mapping for a + user process, for example, if the virtual address is configured + for a 3G/1G split, the root process can use this flag to create + mapping in the top 1 GB area for the user process or the + lower 3 GB area for the root process. This is useful for + shared buffer use cases. */ +#define QURT_MAP_HASSEMAPHORE 0x0200U /**< Has semaphore. */ +#define QURT_MAP_TRYFIXED 0x0400U /**< Try to create a mapping for a virtual address that was passed. + If the passed virtual address fails, use a random virtual address. */ +#define QURT_MAP_WIRED 0x0800U /**< Wired. */ +#define QURT_MAP_FILE 0x0000U /**< File. */ +#define QURT_MAP_ANON 0x1000U /**< Allocate physical memory from the pool that was passed. + By default, memory is allocated from the default physpool. */ +#define QURT_MAP_VA_ONLY 0X2000U /**< Reserve a virtual address without + mapping it. */ + +/** @cond */ +#define QURT_MAP_ALIGNED(n) ((n) << QURT_MAP_ALIGNMENT_SHIFT) +#define QURT_MAP_ALIGNMENT_SHIFT 24 + + +#define QURT_MAP_ALIGNMENT_MASK QURT_MAP_ALIGNED(0xff) /**< */ +#define QURT_MAP_ALIGNMENT_64KB QURT_MAP_ALIGNED(16) /**< */ +#define QURT_MAP_ALIGNMENT_16MB QURT_MAP_ALIGNED(24) /**< */ +#define QURT_MAP_ALIGNMENT_4GB QURT_MAP_ALIGNED(32) /**< */ +#define QURT_MAP_ALIGNMENT_1TB QURT_MAP_ALIGNED(40) /**< */ +#define QURT_MAP_ALIGNMENT_256TB QURT_MAP_ALIGNED(48) /**< */ +#define QURT_MAP_ALIGNMENT_64PB QURT_MAP_ALIGNED(56) /**< */ +/** @endcond */ +#define QURT_MAP_FAILED ((void *) -1) /**< Mapping creation failed. */ + +/* +|| The macros below are extensions beyond the standard mmap flags, but follow +|| the style of the mmap flags. +*/ +/** @cond */ +// Describe bitfields in (prot) +#define QURT_PROT_CACHE_BOUNDS 16U,19U,7U /**< Bits 16 through 19 are cache attribute, default is 0. */ +#define QURT_PROT_BUS_BOUNDS 20U,21U,0U /**< Bits 20 through 21 are bus attributes, default is 0. */ +#define QURT_PROT_USER_BOUNDS 22U,23U,3U /**< Bits 22 through 23 are user mode, default is 3; + default of 3 means to derive user mode setting from the + default mode of the client. */ + +// Describe bitfields in (flags) +#define QURT_MAP_PHYSADDR_BOUNDS 15U,15U,0U /**< Bits 15 through 15 are physaddr, default is 0. */ +#define QURT_MAP_TYPE_BOUNDS 16U,19U,0U /**< Bits 16 through 19 are mapping type, default is 0. */ +#define QURT_MAP_REGION_BOUNDS 20U,23U,0U /**< Bits 20 through 23 are region type, default is 0. */ +/** @endcond */ + +// These macros get OR'ed into (prot) +#define QURT_PROT_CACHE_MODE(n) QURT_MMAP_BUILD(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_BUS_ATTR(n) QURT_MMAP_BUILD(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_USER_MODE(n) QURT_MMAP_BUILD(QURT_PROT_USER_BOUNDS,(n)) /**< */ +// These macros get OR'ed into (flags) + +#define QURT_MAP_PHYSADDR QURT_MMAP_BUILD(QURT_MAP_PHYSADDR_BOUNDS,1U) /**< Use the physical address that was passed in offset field. + This is allowed only for root process. */ +#define QURT_MAP_TYPE(n) QURT_MMAP_BUILD(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_REGION(n) QURT_MMAP_BUILD(QURT_MAP_REGION_BOUNDS,(n)) /**< */ +/** @} */ /* end_addtogroup memory_mapping_macros */ +/** @cond */ +// These macros extract fields from (prot) +#define QURT_PROT_GET_CACHE_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_BUS_ATTR(n) QURT_MMAP_EXTRACT(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_USER_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_USER_BOUNDS,(n)) /**< */ + +// These macros extract fields from (flags) +#define QURT_MAP_GET_TYPE(n) QURT_MMAP_EXTRACT(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_GET_REGION(n) QURT_MMAP_EXTRACT(QURT_MAP_REGION_BOUNDS,(n)) /**< */ + +// Macros for bitfield insertion and extraction +#define QURT_MMAP_MASK(lo,hi) (~((~0u) << ((hi)-(lo)+1U))) /**< Mask of same size as [lo..hi]. */ +#define QURT_MMAP_BUILD_(lo,hi,def,n) ((((n)^(def))&QURT_MMAP_MASK((lo),(hi)))<<(lo)) /**< */ +#define QURT_MMAP_EXTRACT_(lo,hi,def,n) ((((n)>>(lo))&QURT_MMAP_MASK((lo),(hi)))^(def)) /**< */ +#define QURT_MMAP_BUILD(a,b) QURT_MMAP_BUILD_(a,b) /**< */ +#define QURT_MMAP_EXTRACT(a,b) QURT_MMAP_EXTRACT_(a,b) /**< */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mq.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mq.h new file mode 100755 index 0000000000000..580c83d3de41a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mq.h @@ -0,0 +1,458 @@ +#ifndef QURT_MQ_H +#define QURT_MQ_H +/** + @file qurt_mq.h + + @brief Prototypes of secure message queues API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2019-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +======================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_MQ_NAME_MAXLEN 16U /**< Maximum name length. */ + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/* This enum must be generated in accordance to process class class numbers. + For now it is made to match generated version, do not change this unless + there is a corresponding change in the process_class.py, indicies start from 0 + basically: QURT_MQ_SECURITY_SCOPE_ = (1 << QURTK_process_class_index_) +*/ +typedef enum { + QURT_MQ_SECURITY_SCOPE_KERNEL = ( 1U << 0 ), + QURT_MQ_SECURITY_SCOPE_SRM = ( 1U << 1 ), + QURT_MQ_SECURITY_SCOPE_SECURE = ( 1U << 2 ), + QURT_MQ_SECURITY_SCOPE_CPZ = ( 1U << 3 ), + QURT_MQ_SECURITY_SCOPE_ROOT = ( 1U << 4 ), + QURT_MQ_SECURITY_SCOPE_SIGNED = ( 1U << 5 ), + QURT_MQ_SECURITY_SCOPE_UNSIGNED = ( 1U << 6 ), + QURT_MQ_SECURITY_SCOPE_SECURE_ROOT = ( 1U << 7 ) +} qurt_mq_security_scope_t; + +typedef enum { + QURT_MQ_CARDINALITY_PTP = (1U << 0), + QURT_MQ_CARDINALITY_MTO = (1U << 1) +}qurt_mq_cardinality_t; + +typedef unsigned int qurt_mqd_t; + +typedef union{ + struct { + unsigned int perms:2; + unsigned int cardinality:1; + unsigned int blocking:1; + + qurt_mq_security_scope_t creator_scope: 8; + qurt_mq_security_scope_t allowed_scope: 8; //can be a bitmask in case of MTO + unsigned int queue_closed: 1; + unsigned int reserved: 11; + }; //try to do anonymous struct + unsigned int raw; +} qurt_mq_flags_t; + + +/* permissions are from qurt_types.h , block X though */ +#if 0 +/** Memory access permission. */ +typedef enum { + QURT_PERM_READ=0x1U, /**< */ + QURT_PERM_WRITE=0x2U, /**< */ + QURT_PERM_EXECUTE=0x4U, /**< */ + QURT_PERM_FULL=QURT_PERM_READ|QURT_PERM_WRITE|QURT_PERM_EXECUTE, /**< */ +} qurt_perm_t; +#endif + +struct qurt_mq_attr { + unsigned flags; /**< Configured flags. Only meaningful with get_attr(), only used for qurt_mq_flags_t.perms. */ + unsigned mq_maxmsg; /**< Maximum number of messages. Used with create() and get_attr. */ + unsigned short mq_send_msgsize; /**< Maximum size (bytes) of message in receiver facing queue, + from sender to receiver. */ + unsigned short mq_recv_msgsize; /**< Maximum size (bytes) of message in sender facing queue, + from receiver to sender. */ + unsigned client_pid; /**< Process ID of client that is allowed to open the message queue + that was created using qurt_mq_create(). */ + qurt_mq_cardinality_t cardinality; /**< Cardinality of message queue connection, see below. */ + qurt_mq_security_scope_t scope; /**< Security scope of the senders to the queue. */ +}; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mq_attr_init + Initializes attributes to default values used for creating the queue. + + The initialize operation sets the following default attribute values: \n + - flag - QURT_PERM_READ | QURT_PERM_WRITE \n + - maxmsg - 1 \n + - mq_send_msgsize - 8 \n + - mq_recv_msgsize - 8 \n + - sender_pid - -1 \n + - cardinality - QURT_MQ_CARDINALITY_PTP \n + - scope - QURT_MQ_SECURITY_SCOPE_SIGNED \n + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the initialized message queue object. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_init(struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_attr_set_send_msgsize + Sets the message size in bytes the sender can send. + Maximum message length is configurable using the XML configuration, however, limited to a maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_send_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_recv_msgsize + Sets the message size in bytes that the receiver can read. + Maximum message length is configurable using the XML configuration, however, limited to maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_recv_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_maxmsg + Sets the maximum message that can queue in the message queue. + Message depth is configurable using the XML configuration. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] depth Maximum message that can be queued. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_maxmsg (struct qurt_mq_attr *attr, unsigned int depth); + +/**@ingroup qurt_mq_attr_set_scope + Sets the scope of the message queue. A message queue created with a security + scope allows only a process class of that scope to open a message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mq_security_scope_t + + @param[in,out] attr Pointer to the message queue object. + @param[in] scope Scope of the message queue: \n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_scope (struct qurt_mq_attr *attr, qurt_mq_security_scope_t scope); + + +/**@ingroup qurt_mq_attr_set_client_pid + Sets the client_pid that can open this message queue. + If client_pid is set, allowed_scope to open MQ shall not be considered. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] client_pid Valid PID for client process. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_client_pid (struct qurt_mq_attr *attr, unsigned client_pid); + +/**@ingroup qurt_mq_attr_set_flags + Sets the properties of the message queues. + The current implementation is only used to set the permission for the message queue using the flag attribute. + Default is #QURT_PERM_READ | #QURT_PERM_WRITE, explicit permission is not implemented. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] flags Permission for message queue. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_flags (struct qurt_mq_attr *attr, unsigned int flags); + +/**@ingroup qurt_mq_create + Create a message queue with the provided name and attributes. + The calling process becomes the owner of the queue. + Name of the message queue is limited to 16 characters including the NULL terminator. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue identifier if + the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] attr Pointer to the initialized message queue attribute + structure that specifies the attributes of the created message queue. + + @return + #QURT_EOK Message queue created. \n + #QURT_EINVALID Invalid arguments. \n + #QURT_ENOSPC Maximum number of queues in the system is exceeded. + + @dependencies + None. +*/ +int qurt_mq_create(qurt_mqd_t *mqd, const char *name, struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_open + Opens a message queue connection between a process and a created message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue + identifier if the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] flags Flag that contains the properties that define the behavior of message queue connection. + Permissions:\n + #QURT_PERM_READ \n + #QURT_PERM_WRITE \n + #QURT_PERM_READ | QURT_PERM_WRITE @tablebulletend + Default is QURT_PERM_READ | QURT_PERM_WRITE, explicit permission is not implemented \n + Cardinality: \n + #QURT_MQ_CARDINALITY_PTP (default) \n + #QURT_MQ_CARDINALITY_MTO (not implemented) \n + Block suspend thread until the message queue with the apecified name is created. \n + Scope: security boundary to which the message queue and its users are constrained. + Block suspend thread until the message queue with the apecified name is created. \n + It is coupled with process privilege level/scope.\n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED @tablebulletend + + @return + QURT_EOK -- Message queue connection successfully opened \n + QURT_EFAILED -- Message queue connection failed , if non-blocking message queue \n + QURT_ENOTALLOWED -- Open failed due to security scope mismatch + + @dependencies + None. +*/ +int qurt_mq_open (qurt_mqd_t *mqd, const char *name, qurt_mq_flags_t flags); + +/**@ingroup qurt_mq_send + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send shall resume that thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] msg_len Length of the message buffer in bytes. + + @return + #QURT_EOK Message queue send was successful.\n + #QURT_EMSGSIZE Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED Send failed due to security scope mismatch. + + @dependencies + None. +*/ +int qurt_mq_send(qurt_mqd_t mqd, const char *msg_ptr, size_t msg_len); + +/**@ingroup qurt_mq_send_timed + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message or until timeout is reached. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_send_timed shall return #QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] duration Interval (in microseconds) that the duration value must be + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in] msg_len Length of message buffer in bytes. + + @return + #QURT_EOK -- Message queue send was successful. \n + #QURT_EMSGSIZE -- Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED -- Send failed due to security scope mismatch \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. +*/ +int qurt_mq_send_timed(qurt_mqd_t mqd, const char *msg_ptr, unsigned long long int duration, size_t msg_len); + + /**@ingroup qurt_mq_recv + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue. \n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv shall resume the thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in,out] msg_len Pointer to the length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID Message pointer or msg_len ptr are NULL. \n + #QURT_EBADR Message queue descriptior (mqd) is invalid. \n + #QURT_EBADF Sender closed the message queue. + + @dependencies + None. +*/ +int qurt_mq_recv(qurt_mqd_t mqd, unsigned char *msg_ptr, size_t *msg_len); + + /**@ingroup qurt_mq_recv_timed + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue or until timeout is reached.\n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_recv_timed shall return QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in] duration Interval (in microseconds) that the duration value must be; + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in,out] msg_len Pointer to length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID -- Message ptr or msg_len ptr are NULL. \n + #QURT_EBADR -- Message queue descriptior (mqd) is invalid.\n + #QURT_EBADF -- Sender closed the message queue. \n + #QURT_ETIMEDOUT -- Timeout. + + @dependencies + None. +*/ +int qurt_mq_recv_timed(qurt_mqd_t mqd, unsigned char *msg_ptr, unsigned long long int duration, size_t *msg_len); + + /**@ingroup qurt_mq_close + Closes the message queue and disassociates the calling process (client) from the message queue + under this descriptor. Marks the queue as closed for the receiver. + This function is expected to be called from the client side. If called + from the server side, the function reduces to no-op and returns success. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue close was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_close(qurt_mqd_t mqd); + + /**@ingroup qurt_mq_destroy + Destroys the message queue. This function ought to be + called from the process that called qurt_mq_create(). + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue destroy was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_destroy(qurt_mqd_t mqd); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif //QURT_MQ_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mutex.h new file mode 100755 index 0000000000000..4ad6b270cdde6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_mutex.h @@ -0,0 +1,211 @@ +#ifndef QURT_MUTEX_H +#define QURT_MUTEX_H +/** + @file qurt_mutex.h + @brief Prototypes of mutex API. + This is mostly a user space mutex, but calls the + kernel to block if the mutex is taken. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT mutex type. + + Both non-recursive mutex lock and unlock, and recursive + mutex lock and unlock can be applied to this type. + */ +typedef union qurt_mutex_aligned8{ + /** @cond */ + struct { + unsigned int holder; + unsigned int count; + unsigned int queue; + unsigned int wait_count; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_mutex_t; +/** @} */ /* end_addtogroup mutex_types */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* @addtogroup mutex_const_macros +@{ */ +#define MUTEX_MAGIC 0xfe /**< */ +#define QURTK_FUTEX_FREE_MAGIC 0x1F // 11111 /**< */ +#define QURT_MUTEX_INIT {{MUTEX_MAGIC, 0, QURTK_FUTEX_FREE_MAGIC,0}} /**< Suitable as an initializer for a + variable of type qurt_mutex_t. */ +/* @} */ /* end_addtogroup mutex_const_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mutex_init + Initializes a mutex object. + The mutex is initially unlocked. + + @note1hang Each mutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_mutex_destroy() + when this object is not used anymore + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the mutex object. Returns the initialized object. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_destroy + Destroys the specified mutex. + + @note1hang Mutexes must be destroyed when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Mutexes must not be destroyed while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_lock + Locks the specified mutex. + If a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. + + @note1hang A thread is suspended indefinitely if it locks a mutex that it has already + locked. Avoid this by using recursive mutexes (Section @xref{dox:recursive_mutexes}). + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_lock(qurt_mutex_t *lock); /* blocking */ + +/**@ingroup func_qurt_mutex_lock_timed + Locks the specified mutex. + When a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + When a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. If the duration of suspension exceeds the timeout duration, wait is + terminated and no access to mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object; specifies the mutex to lock. + @param[in] duration Interval (in microseconds) that the duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_mutex_lock_timed (qurt_mutex_t * lock, unsigned long long int duration); + +/**@ingroup func_qurt_mutex_unlock + Unlocks the specified mutex. \n + More than one thread can be suspended on a mutex. When the mutex is unlocked, only the + highest-priority thread waiting on the mutex is awakened. If the awakened thread has + higher priority than the current thread, a context switch occurs. + + @note1hang The behavior of QuRT is undefined if a thread unlocks a mutex it did not first + lock. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to unlock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_unlock(qurt_mutex_t *lock); /* unlock */ + +/**@ingroup func_qurt_mutex_try_lock + @xreflabel{hdr:qurt_mutex_try_lock} + Attempts to lock the specified mutex. + If a thread performs a try_lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + @note1hang If a thread performs a try_lock operation on a mutex that it has already locked + or is in use by another thread, qurt_mutex_try_lock immediately returns with a + nonzero result value. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_mutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_os_services.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_os_services.h new file mode 100755 index 0000000000000..cbc4c239e9620 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_os_services.h @@ -0,0 +1,24 @@ +/*============================================================================= + + qurt_os_services.c + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ + +#define QURT_OS_SERVICE_THREAD "/os/thread" /**< Thread service */ +#define QURT_OS_SERVICE_FS_HUB "/os/fs_hub" /**< file-system hub */ +#define QURT_OS_SERVICE_CALLBACK "/os/callback" /**< QDI callback service */ +#define QURT_OS_SERVICE_INTERRUPTS "/os/interrupt" /**< Interrupt service */ +#define QURT_OS_SERVICE_PROXY "/os/proxy" /**< QDI proxy serice */ +#define QURT_OS_SERVICE_MEMORY "/os/memory" /**< Memory management service */ +#define QURT_OS_SERVICE_MEMPOOL "/os/mempool" /**< Pool management service */ +#define QURT_OS_SERVICE_PROCESS "/os/process" /**< Process management service */ +#define QURT_OS_SERVICE_MMAP "/os/mem_mapper" /**< mmapper service */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex.h new file mode 100755 index 0000000000000..61aee5cba7ce8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_PIMUTEX_H +#define QURT_PIMUTEX_H 1 +/** + @file qurt_pimutex.h + @brief Prototypes of qurt_pimutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pimutex_init + Initializes a priority inheritance mutex object. + The priority inheritance mutex is initially unlocked. + + This function works the same as qurt_mutex_init(). + + @note1hang Each pimutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_pimutex_destroy() + when this object is not used anymore + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the priority inheritance mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_destroy + Destroys the specified priority inheritance mutex. + + @note1hang Priority inheritance mutexes must be destroyed when they are no longer in + use. Failure to do this causes resource leaks in the QuRT kernel.\n + @note1cont Priority inheritance mutexes must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_lock + Requests access to a shared resources. If a thread performs a lock operation on a mutex + that is not in use, the thread gains access to the shared resource that the mutex protects, + and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + If a thread is suspended on a priority inheritance mutex, and the priority of the suspended + thread is higher than the priority of the thread that has locked the mutex, the thread + with the mutex acquires the higher priority of the suspended thread. The locker thread blocks + until the lock is available. + + @note1hang A thread is not suspended if it locks a priority inheritance mutex that it has + already locked . However, the mutex does not become available to other + threads until the thread performs a balanced number of unlocks on the mutex.\n + @note1cont When multiple threads compete for a mutex, the lock operation for a priority + inheritance mutex is slower than it is for a recursive mutex. + In particular, it is about 10 times slower when the mutex is available for locking, + and slower (with greatly varying times) when the mutex is already locked. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_lock(qurt_mutex_t *lock); + + +/**@ingroup func_qurt_pimutex_lock_timed + Locks a priority inheritance mutex with timeout. + + A thread can lock a priority inheritance mutex for multiple times. The mutex is not + available to other threads until the thread performs the same number of mutex unlock + operations. + + If a thread performs a lock operation on a mutex that is already locked by another thread, + the thread is moved to waiting state. When the mutex becomes available again (because the + other thread has unlocked the mutex), the thread is awakened and tries to lock the mutex. + + If a thread is waiting on a priority inheritance mutex, and the priority of the waiting thread + is higher than the priority of the thread that has locked the mutex, the priority of the thread + that has locked the mutex is raised to the same priority of the waiting thread. + + If the duration of waiting exceeds the timeout duration, the waiting is terminated, and + the function returns QURT_ETIMEDOUT as a failure of the mutex lock. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to lock. + @param[in] duration Duration (in microseconds) to wait. The duration value must be between + #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + #QURT_EINVALID -- Duration is out of range + + @dependencies + None. + + */ +int qurt_pimutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + + +/**@ingroup func_qurt_pimutex_unlock + Releases access to a shared resource; unlocks the specified priority inheritance mutex. \n + More than one thread can be suspended on a priority inheritance mutex. When the mutex + is unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + When a thread unlocks a priority inheritance mutex, its thread priority is restored to its + original value from any higher priority value that it acquired from another thread + suspended on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_try_lock + Request access to a shared resource (without suspend). Attempts to lock the specified priority inheritance mutex.\n + If a thread performs a try_lock operation on a priority inheritance mutex that is not in + use, the thread gains access to the shared resource that is protected by the mutex, and + continues executing. + If a thread performs a try_lock operation on a priority inheritance mutex that is already + in use by another thread, qurt_pimutex_try_lock immediately returns with a + nonzero result value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_pimutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex2.h new file mode 100755 index 0000000000000..b809f163cbfd2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pimutex2.h @@ -0,0 +1,162 @@ +#ifndef QURT_PIMUTEX2_H +#define QURT_PIMUTEX2_H +/** + @file qurt_pimutex2.h + @brief Prototypes of pimutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_pimutex2_init + Initializes a recursive mutex object. + + @deprecated use #qurt_pimutex_init instead. + + The recursive mutex is initially unlocked. + + Objects of type pimutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_destroy + + @deprecated use #qurt_pimutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1cont Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code should destroy an pimutex2 object prior to + deallocating it; calling qurt_pimutex2_destroy() before deallocating it ensures + that all qurt_pimutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_lock + + @deprecated use #qurt_pimutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not being used, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing. + + If a thread performs a lock operation on a recursive mutex that is already being used by + another thread, the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_unlock + + @deprecated use #qurt_pimutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_pimutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_pimutex2_lock(). If a call to qurt_pimutex2_lock() would + succeed immediately, this function behaves similarly, and returns 0 for success. + If a call to qurt_pimutex2_lock() would not succeed immediately, this function has + no effect and returns non-zero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_pimutex2_try_lock(qurt_rmutex2_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pipe.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pipe.h new file mode 100755 index 0000000000000..6bdaa044f8640 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pipe.h @@ -0,0 +1,479 @@ +#ifndef QURT_PIPE_H +#define QURT_PIPE_H +/** + @file qurt_pipe.h + @brief Prototypes of the pipe interface API + This is a pipe or message queue + It blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup pipe_types +@{ */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_PIPE_MAGIC 0xF1FEF1FE /**< Magic. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_RAM 0 /**< RAM. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_TCM 1 /**< TCM. */ + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** QuRT pipe data values type. */ +typedef unsigned long long int qurt_pipe_data_t; + +/** QuRT pipe type.*/ +typedef struct { + /** @cond */ + qurt_mutex_t pipe_lock; + qurt_sem_t senders; + qurt_sem_t receiver; + unsigned int size; + unsigned int sendidx; + unsigned int recvidx; + void (*lock_func)(qurt_mutex_t *); + void (*unlock_func)(qurt_mutex_t *); + int (*try_lock_func)(qurt_mutex_t *); + void (*destroy_lock_func)(qurt_mutex_t *); + unsigned int magic; + qurt_pipe_data_t *data; + /** @endcond */ +} qurt_pipe_t; + +/** QuRT pipe attributes type. */ +typedef struct { + /** @cond */ + qurt_pipe_data_t *buffer; + unsigned int elements; + unsigned char mem_partition; + /** @endcond */ +} qurt_pipe_attr_t; + +/** @} */ /* end_addtogroup pipe_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pipe_attr_init + @xreflabel{hdr:qurt_pipe_attr_init} + Initializes the structure that sets the pipe attributes when a pipe is created. + + After an attribute structure is initialized, the individual attributes in the structure are + explicitly set using the pipe attribute operations. + + The attribute structure is assigned the following default values: \n + - buffer -- 0 \n + - elements -- 0 \n + - mem_partition -- #QURT_PIPE_ATTR_MEM_PARTITION_RAM + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_init(qurt_pipe_attr_t *attr) +{ + attr->buffer = NULL; + attr->elements = 0; + attr->mem_partition = QURT_PIPE_ATTR_MEM_PARTITION_RAM; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer + @xreflabel{sec:qurt_pipe_attr_set_buffer} + Sets the pipe buffer address attribute.\n + Specifies the base address of the memory area to use for the data buffer of a pipe. + + The base address and size (Section @xref{sec:qurt_pipe_attr_set_elements}) specify the + memory area used as a pipe data buffer. The user is responsible for allocating the + memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t \n + #qurt_pipe_data_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] buffer Pointer to the buffer base address. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer(qurt_pipe_attr_t *attr, qurt_pipe_data_t *buffer) +{ + attr->buffer = buffer; +} + +/**@ingroup func_qurt_pipe_attr_set_elements + @xreflabel{sec:qurt_pipe_attr_set_elements} + Specifies the length of the memory area to use for the data buffer of a pipe. + + The length is expressed in terms of the number of 64-bit data elements that + can be stored in the buffer. + + The base address (Section @xref{sec:qurt_pipe_attr_set_buffer}) and size specify + the memory area used as a pipe data buffer. The user is responsible for + allocating the memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] elements Pipe length (64-bit elements). + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_elements(qurt_pipe_attr_t *attr, unsigned int elements) +{ + attr->elements = elements; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer_partition + @xreflabel{sec:qurt_pipe_attr_set_buffer_partition} + Specifies the memory type where a pipe's buffer is allocated. + Allocate pipes in RAM or TCM/LPM. + + @note1hang If a pipe is specified as allocated in TCM/LPM, it must be created + with the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] mem_partition Pipe memory partition. Values: \n + - #QURT_PIPE_ATTR_MEM_PARTITION_RAM -- Pipe resides in RAM \n + - #QURT_PIPE_ATTR_MEM_PARTITION_TCM -- Pipe resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer_partition(qurt_pipe_attr_t *attr, unsigned char mem_partition) +{ + attr->mem_partition = mem_partition; +} + +/**@ingroup func_qurt_pipe_create + Creates a pipe.\n + Allocates a pipe object and its associated data buffer, and initializes the pipe object. + + @note1hang The buffer address and size stored in the attribute structure specify how the + pipe data buffer is allocated. + + @note1cont If a pipe is specified as allocated in TCM/LPM, it must be created + using the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the created pipe object. + @param[in] attr Pointer to the attribute structure used to create the pipe. + + @return + #QURT_EOK -- Pipe created. \n + #QURT_EFAILED -- Pipe not created. \n + #QURT_ENOTALLOWED -- Pipe cannot be created in TCM/LPM. + + @dependencies + None. + */ +int qurt_pipe_create(qurt_pipe_t **pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_init + Initializes a pipe object using an existing data buffer. + + @note1hang The buffer address and size stored in the attribute structure must + specify a data buffer that the user has already allocated. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the pipe object to initialize. + @param[in] attr Pointer to the pipe attribute structure used to initialize the pipe. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Failure. + + @dependencies + None. + */ +int qurt_pipe_init(qurt_pipe_t *pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_destroy + @xreflabel{sec:qurt_pipe_destroy} + Destroys the specified pipe. + + @note1hang Pipes must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel. + Pipes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_destroy(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_delete + Deletes the pipe.\n + Destroys the specified pipe (Section @xref{sec:qurt_pipe_destroy}) and deallocates the pipe object and its + associated data buffer. + + @note1hang Delete pipes only if they were created using qurt_pipe_create + (and not qurt_pipe_init). Otherwise the behavior of QuRT is undefined. \n + @note1cont Pipes must be deleted when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Pipes must not be deleted while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_delete(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_send + Writes a data item to the specified pipe. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + None. + + @dependencies + None. +*/ +void qurt_pipe_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_receive + Reads a data item from the specified pipe. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + Integer containing the 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_receive(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_try_send + Writes a data item to the specified pipe (without suspending the thread if the pipe is full).\n + + If a thread writes to a full pipe, the operation returns immediately with success set to -1. + Otherwise, success is always set to 0 to indicate a successful write operation. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + 0 -- Success. \n + -1 -- Failure (pipe full). + + @dependencies + None. +*/ +int qurt_pipe_try_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_try_receive + Reads a data item from the specified pipe (without suspending the thread if the pipe is + empty).\n + If a thread reads from an empty pipe, the operation returns immediately with success set + to -1. Otherwise, success is always set to 0 to indicate a successful read operation.\n + + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[out] success Pointer to the operation status result. + + @return + Integer containing a 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_try_receive(qurt_pipe_t *pipe, int *success); + +/**@ingroup func_qurt_pipe_receive_cancellable + Reads a data item from the specified pipe (with suspend), cancellable. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + The operation is cancelled if the user process of the calling thread is killed, + or if the calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] result Pointer to the integer containing the 64-bit data item from pipe. + + @return + #QURT_EOK -- Receive completed. \n + #QURT_ECANCEL -- Receive canceled. \n + #QURT_EDESTROY -- Receive destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_receive_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t *result); + +/**@ingroup func_qurt_pipe_send_cancellable + @xreflabel{hdr:qurt_pipe_send_cancellable} + Writes a data item to the specified pipe (with suspend), cancellable. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + The operation is canceled if the user process of the calling thread is killed, or if the + calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] data Data item to write. + + @return + #QURT_EOK -- Send completed. \n + #QURT_ECANCEL -- Send canceled. \n + #QURT_EDESTROY -- Send destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_send_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_is_empty + Returns a value indicating whether the specified pipe contains any data. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + 1 -- Pipe contains no data. \n + 0 -- Pipe contains data. + + @dependencies + None. +*/ +int qurt_pipe_is_empty(qurt_pipe_t *pipe); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIPE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmem_manager.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmem_manager.h new file mode 100755 index 0000000000000..8c8da985228b9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmem_manager.h @@ -0,0 +1,82 @@ +#ifndef QURT_PMEM_MANAGER_H +#define QURT_PMEM_MANAGER_H +/** + @file qurt_pmem_manager.h + Prototypes of kernel physical memory manager APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* physical memory API return error code */ +#define QURT_PMEM_SUCCESS 0 +#define QURT_PMEM_NO_PRIV 1 +#define QURT_PMEM_RETRY 2 +#define QURT_PMEM_OVERLAP 3 +#define QURT_PMEM_NOT_EXIST 4 +#define QURT_PMEM_INIT_FAILURE 5 +#define QURT_PMEM_OUTSTANDING_MAPPING 6 +#define QURT_PMEM_GENERIC_FAILURE 7 +#define QURT_PMEM_ENTRY_FOUND 8 +#define QURT_PMEM_REACH_END 9 +#define QURT_PMEM_UNCLAIMED 10 +#define QURT_PMEM_ALREADY_CLAIMED 11 + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_pmem_acquire + Acquire the ownership of a specific physical memory region. + + @note1hang The ownership will be the caller + + @param[in] ppage Starting physical page number + @param[in] pnum Number of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_OVERLAP -- The whole or part of the range has been owned \n + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. +*/ +int qurt_pmem_acquire(unsigned int ppage, unsigned int pnum); + +/**@ingroup func_qurt_pmem_release + Release the ownership of a specific physical memory region. + + @param[in] ppage The start of physical page number + @param[in] pnum The numbers of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_NOT_EXIST -- The physical memory range is not usable. \n + #QURT_PMEM_OUTSTANDING_MAPPING -- There is outstanding mapping in this range + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. + */ +int qurt_pmem_release(unsigned int ppage, unsigned int pnum); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMEM_MANAGER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmu.h new file mode 100755 index 0000000000000..73ea8eba04abf --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_pmu.h @@ -0,0 +1,121 @@ +#ifndef QURT_PMU_H +#define QURT_PMU_H +/** + @file qurt_pmu.h + Prototypes of pipe interface API. + A pipe or message queue blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_pmu_set + Sets the value of the specified PMU register. + + @note1hang Setting PMUEVTCFG automatically clears the PMU registers PMUCNT0 + through PMUCNT3. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @param[in] reg_value Register value. + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_set (int reg_id, unsigned int reg_value); + +/**@ingroup func_qurt_pmu_get + Gets the PMU register.\n + Returns the current value of the specified PMU register. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @return + Integer -- Current value of the specified PMU register. + + @dependencies + None. + */ +unsigned int qurt_pmu_get (int reg_id); + +/**@ingroup func_qurt_pmu_enable + Enables or disables the Hexagon processor PMU. + Profiling is disabled by default. + + @note1hang Enabling profiling does not automatically reset the count registers -- this must + be done explicitly before starting event counting. + + @param[in] enable Performance monitor. Values: \n + - 0 -- Disable performance monitor \n + - 1 -- Enable performance monitor @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_enable (int enable); + +/**@ingroup func_qurt_pmu_get_pmucnt + Reads PMU counters in a single trap. + + @param[out] buf Pointer to a buffer to save values read from PMU counters. + buffer size should be at least 32 bytes to read all eight PMU counters. + + @return + #QURT_EOK -- Successful read.\n + #QURT_EFATAL -- Failure. + + @dependencies + None. + */ +int qurt_pmu_get_pmucnt (void * buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMU_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_power.h new file mode 100755 index 0000000000000..2ee4d29a73976 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_power.h @@ -0,0 +1,140 @@ +#ifndef QURT_POWER_H +#define QURT_POWER_H +/** + @file qurt_power.h + @brief Prototypes of power API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/*============================================================================= + + EDIT HISTORY FOR MODULE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + +when who what, where, why +-------- --- ------------------------------------------------------------ +03/03/11 op Add header file +12/12/12 cm (Tech Pubs) Edited/added Doxygen comments and markup. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +/**@ingroup func_qurt_power_shutdown_fail_exit + Returns from Power Collapse mode when power collapse cannot proceed. + + This function unmasks the global interrupt. This operation is used only when the thread is + recovering from a failed power collapse operation (Section @xref{sec:powerShutdownEnter}). + + @return + #QURT_EOK -- Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_fail_exit qurt_power_exit + +/**@ingroup func_qurt_power_shutdown_exit + Undoes state changes made preparing for power collapse.\n + This function unmasks the global interrupts. + + @return + #QURT_EOK --Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_exit qurt_power_exit +/**@endcond */ + +/**@ingroup func_qurt_system_ipend_get + Gets the IPEND register.\n + + @note1hang Returns the current value of the Hexagon processor IPEND register. The return value + is a mask value that identifies the individual interrupts that are pending. \n + + @note1hang The bit order of the mask value is identical to the order defined for the IPEND register. A + mask bit value of 1 indicates that the corresponding interrupt is pending, and 0 indicates that the + corresponding interrupt is not pending. \n + + @return + Return the IPEND register value. + + @dependencies + None. + */ +unsigned int qurt_system_ipend_get (void); + + +/**@ingroup func_qurt_system_vid_get + Gets the VID register. \n + + @note1hang Returns the current value of the Hexagon processor VID register. The return value is + the vector number of a second-level interrupt that has been accepted by the Hexagon + processor core.\n + + @return + Return the VID register value that is the L2 VIC interrupt number accepted by the processor. + Valid range is 0 to 1023. + + @dependencies + None. + */ +unsigned int qurt_system_vid_get(void); + +/**@ingroup func_qurt_power_shutdown_get_pcycles + Gets the number of power collapses and processor cycles for entering and exiting most recent + power collapse. + + @note1hang If no power collapse has occured yet, processor cycle numbers are zero. + + @param[out] enter_pcycles Number of processor cycles for entering most + recent power collapse. + @param[out] exit_pcycles Number of processor cycles for exiting most + recent power collapse. + @return + Zero -- No power collapses have occurred. \n + Nonzero -- Number of power collapses that have occurred since + the processor was reset. + + @dependencies + None. + */ +int qurt_power_shutdown_get_pcycles( unsigned long long *enter_pcycles, unsigned long long *exit_pcycles ); + +/**@ingroup func_qurt_system_tcm_set_size + Set size of TCM to save during full power collapse. + + @note1hang The size aligns to 32 bytes. If size passed is greater than the maximum size defined in + XML, the size is truncated to the size defined in XML. + + @param[in] new_size Size of TCM to save. + + @return + Zero -- Size successfully set \n + -1 -- Size of 0 passed + + @dependencies + None. + */ +int qurt_system_tcm_set_size(unsigned int new_size); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_POWER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_printf.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_printf.h new file mode 100755 index 0000000000000..a775d8a815918 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_printf.h @@ -0,0 +1,44 @@ +#ifndef QURT_PRINTF_H +#define QURT_PRINTF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file qurt_printf.h + Prototypes of printf API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup chapter_function_tracing +@{ */ + +int qurt_printf(const char* format, ...); + +int qurt_vprintf(const char* format, va_list args); + +/** @} */ /* end_addtogroup chapter_function_tracing */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PRINTF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_process.h new file mode 100755 index 0000000000000..0df9ddc2d4a70 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_process.h @@ -0,0 +1,995 @@ +#ifndef QURT_PROCESS_H +#define QURT_PROCESS_H +/** + @file qurt_process.h + @brief Prototypes of QuRT process control APIs. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2009-2013, 2021-2023 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_callback.h" +#include "qurt_consts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup process_types +@{ */ +#define QURT_PROCESS_ATTR_NAME_MAXLEN QURT_MAX_NAME_LEN /**< Maximum length of the process name. */ +#define QURT_PROCESS_ATTR_BIN_PATH_MAXLEN 128 /**< Maximum length of the path of binary/ELF for this process. */ +#define QURT_PROCESS_ATTR_CAP_MAXLEN 128 /**< Maximum length for a resource name. */ + +/** QuRT process capability wildcard strings */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_ALL "ALLOW_ALL" /**< Capability wild-card for full access */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_NONE "ALLOW_NONE" /**< Capability wild-card for no access */ + +/** QuRT process capability states */ +#define QURT_PROCESS_ATTR_CAP_ENABLED 0x1 /**< Capability enabled*/ +#define QURT_PROCESS_ATTR_CAP_DISABLED 0x0 /**< Capability disabled*/ + +/* QuRT process thread attributes. */ +#define QURT_PROCESS_DEFAULT_CEILING_PRIO 0 /**< Default ceiling priority of the threads in the new process. */ +#define QURT_PROCESS_DEFAULT_MAX_THREADS -1 /**< Default number of threads in the new process. + -1 indicates that the limit is set to the maximum supported by the system. */ + +/* QuRT process flags. */ +#define QURT_PROCESS_SUSPEND_ON_STARTUP (1U) /**< Suspend the new processes just before calling main(). */ +#define QURT_PROCESS_NON_SYSTEM_CRITICAL (1u << 1) /**< Starts the new process as non system-critical. */ +#define QURT_PROCESS_ISLAND_RESIDENT (1u << 2) /**< Process is island resident. */ +#define QURT_PROCESS_RESTARTABLE (1u << 3) /**< Indicates that the process is restartable */ +#define QURT_PROCESS_UNTRUSTED (1u << 7) /**< Starts the new process as unsigned process. */ + +/* QuRT process debugging session status.*/ +#define QURT_DEBUG_NOT_START 0 /**< Debug is not started. */ +#define QURT_DEBUG_START 1 /**< Debug has started. */ + +/** Process Suspend Options */ +#define QURT_PROCESS_SUSPEND_DEFAULT 0 + +/** Process Resume Options */ +#define QURT_PROCESS_RESUME_DEFAULT 0 + + +/* QuRT process types. */ +typedef enum { + QURT_PROCESS_TYPE_RESERVED, /**< Process type is reserved. \n */ + QURT_PROCESS_TYPE_KERNEL, /**< Kernel process. \n*/ + QURT_PROCESS_TYPE_SRM, /**< SRM process. \n*/ + QURT_PROCESS_TYPE_SECURE, /**< Secure process. \n*/ + QURT_PROCESS_TYPE_ROOT, /**< Root process. \n*/ + QURT_PROCESS_TYPE_USER, /**< User process. */ +}qurt_process_type_t; + +/** QuRT process callback types. */ +typedef enum { + QURT_PROCESS_DUMP_CB_ROOT, /**< Register the callback that executes in the + root process context. \n */ + QURT_PROCESS_DUMP_CB_ERROR, /**< Register the user process callback that is + called after threads in the process are frozen. \n */ + QURT_PROCESS_DUMP_CB_PRESTM, /**< Register the user process callback that is + called before threads in the process are frozen. \n*/ + QURT_PROCESS_DUMP_CB_MAX /**< Reserved for error checking. */ +}qurt_process_dump_cb_type_t; + +/** QuRT process dump attributes. */ +typedef struct _qurt_pd_dump_attr{ + /** @cond */ + unsigned int enabled; /**< Process dump is enabled. */ + const char *path; /**< Process dump path. */ + unsigned int path_len; /**< Length of process dump path. */ + /** @endcond */ +}qurt_pd_dump_attr_t; + +/** QuRT process capability resource type */ +enum qurt_process_cap_type_t { + QURT_PROCESS_CAP_TYPE_NUM_ENTRIES=0, /**< Number of entries in the capability structure*/ + QURT_PROCESS_CAP_TYPE_DRIVER=1, /**< Driver resource */ + QURT_PROCESS_CAP_TYPE_MAX /**< Maximum identifier */ +}; + +/** QuRT process capability structure */ +typedef struct _qurt_capability { + enum qurt_process_cap_type_t type; /**< Resource type */ + char name[QURT_PROCESS_ATTR_CAP_MAXLEN]; /**< Resource name*/ + unsigned long long cap; /**< Capabilities allowed for this resource */ +}qurt_capability_t; + +/** QuRT process attributes. */ +typedef struct _qurt_process_attr { + /** @cond */ + char name[QURT_PROCESS_ATTR_NAME_MAXLEN]; /**< Name of the new process. */ + char path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the binary for the new process. */ + char dtb_path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the DTB ELF for the new process. */ + int flags; /**< Flags as indicated by QuRT process flags. */ + unsigned int sw_id; /**< Software ID of the process be load. */ + unsigned sid; /**< Stream ID of the process being spawned. */ + unsigned max_threads; /**< Maximum number of threads that the new process can create. */ + unsigned short ceiling_prio; /**< Maximum priority at which threads can be + created by new process. */ + qurt_process_type_t type; /**< Process type as indicated by + #qurt_process_type_t. */ + qurt_pd_dump_attr_t dump_attr; /**< Process dump attributes for the new process + as indicated by #qurt_pd_dump_attr_t. */ + qurt_capability_t *capabilities; /**< Pointer to array of structure of type + qurt_capability_t */ + /** @endcond */ +} qurt_process_attr_t; + +/** @} */ /* end_addtogroup process_types */ + +/*============================================================================= +FUNCTIONS +=============================================================================*/ + /** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_create + Creates a process with the specified attributes, and starts the process. + + The process executes the code in the specified executable ELF file. + + @datatypes + #qurt_process_attr_t + + @param[out] attr Accepts an initialized process attribute structure, which specifies + the attributes of the created process. + + @return + Postive return value Indicates Process ID. + Negative return value Indicates any of follwoing error, + #-QURT_EPRIVILEGE -- Caller does not have privilege for this operation \n + #-QURT_EMEM -- Not enough memory to perform the operation \n + #-QURT_EFAILED -- Operation failed \n + #-QURT_ENOTALLOWED -- Operation not allowed \n + #-QURT_ENOREGISTERED -- Not registered \n + #-QURT_ENORESOURCE -- Resource exhaustion \n + #-QURT_EINVALID -- Invalid argument value + #QURT_EFATAL -- attr is NULL + + @dependencies + None. +*/ +int qurt_process_create (qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_get_id + Returns the process identifier for the current thread. + + @return + None. + + @dependencies + Process identifier for the current thread. +*/ +int qurt_process_get_id (void); +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_get_uid + Returns the user identifier for the current thread. + + @return + None. + + @dependencies + User identifier for the current thread. +*/ +int qurt_process_get_uid (void); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_init + Initializes the structure that sets the process attributes when a thread is created. + + After an attribute structure is initialized, the individual attributes in the structure can + be explicitly set using the process attribute operations. + + Table @xref{tbl:processAttrDefaults} lists the default attribute values set by the initialize + operation. + + @inputov{table_process_attribute_defaults} + + @datatypes + #qurt_process_attr_t + + @param[out] attr Pointer to the structure to initialize. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_process_attr_init (qurt_process_attr_t *attr) +{ + attr->name[0] = '\0'; + attr->path[0] = '\0'; + attr->dtb_path[0] = '\0'; + attr->flags = 0; + attr->sw_id = 0; + attr->sid = 0; + attr->max_threads = (unsigned)QURT_PROCESS_DEFAULT_MAX_THREADS; + attr->ceiling_prio = QURT_PROCESS_DEFAULT_CEILING_PRIO; + attr->type = QURT_PROCESS_TYPE_RESERVED; + attr->dump_attr.enabled = 0; + attr->dump_attr.path = NULL; + attr->dump_attr.path_len = 0; + attr->capabilities = NULL; +} + +/**@ingroup func_qurt_process_attr_set_executable + Sets the process name in the specified process attribute structure. + + Process names identify process objects that are already + loaded in memory as part of the QuRT system. + + @note1hang Process objects are incorporated into the QuRT system at build time. + + @note1hang Maximum length of name string is limited to QURT_PROCESS_ATTR_NAME_MAXLEN - 1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] name Pointer to the process name. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_executable (qurt_process_attr_t *attr, const char *name); + +/**@ingroup func_qurt_process_attr_set_binary_path + Sets the binary path for the process loading in the specified process attribute structure. + + Path specifies the binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_binary_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_dtb_path + Sets the DTB binary path for the process loading in the specified process attribute structure. + + Path specifies the DTB binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_dtb_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_flags +Sets the process properties in the specified process attribute structure. +Process properties are represented as defined symbols that map into bits +0 through 31 of the 32-bit flag value. Multiple properties are specified by OR'ing +together the individual property symbols. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] flags QURT_PROCESS_NON_SYSTEM_CRITICAL Process is considered as non system-critical. + This attribute will be used by error services, + to decide whether to kill user pd or whole subsystem. + QURT_PROCESS_ISLAND_RESIDENT Process will be marked as island resident. + QURT_PROCESS_RESTARTABLE Process will be marked as restartable. + QURT_PROCESS_UNTRUSTED Process will be marked as unsigned process. +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_flags (qurt_process_attr_t *attr, int flags) +{ + attr->flags = flags; +} +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_sid +Sets the process streamID in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sid streamID to set for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sid (qurt_process_attr_t *attr, unsigned sid) +{ + attr->sid = sid; +} +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_set_max_threads +Sets the maximum number of threads allowed in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] max_threads Maximum number of threads allowed for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_max_threads (qurt_process_attr_t *attr, unsigned max_threads) +{ + attr->max_threads = max_threads; +} + +/**@ingroup func_qurt_process_attr_set_sw_id +Sets the software ID of the process to load in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sw_id Software ID of the process, used in authentication. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sw_id(qurt_process_attr_t *attr, unsigned int sw_id) +{ + attr->sw_id = sw_id; +} + +/**@ingroup func_qurt_process_attr_set_ceiling_prio +Sets the highest thread priority allowed in the specified process attribute structure. +Refer qurt_thread.h for priority ranges. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] prio Priority. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_ceiling_prio (qurt_process_attr_t *attr, unsigned short prio) +{ + attr->ceiling_prio = prio; +} +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_dump_status +Sets the process domain dump-enabled field in the process domain dump attributes. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] enabled 1 -- Process domain dump is collected \n + 0 -- Process domain dump is not collected + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_status(qurt_process_attr_t *attr, unsigned int enabled) +{ + attr->dump_attr.enabled = enabled; +} + +/**@ingroup func_qurt_process_attr_set_dump_path +Sets the process domain dump path and type. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] path Path where the process domain dumps must be saved. +@param[in] path_len Length of the path string. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_path(qurt_process_attr_t *attr, const char *path, int path_len) +{ + attr->dump_attr.path = path; + attr->dump_attr.path_len = (unsigned int)path_len; +} + +/**@ingroup func_qurt_process_attr_set_capabilities +Sets list of capabilities available to this process. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] capabilities Pointer to array of structures of type qurt_capability_t defining + resources and capabilites + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_capabilities(qurt_process_attr_t *attr, qurt_capability_t *capabilities) +{ + attr->capabilities = capabilities; +} + +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_cmdline_get +Gets the command line string associated with the current process. +The Hexagon simulator command line arguments are retrieved using +this function as long as the call is made +in the process of the QuRT installation, and with the +requirement that the program runs in a simulation environment. + +If the function modifies the provided buffer, it zero-terminates +the string. It is possible that the function does not modify the +provided buffer, so the caller must set buf[0] to a NULL +byte before making the call. A truncated command line is returned when +the command line is longer than the provided buffer. + +@param[in] buf Pointer to a character buffer that must be filled in. +@param[in] buf_siz Size (in bytes) of the buffer pointed to by the buf argument. + +@return +None. + +@dependencies +None. +*/ +void qurt_process_cmdline_get(char *buf, unsigned buf_siz); + +/**@ingroup func_qurt_process_get_thread_count +Gets the number of threads present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of threads in the process indicated by PID, if positive value is obtained +Negative error code if failed include: + QURT_EFATAL - Invalid PID + -QURT_ENOTALLOWED - Current process doesnt have access to target process indicated by PID + +@dependencies +None. +*/ +int qurt_process_get_thread_count(unsigned int pid); + +/**@ingroup func_qurt_process_get_thread_ids +Gets the thread IDs for a process indicated by PID. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a user passed buffer that must be filled in with thread IDs. +@param[in] thread_num Number of thread IDs requested. + +@return +#QURT_EOK - Success +#QURT_EFATAL - Failed, ptr is NULL + +@dependencies +None. + */ +int qurt_process_get_thread_ids(unsigned int pid, unsigned int *ptr, unsigned thread_num); +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_dump_get_mem_mappings_count +Gets the number of mappings present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of mappings for the process indicated by the PID. + +@dependencies +None. +*/ +int qurt_process_dump_get_mem_mappings_count(unsigned int pid); + +/**@ingroup func_qurt_process_dump_get_mappings +Gets the mappings for a specified PID. + +@note1hang This API skips device type mappings or mappings created by setting the #QURT_PERM_NODUMP attribute. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a buffer that must be filled in with mappings. +@param[in] count Count of mappings requested. + +@return +Number of mappings filled in the buffer passed by the user. + +@dependencies +None. +*/ +int qurt_process_dump_get_mappings(unsigned int pid, unsigned int *ptr, unsigned count); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_get +Gets the attributes of the process with which it was created. + +@datatypes +#qurt_process_attr_t + +@param[in] pid PID of the process for which the information is required. +@param[in,out] attr Pointer to the user allocated attribute structure. + +@return +#QURT_EOK - Success +#QURT_INVALID - Invalid PID +#QURT_EFATAL - attr is NULL + +@dependencies +None. +*/ +int qurt_process_attr_get(unsigned int pid, qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_dump_register_cb +Registers the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information. +@param[in] type Callback type; these callbacks are called in the context of the user process domain: \n + #QURT_PROCESS_DUMP_CB_PRESTM -- Before threads of the exiting process are frozen. \n + #QURT_PROCESS_DUMP_CB_ERROR -- After threads are frozen and captured. \n + #QURT_PROCESS_DUMP_CB_ROOT -- After threads are frozen and captured, and CB_ERROR type of callbacks + are called. +@param[in] priority Priority. + +@return +#QURT_EOK -- Success \n +Other values -- Failure + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_register_cb(qurt_cb_data_t *cb_data, qurt_process_dump_cb_type_t type, unsigned short priority); + +/**@ingroup func_qurt_process_dump_deregister_cb +Deregisters the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information to deregister. +@param[in] type Callback type. + +@return +#QURT_EOK -- Success.\n +Other values -- Failure. + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_deregister_cb(qurt_cb_data_t *cb_data,qurt_process_dump_cb_type_t type); + +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_set_rtld_debug +Sets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in] address rtld_debug address. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_set_rtld_debug(unsigned int pid,unsigned int address); + +/**@ingroup func_qurt_process_get_rtld_debug +Gets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in,out] address Pointer to the user passed address in which the rtld_debug address must be returned. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_get_rtld_debug(unsigned int pid,unsigned int *address); +/** @endcond */ +/**@ingroup func_qurt_process_exit +Exits the current user process with an exit code. + +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exit(int exitcode); + +/**@ingroup func_qurt_process_kill +Kills the process represented by the PID with the exit code. + +@param[in] pid PID of the process to kill. +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_kill(int pid, int exitcode); + + +/**@ingroup func_qurt_debugger_register_process +Registers the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. +@param[in] adr Address. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_register_process(int pid, unsigned int adr); + + +/**@ingroup func_qurt_debugger_deregister_process +Deregister the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_deregister_process(int pid); + +/**@ingroup func_qurt_process_exec_callback +Executes callbacks in the user process as indicated by the client_handle argument. + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] callback_fn Callback function to execute. +@param[in] stack_base Stack address to use. +@param[in] stack_size Stack size. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exec_callback(int client_handle, + unsigned callback_fn, + unsigned stack_base, + unsigned stack_size); + +/**@ingroup func_qurt_process_get_pid +Gets the process ID of the process that the client_handle argument represents. + +@note1hang This API is not supported for unsigned PD, For unsigned PD use qurt_process_get_id() + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] pid Pointer to the address to store the PID. + +@return +#QURT_EOK -- Success +#QURT_EFATAL -- pid pointer passed as NULL + +@dependencies +None. +*/ +int qurt_process_get_pid(int client_handle, int * pid); + +/**@ingroup func_qurt_process_get_dm_status +Gets the debugging session status on the process represented by the pid argument. + +@param[in] pid Process ID +@param[in,out] status Address to store the status: \n + #QURT_DEBUG_NOT_START \n + #QURT_DEBUG_START + +@return +#QURT_EOK - Success \n +#QURT_EINVALID - Error + +@dependencies +None. +*/ +int qurt_process_get_dm_status( unsigned int pid, unsigned int *status); + + +/**@ingroup func_qurt_process_suspend_threads + Suspends user threads in a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in GuestOS/root process. + After the user threads in the target user process are suspended, they cannot be scheduled to run by the kernel + until they resume later. + + This function has one optional argument with one default option. + #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + This function call is a synchronous call, the function returns after the relevant threads are + completely suspended. + + If some user threads in the target user process are set as non-suspendable, this function call does + not suspend these threads. + + If the target user process is already suspended, this function call returns success as the + confirmation on the user process suspending. + + QuRT debugger monitor threads in the target user process are non-suspendable, this function call does + not suspend the threads. + + If the target user process is a secure user process, or a CPZ process, this function call returns error + without suspending the target user process. + + If a user thread in the target user process runs in the guest OS/root process via a QDI call, this function call + does not suspend the thread in the guest OS, but instead marks the thread as pending-suspend. The thread is suspended + when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success while the user thread can be running in GuestOS, and is suspended + when exiting the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Dfault option #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid process_id input \n + #QURT_ENOTALLOWED -- Failure because the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_suspend_threads (unsigned int process_id, unsigned int option); + + +/**@ingroup func_qurt_process_resume_threads + Resumes a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in the guest OS/root process. + After the user threads in the target user process resume, the kernel scheduler + can schedule the user threads to run based on their thread priorities. + + This function has an optional argument, #QURT_PROCESS_RESUME_DEFAULT, which + resumes user threads in the target user process. + + This is an asynchronous function, it returns after the kernel moves the user thread from + suspended state to runnable state. The threads are scheduled to run based on their thread priorities. + + This function call does not resume threads in the target user process that have been set as non-resumable. + + If the target user process have already resumed, this function call confirms that the user process resumes + by returning success. + + If the target user process is a secure user process or a CPZ process, this function call returns an error without + resuming operation. + + If user threads in the target user process run in the guest OS/root process via QDI call, this function + call clears the mark of suspend-pending on these threads, so that the threads are be suspended when it exits + the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Default option #QURT_PROCESS_RESUME_DEFAULT resumes user threads in the target user process. + + @return + #QURT_EOK -- Success + #QURT_EINVALID -- Failure because of invalid process_id input. + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_resume_threads (unsigned int process_id, unsigned int option); + +/**@ingroup func_qurt_process_vtcm_window_set + Set a VTCM access window for a process. + The caller thread needs to be in SRM process. + + This is an synchronous function, it ensures all running threads of the process have the requested + window in effect.The requested view for all non-running thread will take in effect when they get + scheduled. + + @param[in] pid Process identifier. + @param[in] enable QURT_VTCM_WINDOW_ENABLE enforces VTCM access window defined by high and low offset. + QURT_VTCM_WINDOW_DISABLE high and low offset is ignored and VTCM access is fully + disabled for the process. + @param[in] high_offset Specifies the high window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT restore high offset to reset value. + @param[in] low_offset Specifies the low window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT restore low offset to reset value. + + @note1hang + when high_offset is set to QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT and low offset is set as + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT full VTCM range is accessible. Access to VTCM is controlled + via MMU mapping for the process. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_set(int pid, unsigned int enable, unsigned int high_offset, unsigned int low_offset); + +/**@ingroup func_qurt_process_vtcm_window_get + Get the VTCM window for a process. + The caller thread needs to be in SRM process. + + + @param[in] pid Process identifier. + @param[out] enable address to store enable status if set + @param[out] high_offset address to return high window offset, in 4K increments, from the base address of the VTCM + @param[out] low_offset address to return low window offset, in 4K increments, from the base address of the VTCM. + + @note1hang + User must first check the value of enable returned before checking high and low offset. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_get(int pid, unsigned int *enable, unsigned int *high_offset, unsigned int *low_offset); + +/**@ingroup func_qurt_process_set_group_config + Enable thread groups in the process with the ceiling priorities setup + + @param[in] process_id Process identifier. + @param[in] group_bitmask 64-bit mask of active thread groups + @param[in] ceiling_priorities array of ceiling priorities for thread group + + @note1hang + This API can only be called by root PD and can only be called once for each process, otherwise it will be + rejected. Group 0 must be enabled in group_bitmask, otherwise QuRT will return error. After this API, all + exisiting threads will be moved to group 0, and if there is any thread's priority higher than ceiling + priority of group 0, it will be lowered to the ceiling value. + Examples 1: + group_bitmask = 0xD7; //'b11010111 + ceiling_priorities[] = {100, 128, 200, 0, 196, 0, 240, 20}; // 0 - does not care + Exmaples 2: + group_mask = 0x5; //'b101 + ceiling_priorities[] = {240, 0, 20}; // 0 - does not care + + + @return + #QURT_EOK -- Success. + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_ENOTALLOWED -- The group has been configured already. + + @dependencies + None. + */ +int qurt_process_set_group_config(unsigned int process_id, unsigned long long group_bitmask, + unsigned char *ceiling_priorities); + + +/**@ingroup func_qurt_process_stid_set + Set the specified stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[in] stid stid to be set + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) if stid needs to set at a process level. + All threads within a process that has default stid (QURT_STID_DEFAULT) will inherit the stid set for a process. + When a non-default group_id is specified, the stid is set only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_set(unsigned int pid, unsigned int group_id , unsigned int stid); + +/**@ingroup func_qurt_process_stid_get + Get the stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[out] Pointer to a variable to return stid + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) to return process-level stid. + When a non-default group_id is specified, the stid is returned only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_get(unsigned int pid, unsigned int group_id , unsigned int *stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_profile.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_profile.h new file mode 100755 index 0000000000000..2a50c461440f6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_profile.h @@ -0,0 +1,98 @@ +#ifndef QURT_PROFILE_H +#define QURT_PROFILE_H +/** + @file qurt_profile.h + QuRT profiling support. + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup profiling_macros +@{ */ +#define QURT_PROFILE_DISABLE 0 /**< Disable profiling. */ +#define QURT_PROFILE_ENABLE 1 /**< Enable profiling. */ + +typedef unsigned int qurt_profile_param_t; + +#define QURT_PROFILE_PARAM_THREAD_READY_TIME 0U /**< Profile thread ready time. */ + +/** @} */ /* end_addtogroup profiling_macros */ + +/** @addtogroup profiling_types + @{ */ +/** Profiling results. */ +typedef union +{ + /** Result associated with #QURT_PROFILE_PARAM_THREAD_READY_TIME. */ + struct + { + unsigned int ticks; /**< Cumulative ticks the thread was ready. */ + } thread_ready_time; + +} qurt_profile_result_t; +/** @} */ /* end_addtogroup profiling_types */ + +/**@ingroup func_qurt_profile_enable2 + * Starts profiling of a specific parameter on a specific thread (as applicable). + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of the thread (if applicable) for which the specified + * paramter must be profiled. + * @param[in] enable #QURT_PROFILE_DISABLE -- disable \n #QURT_PROFILE_ENABLE -- + * enable + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EALREADY -- Measurement already in progress or already stopped \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_enable2 ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + int enable +); + +/**@ingroup func_qurt_profile_get + * Gets the value of the profiling parameter that was previously enabled. + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of thread (if applicable) for which the specified + * profiling paramter must be retrieved. + * @param [out] result Profiling result associated with the parameter for the specified + * thread (if applicable). + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EFAILED -- Operation failed; profiling was not enabled \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_get ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + qurt_profile_result_t * result +); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ptrace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ptrace.h new file mode 100755 index 0000000000000..622304dd92865 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_ptrace.h @@ -0,0 +1,37 @@ +/*============================================================================= + + qurt_ptrace.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SYS_PTRACE_H__ +#define __SYS_PTRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum __ptrace_request +{ + /** + Indicates that the process making this request is requesting to be traced. + */ + PTRACE_TRACEME = 0, + PTRACE_EXT_IS_DEBUG_PERMITTED = 500 +}; + +long ptrace(enum __ptrace_request request, unsigned int pid, void*addr, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_PTRACE_H__ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi.h new file mode 100755 index 0000000000000..705408e5cfc6f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi.h @@ -0,0 +1,185 @@ +#ifndef QDI_H +#define QDI_H + +/** + @file qurt_qdi.h + @brief Prototypes of QuRT Driver Invocation API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_qdi_open + Opens the specified driver for subsequent operations. + qurt_qdi_open() is the primary mechanism by which a driver user can + obtain a QDI handle. The user provides the name of the driver to the + qurt_qdi_open call, and gets back a handle referencing + the named driver. \n + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_open function prototype is not actually defined as a varargs. + + + @param[in] p Driver name. + @param[in] ... Up to nine additional device-specific arguments can be passed as parameters, + and should follow the POSIX open() convention. \n + - flags -- Optional second parameter (POSIX flags), the handle + access requested (read-only, write-only, or read-write, + for instance) and other flags such as whether the call + should create a new device or only open an existing + device. \n + - mode -- Optional third parameter (POSIX mode); permissions to + configure when a new device is created. @tablebulletend + + @return + Negative value -- Error. \n + Non-negative value -- Success, this result value serves as a handle to the + opened driver. + @dependencies + None. + */ +// int qurt_qdi_open(); +#define qurt_qdi_open(p,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN,(p),##__VA_ARGS__) + +#define qurt_qdi_open_dt(p,q,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN_FROM_DT,(p),(q),##__VA_ARGS__) + +/**@ingroup func_qurt_qdi_handle_invoke + Performs a generic driver operation, which (depending on the specified operation) can be + either be one of the predefined operations listed in @xhyperref{tbl:functionMapping,QDI function mapping} + or a driver-specific operation. + The user provides a QDI handle and an integer + method number, along with 0 to 8 optional 32-bit arguments. + The device driver invocation function is invoked with the + same method number and 0 to 8 optional arguments. The + return value from the invocation function is passed back to + the user as the return value of qurt_qdi_handle_invoke. + + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_handle_invoke() function prototype is not actually defined as a + varargs function (and would break if it were defined this way). + + @param[in] h Driver handle. + @param[in] m Integer number for the operation to perform. + @param[in] ... Up to eight optional arguments can be passed to the device driver as operation-specific parameters: \n + arg1 -- First parameter \n + arg2 -- Second parameter \n + arg3 -- Third parameter \n + arg4 -- Fourth parameter \n + arg5 -- Fifth parameter \n + arg6 -- Sixth parameter \n + arg7 -- Seventh parameter \n + arg8 -- Eighth parameter + + @return + Integer value defined by the device driver. \n + -1 -- Error. + + @dependencies + None. + */ +// int qurt_qdi_handle_invoke(); +#define qurt_qdi_handle_invoke(h,m,...) \ + _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__) +#define _QDMHI3(a,b,c) qurt_qdi_qhi3(0,b,c) +#define _QDMHI4(a,b,c,d) qurt_qdi_qhi4(0,b,c,(int)(d)) +#define _QDMHI5(a,b,c,d,e) qurt_qdi_qhi5(0,b,c,(int)(d),(int)(e)) +#define _QDMHI6(a,b,c,d,e,f) qurt_qdi_qhi6(0,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMHI7(a,b,c,d,e,f,g) qurt_qdi_qhi7(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMHI8(a,b,c,d,e,f,g,h) qurt_qdi_qhi8(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMHI9(a,b,c,d,e,f,g,h,i) qurt_qdi_qhi9(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMHI10(a,b,c,d,e,f,g,h,i,j) qurt_qdi_qhi10(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMHI11(a,b,c,d,e,f,g,h,i,j,k) qurt_qdi_qhi11(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMHI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_qdi_qhi12(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) +int qurt_qdi_qhi3(int,int,int); +int qurt_qdi_qhi4(int,int,int,int); +int qurt_qdi_qhi5(int,int,int,int,int); +int qurt_qdi_qhi6(int,int,int,int,int,int); +int qurt_qdi_qhi7(int,int,int,int,int,int,int); +int qurt_qdi_qhi8(int,int,int,int,int,int,int,int); +int qurt_qdi_qhi9(int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi10(int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi11(int,int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi12(int,int,int,int,int,int,int,int,int,int,int,int); + +/**@ingroup func_qurt_qdi_write + Writes data to the specified driver. + A predefined invocation routine for drivers that + support a POSIX-like write functionality. + qqurt_qdi_write(handle, buf, len) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_WRITE, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data to write is stored. + @param[in] len Number of bytes of data to write. + + @return + Non-negative integer -- Number of bytes written. \n + Negative error code -- Write could not take place. + + @dependencies + None. + */ +int qurt_qdi_write(int handle, const void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_read + User-visible API to read data from a QDI handle. + A predefined invocation routine for drivers that + support a POSIX-like read functionality. + qurt_qdi_read(handle, buf, len) is equivalent to: + qurt_qdi_handle_invoke(handle, QDI_READ, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data read is stored. + @param[in] len Number of bytes of data to read. + + @return + Non-negative integer number -- Bytes read. \n + Negative error code -- Read could not take place. + + @dependencies + None. + */ +int qurt_qdi_read(int handle, void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_close + Closes the specified driver, releasing any resources associated with the open driver. + User-visible API to close a QDI handle. + + This API should be called when the user is done using a + QDI-based handle. When this function is called, the driver can release + any resources held and perform other necessary cleanup + operations. qurt_qdi_close(handle) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_CLOSE, handle) + + @param[in] handle Driver handle. + + @return + 0 -- Success.\n + Negative error code -- Failure. + + @dependencies + None. + */ +int qurt_qdi_close(int handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_constants.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_constants.h new file mode 100755 index 0000000000000..4866fada067f0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_constants.h @@ -0,0 +1,193 @@ +#ifndef QDI_CONSTANTS_H +#define QDI_CONSTANTS_H + +/** + @file qurt_qdi_constants.h + @brief Predefined invocation methods for drivers. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Method numbers used for QDI. +|| +|| Intended grouping of method numbers for QDI +|| including future usage: +|| +|| Method 0 should always be unused and not responded to by +|| any driver. +|| Methods 1 and 2 are reserved for name registration and +|| name lookup. +|| Methods 3 through 31 are reserved for POSIX-type operations +|| on open handles. +|| Methods 32 through 127 are reserved for the QDI infrastructure +|| and may be extended in the future to provide standard +|| driver debug services, management services, and system +|| notifications. +|| Methods 128 through 255 are reserved for the use of automatically +|| generated methods such as might be generated by an IDL (interface +|| definition language). The infrastructure may be extended to +|| perform services on these methods based on information provided +|| by the IDL, such as automatic buffer validation, etc. These +|| method numbers should not be used for any "ad hoc" methods. +|| Methods with number >= 256 are "private" method numbers that are +|| outside the scope of the QDI infrastructure. Drivers that want +|| to generate and consume their own "ad hoc" methods are free to +|| use these method numbers as they wish. The infrastructure does +|| not generate these method numbers or respond to them, but +|| passes them on unmolested. +|| +|| All driver implementations *should* return a value of +|| -1 when called with an unsupported method. The standard error +|| return value for POSIX APIs is -1, so we emulate that behavior +|| here. +*/ +/** @cond */ +#define QDI_UNUSED 0 +#define QDI_DEVNAME_REGISTER 1 +#define QDI_OPEN 2 +#define QDI_CLOSE 3 +#define QDI_READ 4 +#define QDI_WRITE 5 +#define QDI_IOCTL 6 +#define QDI_MMAP 7 +#define QDI_OS_FILEOPEN 8 +#define QDI_FLEN 9 +#define QDI_UNLINK 10 +#define QDI_FTELL 22 +#define QDI_SEEK 23 +#define QDI_FSTAT 24 + +#define QDI_FSNAME_REGISTER 150 +#define QDI_FS_OPEN 151 +#define QDI_MMAP2 153 +#define QDI_MPROTECT2 154 +#define QDI_MUNMAP2 155 + +#define QDI_CLIENT_HANDLE_OBJREF_GET 10 + +#define QDI_OS_PROCESS_LOAD 12 +#define QDI_OS_PROCESS_CHOOSE_ASID 13 + +#define QDI_OS_SET_GP 26 +#define QDI_CLIENT_HANDLE_CALLBACK 27 + +#define QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T 19 //reused +#define QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T 80 +#define QDI_CLIENT_HANDLE_HANDLE_RELEASE 81 +#define QDI_CLIENT_HANDLE_COPY_FROM_USER 82 +#define QDI_CLIENT_HANDLE_COPY_TO_USER 83 +#define QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE 86 +#define QDI_CLIENT_HANDLE_SAFE_CACHE_OPS 87 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK 41 +#define QDI_CLIENT_HLOSPOOL_INFO_GET 90 +#define QDI_CLIENT_HLOSPOOL2_INFO_GET 96 + +#define QDI_CLIENT_PID 44 +#define QDI_CLIENT_ASID QDI_CLIENT_PID + +#define QDI_OS_CLIENT_INFO_GET 48 + +#define QDI_OS_MEM_LOOKUP_PHYSADDR 57 + +#define QDI_OS_THREAD_ITERATOR_CREATE 68 +#define QDI_OS_THREAD_ITERATOR_NEXT 69 + +#define QDI_OS_SYSENV 78 + +#define QDI_REGION_USERMALLOC_INIT 180 // This method is for generic handle + + +#define QDI_CLIENT_HANDLE_USER_MALLOC 84 +#define QDI_CLIENT_HANDLE_USER_FREE 85 + +#define QDI_SIGNAL_GROUP_SIGNAL_CREATE 96 +#define QDI_SIGNAL_GROUP_WAIT 98 +#define QDI_SIGNAL_GROUP_POLL 99 +#define QDI_SIGNAL_SET 96 +#define QDI_SIGNAL_CLEAR 97 +#define QDI_SIGNAL_WAIT 98 +#define QDI_SIGNAL_POLL 99 + +#define QDI_OS_WAIT_FOR_MAIN_REAPER 104 + +#define QDI_CLIENT_HANDLE_REFPROXY_INSTALL 105 +#define QDI_CLIENT_HANDLE_REFPROXY_ADD 106 +#define QDI_CLIENT_HANDLE_REFPROXY_REMOVE 107 + +#define QDI_CLIENT_HANDLE_DETACH 116 + +#define QDI_OS_RESERVED1 139 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK2 142 + +#define QDI_DT_REGISTER 158 +#define QDI_OPEN_DEVICE 159 +#define QDI_OPEN_FROM_DT 160 + +#define QDI_PRIVATE 256 /* Method numbers beginning at 256 + are private method numbers, which + are device-specific and available + for use by device implementors. */ +/* +|| Permission bitmasks for use with qurt_qdi_lock_buffer(). +|| +|| Make sure these match with permission values from qurt_perm_t. +*/ +/** @endcond */ + +/** @addtogroup driver_support_constants +@{ */ +#define QDI_PERM_W 2 /**< Write access. */ +#define QDI_PERM_R 1 /**< Read access. */ +#define QDI_PERM_RW (QDI_PERM_R | QDI_PERM_W) /**< Read/write access. */ + +#define QDI_HANDLE_LOCAL_CLIENT 3 /**< Local client. */ +#define QDI_HANDLE_GENERIC 4 /**< Generic. */ + +#define QDI_REFCNT_BASE 0x510000 /**< */ +#define QDI_REFCNT_MAXED 0x51FFFD /**< */ +#define QDI_REFCNT_INIT 0x51FFFE /**< Driver object is temporary and is eventually deleted.*/ +#define QDI_REFCNT_PERM 0x51FFFF /**< Driver object is permanent and is never deleted. */ +/** @} */ /* end_addtogroup driver_support_constants */ + +/** @cond */ +/* +|| Flags used by process loaders. +*/ + +#define QDI_OS_PROCESS_FLAGS_ISLAND_RESIDENT 0x1 /* Set this flag to request the loaded process + to have island residency. */ +#define QDI_OS_PROCESS_FLAGS_ROOT_RESIDENT 0x2 /* Set this flag to request the loaded process + to have root residency, for example, DL Pager. */ +/* +|| Constants used for qurt_event register API, type field. +*/ + +#define QURT_PROCESS_EXIT 1 + +/* +|| Constants used by QDI extensions. +*/ + +#define QURT_QDI_SINGLETON_TYPE_TRUE 0 +#define QURT_QDI_SINGLETON_TYPE_FALSE 1 +#define QURT_QDI_SINGLETON_TYPE_PER_PROCESS 2 +/** @endcond */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QDI_CONSTANTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_driver.h new file mode 100755 index 0000000000000..e044e25f1bb72 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_driver.h @@ -0,0 +1,868 @@ +#ifndef QURT_QDI_DRIVER_H +#define QURT_QDI_DRIVER_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2018, 2019-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "stddef.h" +#include "qurt_qdi.h" +#include "qurt_types.h" +#include "qurt_callback.h" +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" +#include "qurt_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| This gives the canonical form for the arguments to a QDI +|| driver invocation function. The arguments are as follows: +|| +|| int client_handle (R0) QDI handle that represents the client +|| that made this QDI request. If the +|| client is remote, this is a +|| variable handle; if the client is local +|| (same thread and process), this is +|| set to QDI_HANDLE_LOCAL_CLIENT. +|| +|| qurt_qdi_obj_t *obj (R1) Points at the qdi_object_t structure +|| on which this QDI request is being made. +|| The qdi_object_t structure is usually +|| the first element of a larger structure +|| that contains state associated with the +|| object; because it is usually the first +|| element, the object pointers can be freely +|| interchanged through casts. +|| +|| int method (R2) Integer QDI method that represents +|| the request type. +|| +|| qurt_qdi_arg_t arg1 (R3) First three general purpose arguments +|| qurt_qdi_arg_t arg2 (R4) to the invocation function are passed in +|| qurt_qdi_arg_t arg3 (R5) these slots. +|| +|| qurt_qdi_arg_t arg4 (SP+0) Arguments beyond the first three are +|| qurt_qdi_arg_t arg5 (SP+4) passed on the stack. +|| qurt_qdi_arg_t arg6 (SP+8) +|| qurt_qdi_arg_t arg7 (SP+12) +|| qurt_qdi_arg_t arg8 (SP+16) +|| qurt_qdi_arg_t arg9 (SP+20) +|| +|| The canonical form of the invocation function takes a +|| total of 12 arguments, but not all of them are used. In general, +|| the QDI infrastructure only passes those arguments provided by +|| the caller; if the invocation function accesses additional +|| arguments beyond those provided by the caller, the values are not +|| useful. +*/ +/** @cond */ +#define QDI_INVOKE_ARGS \ + int, struct qdiobj *, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define QDI_EXT_INVOKE_ARGS \ + int, qurt_qdi_man_obj_t*, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define BUFFER_LOCK 1 +#define BUFFER_UNLOCK 0 + +struct qdiobj; +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef union { + void *ptr; /**< Pointer to the driver handle. */ + int num; /**< Method number. */ +} qurt_qdi_arg_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI driver version */ +typedef union { + int num; + struct { + short major; /** Driver major version number. */ + short minor; /** Driver minor version number. */ + }; +} qurt_qdi_version_t; + +typedef int (*qurt_qdi_pfn_invoke_t)(QDI_INVOKE_ARGS); +typedef void (*qurt_qdi_pfn_release_t)(struct qdiobj *); +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef struct qdiobj { + qurt_qdi_pfn_invoke_t invoke; /**< Invocation function that implements the driver methods.*/ + int refcnt; /**< Reference count, an integer value maintained by the QDI infrastructure that tracks the number of + references to a driver instance. */ + qurt_qdi_pfn_release_t release; /**< Release function that performs details associated with deleting an instance + of the driver object.*/ +} qurt_qdi_obj_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI managed object */ +typedef struct qurt_qdi_man_obj +{ + qurt_qdi_obj_t qdi_obj; + union + { + struct qurt_qdi_ext_driver * opener_obj; + struct qurt_qdi_ext_device * device_obj; + }; +}qurt_qdi_man_obj_t; + +typedef int (*qurt_qdi_ext_pfn_create_t)(int client_id, const char *name, qurt_qdi_version_t version, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_create_device_t)(int client_id, const char *name, qurt_qdi_version_t version, struct qurt_qdi_ext_device * device, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_invoke_t)(QDI_EXT_INVOKE_ARGS); +typedef void (*qurt_qdi_ext_pfn_destroy_t)(qurt_qdi_man_obj_t *qdi_obj); +typedef int (*qurt_qdi_ext_pfn_probe_t)(void *handle, struct qurt_qdi_ext_device **device); + +typedef struct qurt_qdi_ext_obj_info{ + qurt_qdi_man_obj_t *obj; + int qdi_client_id; + struct qurt_qdi_ext_obj_info *next; +}qurt_qdi_ext_obj_info_t; +typedef struct qurt_qdi_ext_obj_info *qurt_qdi_ext_obj_info_ptr; + +/** QuRT QDI device */ +//temporarily add this back while there are still drivers who statically define this structure +struct qurt_qdi_device { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; +}; +typedef struct qurt_qdi_device qurt_qdi_man_device; + +struct qurt_qdi_ext_driver { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + qurt_qdi_ext_pfn_create_device_t create_device; + qurt_qdi_version_t version; + qurt_qdi_ext_pfn_probe_t probe; + const char* compatible; + struct qurt_qdi_ext_device * device_list; + //qurt_qdi_ext_device_ptr device_list; +}; +typedef struct qurt_qdi_ext_driver qurt_qdi_ext_driver_t; +//above replaces qurt_qdi_man_device + +extern int qurt_qdi_obj_ref_inc(qurt_qdi_obj_t *); +extern int qurt_qdi_obj_ref_dec(qurt_qdi_obj_t *); + +extern int qurt_qdi_ext_opener (QDI_INVOKE_ARGS); +/** @endcond */ +/**@ingroup func_qurt_qdi_method_default + Processes a method that is unrecognized or unsupported in the driver invocation function. + All arguments passed to the current invocation function (Section @xref{sec:invocationFunction}) must be forwarded + to this function. + + @note1hang Invocation functions must process all unrecognized or unsupported methods + by calling this function. + + @return + None. + + @dependencies + None. +*/ +extern int qurt_qdi_method_default(QDI_INVOKE_ARGS); + +/**@ingroup func_qurt_qdi_handle_create_from_obj_t + Allocates a new device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[out] obj Pointer to the driver object. + + @return + Non-negative integer -- Success; this value is the new handle. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_invoke + Allocates a new island device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). + @param[in] obj Pointer. + + @return + Non-negative integer value that is the new handle -- Success. \n + Negative return value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_island_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_release + Deallocates the specified device handle. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] handle_to_release Handle to release. + + @return + 0 -- Success. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_release(int client_handle, int handle_to_release) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_RELEASE, + handle_to_release); +} + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_handle(int client_handle, int object_handle) +{ + qurt_qdi_obj_t *ret; + + ret = NULL; + + qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_OBJREF_GET, + object_handle, + &ret); + + return ret; +} + +/**@ingroup func_qurt_client_add_memory + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory(int client_handle, qurt_addr_t phys_addr, qurt_size_t size); + +/**@ingroup func_qurt_client_add_memory2 + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting 36-bit address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory2(int user_client_handle, qurt_paddr_64_t phys_addr, qurt_size_t size); + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_pointer(qurt_qdi_obj_t *objptr) +{ + qurt_qdi_obj_t * ret = NULL; + + if (qurt_qdi_obj_ref_inc(objptr) < 0) { + ret = NULL; + } else { + ret = objptr; + } + + return ret; +} + +static __inline void +qurt_qdi_objref_release(qurt_qdi_obj_t *objptr) +{ + if (qurt_qdi_obj_ref_dec(objptr) == 1) { + (*objptr->release)(objptr); + } +} + +/**@ingroup func_qurt_qdi_copy_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the driver buffer. + @param[in] src Base address of the user buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_from_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_FROM_USER, + dest, src, len); +} + +/**@ingroup qurt_qdi_copy_string_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param dest Base address of the driver buffer. + @param src Base address of the user buffer. + @param len Number of bytes to copy. NOTE: This is the destination buffer length. + + @return + Negative error result -- privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +int qurt_qdi_copy_string_from_user(int client_handle, char *dest, const char *src, unsigned len); + +/**@ingroup func_qurt_qdi_copy_to_user + Copies the contents of a driver memory buffer to user memory. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the user buffer. + @param[in] src Base address of the driver buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_to_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_TO_USER, + dest, src, len); +} + +/**@ingroup func_qurt_qdi_safe_cache_ops + Do cache operations on user memory + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] addr Base address of the user memory. + @param[in] size Size of the user memory. + @param[in] opcode Cache operations (QURT_MEM_CACHE_FLUSH, QURT_MEM_CACHE_INVALIDATE...) + @param[in] type Cache type (QURT_MEM_ICACHE, QURT_MEM_DCACHE) + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_safe_cache_ops(int client_handle, qurt_addr_t addr, qurt_size_t size, + qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SAFE_CACHE_OPS, + addr, size, opcode, type); +} + + +/**@ingroup func_qurt_qdi_buffer_lock + Prepares for the direct manipulation of a potentially untrusted buffer provided by a QDI + client. + + This function is used to permit a trusted driver to safely access memory that is + provided by a potentially untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + + This function performs the following security checks: \n + - Verifies that the entire buffer is accessible to the client. \n + - Ensures that the pointer remains valid for the remainder of the QDI driver + operation. \n + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] buf Pointer to the base address of the client buffer address. + @param[in] len Buffer length (in bytes). + @param[in] perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + - #QDI_PERM_R -- Read access \n + - #QDI_PERM_W -- Write access \n + - #QDI_PERM_RW -- Read/write access @tablebulletend + @param[out] obuf Pointer to the buffer address that the driver must use to access the buffer. + + @return + Negative value -- Error; the operation crosses a privilege boundary, indicating a privilege or security violation. \n + Nonzero value -- User passed a buffer that does not fulfill the requested read/write access permission. + In this case the QDI driver call must be terminated cleanly, with an appropriate error code + returned to the client. \n + Zero -- Success; when this occurs the QDI driver must use the pointer at *obuf to access memory, and not the + pointer passed in as buf -- even if the user process changes the mapping of memory at buf, + the mapping of memory at *obuf remains valid until the driver invocation completes. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK, + buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_lock2 + Prepares for the direct manipulation of a possibly-untrusted buffer provided by a QDI + client. + This API permits a trusted driver to safely access memory + provided by a possibly-untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + This function performs the following security checks: \n + -- Entire buffer is accessible to the client. \n + -- Entire buffer is mapped with permissions passed in perms field \n + -- Entire buffer is physically contiguous \n + In addition to the security checks, the API also locks the client mapping such that the client + cannot remove the mapping while the physical memory is used by the trusted + driver. \n + + @note1 Drivers are responsible for calling qurt_qdi_buffer_unlock() at appropriate time. Not + pairing qurt_qdi_buffer_unlock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client. If the client exits abruptly, the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Safe buffer + unmapping or user buffer unlock is not supported in Island mode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + -- #QDI_PERM_R -- Read access \n + -- #QDI_PERM_W -- Write access \n + -- #QDI_PERM_RW -- Read/write access \n + @param obuf Optional parameter that returns a pointer to the buffer address that + the driver must use to access the buffer. If NULL is passed, the API + only performs security checks and does not create a mapping to access the user buffer in + a safe way. + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EPRIVILEGE -- One of the security checks on the user buffer failed. \n + QURT_EFAILED -- Mapping cannot be created for the trusted driver. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock2(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_LOCK, buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_unlock + This API is paired with qurt_qdi_buffer_lock2(). A temporary overlapping mapping + created for the driver is removed. Client mapping for the user buffer is + unlocked. + + @note1 Drivers are responsible for pairing this with qurt_qdi_buffer_lock(). Not + pairing qurt_qdi_buffer_lock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client, and if the client exits abruptly, all the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Actual + unmapping of driver accessible memory or unlocking of the buffer is not + supported in Island bode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param obuf Safe buffer address that was returned in the obuf field after calling + qurt_qdi_buffer_lock2(). + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. \n + other results -- Safe buffer unmapping failed or unlocking of user buffer failed \n. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_unlock(int client_handle, void *buf, unsigned len, + void *obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_UNLOCK, buf, len, obuf); +} + +/**@ingroup func_qurt_qdi_user_malloc + Allocates memory area in the QDI heap that is read/write accessible to both the driver and + the client. \n + @note1hang The QDI heap has a limited amount of memory available, and only the + device driver can free the allocated memory. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param size Size. + + @return + Non-zero -- Success; this returned value points to the allocated memory area. \n + Zero -- Error. + + @dependencies + None. +*/ +void *qurt_qdi_user_malloc(int client_handle, unsigned size); + +/**@ingroup func_qurt_qdi_user_free + Deallocates memory area in the QDI heap. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param ptr Pointer. + + @dependencies + None. +*/ +void qurt_qdi_user_free(int client_handle, void *ptr); + +/**@ingroup funct_qurt_qdi_client_detach + Detaches a client (a process), indicating that the client does not + participate in the qurt_wait() mechanism. This behavior + is opt-in and irrevocable. When a client is detached, it can + not be un-detached. + + @param client_handle Handle of the client to detach. + + @return + Zero -- Success. Detachable clients always return success. + Nonzero value -- client_handle did not refer to a + detachable user client. + + @dependencies + None. +*/ +static __inline int qurt_qdi_client_detach(int client_handle) +{ + return qurt_qdi_handle_invoke(client_handle, QDI_CLIENT_HANDLE_DETACH); +} + +/**@ingroup func_qurt_qdi_signal_group_create + Creates a new signal group for use in a device driver. + A QDI signal group contains up to 32 signals, which can be operated on either + individually (using the qurt_qdi_signal_* functions) or as a group (using the + qurt_qdi_signal_group_* functions). \n + @note1hang Driver implementation is responsible for using the proper signal group + handle in any given situation. \n + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param p_signal_group_handle_local Returns a handle intended for use by code that + resides in the same context and process as the created signal group + (for example, the device driver implementation that allocated the + signal group). + @param p_signal_group_handle_remote Returns a handle intended for use by code + that resides in a different context and process than the created signal group + (for example, the user-mode client of an OS driver). + + @return + Zero return value indicates success.\n + Negative return value indicates could not create signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_create(int client_handle, + int *p_signal_group_handle_local, + int *p_signal_group_handle_remote) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE, + p_signal_group_handle_local, + p_signal_group_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_group_wait + Suspends the current thread until any of the signals are set in the specified signal group. + + If a signal is set in a signal group object, and a thread waits on the signal group object, + the thread is awakened. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @param signal_group_handle Handle of the signal group. + + @return + If the client is remote: + QURT_EOK -- Wait complete \n + QURT_ECANCEL -- Wait cancelled.\n + If the client is local, returns a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_wait(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_group_poll + Returns a value that indicates if any of the signals are set in the specified signal group. + + @param signal_group_handle Handle of the signal group. + + @return + 1 -- Indicates whether any of the signals are set in the signal group.\n + 0 -- Indicates that none of the signals are set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_poll(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_POLL); +} + + +/**@ingroup func_qurt_qdi_signal_create + Creates a new signal in the specified signal group. + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @note1hang Driver implementation is responsible for using the proper signal handle in + any given situation. + + @param signal_group_handle Handle of an existing signal group. + @param p_signal_handle_local Returns a handle intended for use by code that resides in + the same context and process as the created signal (for example, + the device driver implementation that allocated the signal). + @param p_signal_handle_remote Returns a handle intended for use by code that resides in + a different context and process than the created signal (for + example, the user-mode client of an OS driver). + + @return + Nonzero value -- No more signals can be created in the specified + signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_create(int signal_group_handle, + int *p_signal_handle_local, + int *p_signal_handle_remote) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_SIGNAL_CREATE, + p_signal_handle_local, + p_signal_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_set + Sets the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_set(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_SET); +} + +/**@ingroup func_qurt_qdi_signal_clear + Clears the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_clear(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_CLEAR); +} + +/**@ingroup func_qurt_qdi_signal_wait + Suspends the current thread until the specified signal is set. + If a signal is set in a signal object, and a thread waits on the signal object, the + thread is awakened. If the awakened thread has higher priority than the current thread, a + context switch may occur. + + @param signal_handle Handle of the signal. + + @return + If client is remote: + QURT_EOK -- Wait complete. \n + QURT_ECANCEL -- Wait cancelled.\n + If client is local, return a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_wait(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_poll + Returns a value that indicates if the specified signal is set. + + @param signal_handle Handle of the signal. + + @return + 1 -- Signal is set. \n + 0 -- Signal is not set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_poll(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_POLL); +} + +/**@ingroup func_qurt_qdi_devname_register + Registers a QDI device with the generic QDI object in the + current QDI context. + + This function registers an exact name or a directory prefix with a QDI opener object. + Future invocations of qurt_qdi_open() in the context of the caller invokes the + opener object if a match is detected. + + Directory prefix names are specified by ending the name with a forward slash character. + + Example of an exact name: + @code qurt_qdi_devname_register(/dev/foobar, foobar_opener);@endcode + + Example of a directory prefix: + @code qurt_qdi_devname_register(/pipedev/, pipedev_opener);@endcode + + Given the two registrations shown above, the only qurt_qdi_open() requests to + direct to the foobar_opener object are requests for the exact name + "/dev/foobar", Any request beginning with "/pipedev/" is directed to the + pipedev_opener object. + + The pipedev invocation function presumably examines the name argument to + determine exactly how to handle the request. The name is passed to the invocation + function in the a1.ptr argument (Section @xref{sec:invocationFunction}). + + @param name Device name or device name prefix. + @param opener Pointer to the opener object for the device. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. + + @dependencies + None. + */ +static __inline int qurt_qdi_devname_register(const char *name, + qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, + QDI_DEVNAME_REGISTER, + name, + opener); +} + +// Macros for backward compatibility with deprecated APIs +// (These will go away soon) + +#define qurt_qdi_register_devname(name, opener) \ + qurt_qdi_devname_register((name), (void *)(opener)) +#define qurt_qdi_new_handle_from_obj_t(handle, obj) \ + qurt_qdi_handle_create_from_obj_t((handle), (obj)) +#define qurt_qdi_release_handle(client_handle, handle) \ + qurt_qdi_handle_release((client_handle), (handle)) +#define qurt_qdi_lock_buffer(handle, buf, len, perms, obuf) \ + qurt_qdi_buffer_lock((handle), (buf), (len), (perms), (obuf)) +#define qurt_qdi_usermalloc(handle, size) \ + qurt_qdi_user_malloc((handle), (size)) +#define qurt_qdi_userfree(handle, ptr) \ + qurt_qdi_user_free((handle), (ptr)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_ext.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_ext.h new file mode 100755 index 0000000000000..383e1799a15d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_ext.h @@ -0,0 +1,58 @@ +#ifndef QURT_QDI_EXT_H +#define QURT_QDI_EXT_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018, 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct qurt_qdi_ext_device { + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + struct qurt_qdi_ext_device * next; + char * instance; + fdt_node_handle context; +}; +typedef struct qurt_qdi_ext_device *qurt_qdi_ext_device_ptr; + +/**@ingroup func_qurt_qdi_dt_register + Registers a QDI device with the generic QDI object in the current QDI context, + if and only if a compatible device node is found in the device tree. This + function serves as a device tree aware wrapper for qurt_qdi_devname_register(). + + @param name Device name or device name prefix. + @param opener Pointer to QDI ext specialized opener object for the driver. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. +*/ +static __inline int qurt_qdi_dt_register(const char *name, qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_DT_REGISTER, name, opener); +} + +static inline void qurt_qdi_ext_deviceobj_set_name (struct qurt_qdi_ext_device * device, char * name) +{ + device->instance = name; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_imacros.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_imacros.h new file mode 100755 index 0000000000000..c0a8448ac87f8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_imacros.h @@ -0,0 +1,34 @@ +#ifndef QURT_QDI_IMACROS_H +#define QURT_QDI_IMACROS_H + +/** + @file qurt_qdi_imacros.h + @brief Internal macros used for QDI. Mostly consists of tricky (and ugly) + preprocessor hacks that permit us to do varargs function invocations + where we pass optional arguments in registers and where we can do + type casting and checking automatically. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _QDMPASTE(a,b) _QDMPASTE_(a,b) +#define _QDMPASTE_(a,b) a##b +#define _QDMCNT(...) _QDMCNT_(__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _QDMCNT_(a,b,c,d,e,f,g,h,i,j,k,l,cnt,...) cnt + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_proxy.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_proxy.h new file mode 100755 index 0000000000000..f1d8992ea8811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_qdi_proxy.h @@ -0,0 +1,55 @@ +/*============================================================================= + + qurt_qdi_proxy.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef _QURT_QDI_PROXY_H +#define _QURT_QDI_PROXY_H + +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* APIs allowing operation on the proxy object directly */ +int qurt_qdi_proxy_ref_create(void); + +/* APIs allowing to operate on proxy given a known proxy handle + * 1) using qdi handle of the object + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_handle(int proxy_handle, int qdi_handle); +int qurt_qdi_proxy_ref_sub_by_handle(int proxy_handle, int qdi_handle); + +/* 2) using object reference + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); +int qurt_qdi_proxy_ref_sub_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); + +/* API allowing to associate a proxy object with a particular client given a client handle + * successfule return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_install (int client_handle, int proxy_handle); + +/* APIs allowing operation on proxy object from user client + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_add(int qdi_handle); +int qurt_client_proxy_ref_remove(int qdi_handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_QDI_PROXY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex.h new file mode 100755 index 0000000000000..a013a0bbddb1d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_RMUTEX_H +#define QURT_RMUTEX_H +/** + @file qurt_rmutex.h + Prototypes of rmutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013 - 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_rmutex_init + Initializes a recursive mutex object. + The recursive mutex is initialized in unlocked state. + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_destroy + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex protects, and continues executing. + + If a thread performs a lock operation on a mutex that is already use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock_timed + Locks the specified recursive mutex. The wait must be terminated when the specified timeout expires.\n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex is protecting, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked by itself. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + If timeout expires, this wait must be terminated and no access to the mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + + */ +int qurt_rmutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + +/**@ingroup func_qurt_rmutex_unlock + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a mutex. When the mutex is + unlocked, the thread waiting on the mutex awakens. If the awakened + thread has higher priority than the current thread, a context switch occurs. + + @note1hang When a thread unlocks a recursive mutex, the mutex is not available until + the balanced number of locks and unlocks has been performed on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock + Attempts to lock the specified recursive mutex.\n + + If a thread performs a try_lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing.\n + If a thread performs a try_lock operation on a recursive mutex that another thread has + already locked, qurt_rmutex_try_lock immediately returns with a nonzero result + value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex_try_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock_block_once + Attempts to lock a mutex object recursively. If the mutex is available, + it locks the mutex. If the mutex is held by the current thread, + it increases the internal counter and returns 0. If not, it returns a + nonzero value. + If the mutex is already locked by another thread, the caller thread is + suspended. When the mutex becomes available again (because the other + thread has unlocked it), the caller thread is awakened and tries to lock + the mutex; and if it fails, this function returns failure with a nonzero + value. If it succeeds, this function returns success with zero. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the qurt_mutex_t object. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_rmutex_try_lock_block_once(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex2.h new file mode 100755 index 0000000000000..a37e7e4458c4b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_rmutex2.h @@ -0,0 +1,183 @@ +#ifndef QURT_RMUTEX2_H +#define QURT_RMUTEX2_H +/** + @file qurt_rmutex2.h + @brief Prototypes of rmutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT rmutex2 type. + Mutex type used with rmutex2 APIs. + */ +typedef struct { + /** @cond */ + unsigned int holder __attribute__((aligned(8))); /* UGP value of the mutex holder. */ + unsigned short waiters; /* Number of waiting threads. */ + unsigned short refs; /* Number of references to this mutex. */ + unsigned int queue; /* Kernel-maintained futex queuevalue. */ + unsigned int excess_locks; /* Number of excess times the holder has locked the mutex. */ + /** @endcond */ +} qurt_rmutex2_t; +/** @} */ /* end_addtogroup mutex_types */ +/** @cond internal_only*/ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_rmutex2_init + + @deprecated use #qurt_rmutex_init instead. + + Initializes a recursive mutex object. + + The recursive mutex is initially unlocked. + + Objects of type rmutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_destroy + + @deprecated use #qurt_rmutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code must destroy an rmutex2 object prior to + deallocating it; calling qurt_rmutex2_destroy() before deallocating it ensures + that all qurt_rmutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_lock + + @deprecated use #qurt_rmutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that the mutex protects, and continues + to execute. + + If a thread performs a lock operation on a recursive mutex that another thread is using, + the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_unlock + + @deprecated use #qurt_rmutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex awakens. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_rmutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_rmutex2_lock(). When a call to qurt_rmutex2_lock() + succeeds immediately, this function behaves similarly, returning 0 for success. + When a call to qurt_rmutex2_lock() does not succeed immediately, this function has + no effect and returns nonzero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex2_try_lock(qurt_rmutex2_t *lock); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sclk.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sclk.h new file mode 100755 index 0000000000000..a83cf5f1db889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sclk.h @@ -0,0 +1,145 @@ +#ifndef QURT_SCLK_H +#define QURT_SCLK_H +/** + @file qurt_sclk.h + @brief Header file describing the APIs supported by QuRT system SCLK + feature. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + + +/*============================================================================= + + INCLUDE FILES + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + Conversion from microseconds to sleep ticks. + */ +#define QURT_SYSCLOCK_TIMETICK_FROM_US(us) ((us) * 192ULL / 10UL) +#define qurt_sysclock_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_SYSCLOCK_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_SYSCLOCK_MAX_DURATION (1042499uLL * 3600uLL * 1000uLL * 1000uLL) +#define qurt_sysclock_max_duration() QURT_SYSCLOCK_MAX_DURATION +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_SYSCLOCK_MAX_DURATION_TICKS (1042499uLL * 3600uLL * 19200000uLL) +#define qurt_sysclock_max_duration_ticks() QURT_SYSCLOCK_MAX_DURATION_TICKS +/** + Sleep timer error margin for Qtimer is 192 ticks ~10 us. +*/ +#define QURT_SYSCLOCK_ERROR_MARGIN 192U //QURT_TIMER_MIN_DURATION*timer_freq; +#define qurt_sysclock_error_margin() QURT_SYSCLOCK_ERROR_MARGIN + +/*============================================================================= + + DATA DECLARATIONS + +=============================================================================*/ + +/**@ingroup func_qurt_sysclock_get_hw_ticks + @xreflabel{sec:qurt_sysclock_get_hw_ticks} + Gets the hardware tick count.\n + Returns the current value of a 64-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation must be used with care because of the wrap-around behavior. + + @return + Integer -- Current value of 64-bit hardware counter. + + @dependencies + None. + */ +unsigned long long qurt_sysclock_get_hw_ticks (void); + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_32 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_32} + Gets the hardware tick count in 32 bits.\n + Returns the current value of a 32-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 32 bits are the lower 32 bits of the Qtimer counter. + + @return + Integer -- Current value of the 32-bit timer counter. + + @dependencies + None. + */ +static inline unsigned long qurt_sysclock_get_hw_ticks_32 (void) +{ + //Beginning with v61 there is a HW register that can be read directly. + unsigned long count; + __asm__ __volatile__ (" %0 = c30 " : "=r"(count)); + return count; +} + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_16 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_16} + Gets the hardware tick count in 16 bits.\n + Returns the current value of a 16-bit timer counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 16 bits are based on the value of the lower 32 bits in Qtimer + counter, right shifted by 16 bits. + + @return + Integer -- Current value of the 16-bit timer counter, calculated from the lower 32 bits in the + Qtimer counter, right shifted by 16 bits. + + @dependencies + None. + */ + + +static inline unsigned short qurt_sysclock_get_hw_ticks_16 (void) +{ + unsigned long ticks; + + //Beginning with v61 there is a HW register that can be read directly. + __asm__ __volatile__ (" %0 = c30 " : "=r"(ticks)); + __asm__ __volatile__ ( "%0 = lsr(%0, #16) \n" :"+r"(ticks)); + + return (unsigned short)ticks; +} +unsigned long long qurt_timer_timetick_to_us(unsigned long long ticks); +#define qurt_sysclock_timetick_to_us(ticks) qurt_timer_timetick_to_us(ticks) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif /* QURT_SCLK_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_secure_proc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_secure_proc.h new file mode 100755 index 0000000000000..f40c7deb9bca1 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_secure_proc.h @@ -0,0 +1,53 @@ +#ifndef QURT_SECURE_PROC_H +#define QURT_SECURE_PROC_H + +/** + @file qurt_secure_proc.h + @brief Definitions, macros, and prototypes used for handling secure process + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_process_migrate_secure_process + Migrate the user process to Qurt secure process + + @param secure_phy_address Physical starting address of secure memory + @param secure_memory_size Size of secure memory + @param entry Entry function to secure process + + @return + EOK + Negative return value -- Error. + + @dependencies + None. +*/ +int qurt_process_migrate_secure_process(unsigned long long secure_phy_address, unsigned int secure_memory_size, void entry(unsigned)); + +/**@ingroup qurt_process_get_migration_mem_size + get the size of all writable memory regions in a user PD. This is for preparation on secure process migration. + + @return + size of all writable memory regions in a user PD. + + @dependencies + None. +*/ +int qurt_process_get_migration_mem_size(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sem.h new file mode 100755 index 0000000000000..ee5ce4b2d94ab --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_sem.h @@ -0,0 +1,252 @@ +#ifndef QURT_SEM_H +#define QURT_SEM_H +/** + @file qurt_sem.h + Prototypes of semaphore API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup semaphore_types +@{ */ + +/** QuRT semaphore type. */ +typedef union { + /** @cond */ + unsigned int raw[2] __attribute__((aligned(8))); + struct { + unsigned short val; /**< */ + unsigned short n_waiting; /**< */ + unsigned int reserved1; /**< */ + unsigned int queue; /**< */ + unsigned int reserved2; /**< */ + }X; /** @endcond */ +} qurt_sem_t; +/** @} */ /* end_addtogroup semaphore_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_sem_add + Releases access to a shared resource (the specified amount increments the semaphore count value).\n + When a thread performs an add operation on a semaphore, the specified value increments the semaphore count. + The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing. \n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel repeatedly awakens the highest-priority waiting thread and decrements + the semaphore count value until either no waiting threads remain or the + semaphore count value is zero. If any of the awakened threads has higher priority + than the current thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] amt Amount to increment the semaphore count value. + + @return + Unused integer value. + + @dependencies + None. + + */ +int qurt_sem_add(qurt_sem_t *sem, unsigned int amt); + +/**@ingroup func_qurt_sem_up + Releases access to a shared resource. When a thread performs an up operation on a semaphore, + the semaphore count value increments. The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing.\n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel awakens the highest-priority waiting thread and decrements the + semaphore count value. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +static inline int qurt_sem_up(qurt_sem_t *sem) { return qurt_sem_add(sem,1); } + +/**@ingroup func_qurt_sem_down + Requests access to a shared resource. When a thread performs a down operation on a + semaphore, the result depends on the semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +int qurt_sem_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_down_timed + When a thread performs a down operation on a semaphore, the result depends on the + semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. Terminate the wait when the specified timeout expires. + If timeout expires, terminate this wait and grant no access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_sem_down_timed(qurt_sem_t *sem, unsigned long long int duration); + +/**@ingroup func_qurt_sem_try_down + @xreflabel{hdr:qurt_sem_try_down} + Requests access to a shared resource (without suspend). When a thread performs a try down + operation on a semaphore, the result depends on the semaphore count value: \n + - The count value is decremented when it is nonzero. The down operation returns 0 as + the function result, and the thread gains access to the shared resource and is free to + continue executing.\n + - The count value is not decremented when it is zero. The down operation returns -1 + as the function result, and the thread does not gain access to the shared resource + and should not continue executing. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + 0 -- Success. \n + -1 -- Failure. + + @dependencies + None. + + */ +int qurt_sem_try_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init + Initializes a semaphore object. + The default initial value of the semaphore count value is 1. + + @param[out] sem Pointer to the initialized semaphore object. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_destroy + Destroys the specified semaphore.\n + @note1hang Semaphores must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Semaphores must not be destroyed while they are still in use. If this occur, + the behavior of QuRT is undefined. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_sem_destroy(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init_val + Initializes a semaphore object with the specified value. + + @datatypes + #qurt_sem_t + + @param[out] sem Pointer to the initialized semaphore object. + @param[in] val Initial value of the semaphore count value. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init_val(qurt_sem_t *sem, unsigned short val); + +/**@ingroup func_qurt_sem_get_val + Gets the semaphore count value.\n + Returns the current count value of the specified semaphore. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Integer semaphore count value + + @dependencies + None. + */ +static inline unsigned short qurt_sem_get_val(qurt_sem_t *sem ){return sem->X.val;} +int qurt_sem_down_cancellable(qurt_sem_t *sem); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SEM_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_shmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_shmem.h new file mode 100755 index 0000000000000..980557323708a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_shmem.h @@ -0,0 +1,89 @@ +#ifndef QURT_SHMEM_H +#define QURT_SHMEM_H + +/** + @file qurt_shmem.h + + @brief + Prototypes of QuRT inter-process shared memory APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MODE_T +#define MODE_T +typedef unsigned int mode_t; +#endif //MODE_T + +/** + * The shm_open() function establishes a connection between a shared memory object and a file descriptor. + * The file descriptor is used by other functions such as mmap() to refer to that shared memory object. + * + * + * @param name Pointer to string naming a shared memory object. Name has to start with "/shm/" + * @param oflag File status flags and file access modes of the open file description. Following + * flags are defined in and supported: + * O_RDONLY: oepn for read access only + * O_RDWR: Open for read or write access + * O_CREAT: If shared memory object doesn't exist, create one. + * @param mode Permission flags (currently ignored) + * + * @return file descriptor (positive number) if operation successful. + * negative error code if failed + * +*/ + +int shm_open(const char * name, int oflag, mode_t mode); + +/** + * The shm_mmap() function create a shared memory mapping in the virtual address space of the + * the calling process. + * + * @param addr The starting address for the new mapping is specified in addr. + * @param len Specifies the lengh of the shared memory region. + * @param prot Describes the desired memory protection of the mapping. Same as the one in mmap of POSIX. + * @param flags Determines whether updates to the mapping is visible or not to other process. Same as + * the one in mmap of POSIX. + * @param fd The starting adddress for the new mapping is returned. + * @param offset unused. + * + * @return The starting adddress for the new mapping is returned. + * negative error code if failed + * +*/ + +void *shm_mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset); + +/** + * The shm_close() function removes a connection between a shared memory object and a file descriptor. + * If there is no file descriptor connects to the shared memory object, the shared memory object will + * be deleted automatically. Shared memory object has same virtual address in any process. This is + * restriction of single virtual address space. + * + * + * @param fd File descriptor of shared memory object + * + * @return 0 if operation successful. + * negative error code if failed + * +*/ + + +int shm_close(int fd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal.h new file mode 100755 index 0000000000000..3a89c53394ad5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal.h @@ -0,0 +1,518 @@ +#ifndef QURT_SIGNAL_H +#define QURT_SIGNAL_H + +/** + @file qurt_signal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup signals_types +@{ */ +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 /**< Wait any. */ +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 /**< Wait all. */ + +/*===================================================================== + Typedefs + ======================================================================*/ + + +/** QuRT signal type. + */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int signals; + unsigned int waiting; + unsigned int queue; + unsigned int attribute; + }X; + /** @endcond */ +} qurt_signal_t; + + +/** QuRT 64-bit signal type. + */ +typedef struct { + /** @cond */ + qurt_signal_t signal_sum; + unsigned long long signals; + unsigned long long waiting; + /** @endcond */ +} qurt_signal_64_t; +/** @} */ /* end_addtogroup signals_types */ +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal_init + Initializes a signal object. + Signal returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_init(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_destroy + Destroys the specified signal object. + + @note1hang Signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_destroy(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting on the signal. + + If a thread is waiting on a signal object for any of the specified set of signals to set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared when the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread waits to set any of the signals, or to set all of + them. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_timed + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set or until timeout. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared after the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value that identifies the individual signals in the signal object to wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] signals Bitmask of signals that are set + @param[in] duration Duration (microseconds) to wait. Must be in the range + [#QURT_TIMER_MIN_DURATION ... #QURT_TIMER_MAX_DURATION] + + @return + #QURT_EOK -- Success; one or more signals were set \n + #QURT_ETIMEDOUT -- Timed-out \n + #QURT_EINVALID -- Duration out of range + + @dependencies + Timed-waiting support in the kernel. +*/ +/* ======================================================================*/ +int qurt_signal_wait_timed(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, unsigned int *signals, unsigned long long int duration); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_any + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on the thread. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_any(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_all + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_all(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to set the signal, and 0 indicates not to set it. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 32-bit word with current signals + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_get(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_clear + Clear signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_clear(qurt_signal_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal_wait_cancellable + @xreflabel{hdr:qurt_signal_wait_cancellable} + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] return_mask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_signal_wait_cancellable(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, + unsigned int *return_mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_init + Initializes a 64-bit signal object.\n + The signal argument returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore. + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_init(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_destroy + Destroys the specified signal object. + + @note1hang 64-bit signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_destroy(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_wait + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value, which identifies the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_wait(qurt_signal_64_t *signal, unsigned long long mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set it. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifiying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_64_set(qurt_signal_64_t *signal, unsigned long long mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_64_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 64-bit double word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_get(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_clear + Clears signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_clear(qurt_signal_64_t *signal, unsigned long long mask); + +#ifdef __cplusplus +} +#endif + +#endif /* QURT_SIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal2.h new file mode 100755 index 0000000000000..43975100cbf75 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_signal2.h @@ -0,0 +1,340 @@ +#ifndef QURT_SIGNAL2_H +#define QURT_SIGNAL2_H + +/** + @file qurt_signal2.h + @brief Prototypes of kernel signal2 API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 + +/*===================================================================== + Typedefs + ======================================================================*/ + +/** @addtogroup signals2_types +@{ */ +/** qurt_signal2 type. + */ +typedef union { + /** @cond */ + struct{ + unsigned int cur_mask; /* Current set of signal bits that are set. */ + unsigned int sig_state; /* Current state. */ + /* Bit 0 -- in anysignal wait. */ + /* Bit 1 -- in allsignal wait. */ + /* Bit 2 -- in interrupt wait. */ + /* Bits 31-3 -- reference count field. */ + unsigned int queue; /* Kernel-maintained futex queue value. */ + unsigned int wait_mask; /* When sig_state indicates a waiter is present, this is the wait mask. */ + }; + unsigned long long int raw; + /** @endcond */ +} qurt_signal2_t; +/* @} */ /* end_addtogroup signals2_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_init + + @deprecated use #qurt_signal_init instead. + + Initializes a signal2 object. + Signal returns the initialized object. + The signal object is initially cleared. + + Objects of type signal2 solve a potential race condition between + set() and destroy() operations. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + Each mutex-based object has an associated + kernel resource(s), therefore users must call qurt_signal2_destroy() + when this object no longer in use. + */ +/* ======================================================================*/ +void qurt_signal2_init(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_destroy + + @deprecated use #qurt_signal_destroy instead. + + Destroys the specified signal object. + + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont Application code should destroy a signal2 object prior to deallocating it. + Calling qurt_signal2_destroy() before deallocating a + signal2 object ensures completion of all qurt_signal2_set() calls. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_destroy(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait + + @deprecated use #qurt_signal_wait instead. + + Suspends the current thread until the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ANY, the thread will be awakened when + any of the signals specified in the mask are set. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ALL, the thread will be awakened only + when all the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to wait on. + @param[in] attribute Specifies whether the thread waits for any of the signals to be set, or for all of + them to be set. Values:\n + - QURT_SIGNAL_ATTR_WAIT_ANY \n + - QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_any + + @deprecated use #qurt_signal_wait_any instead. + + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened when any of the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_any(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_all + + @deprecated use #qurt_signal_wait_all instead. + + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened only when all the signals specified in the mask are set. + + @note1hang At most one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_all(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_set + + @deprecated use #qurt_signal_set instead. + + Sets signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_get + + @deprecated use #qurt_signal_get instead. + + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the signal object to access. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_get(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_clear + + @deprecated use #qurt_signal_clear instead. + + Clear signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_clear(qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal2_wait_cancellable + + @deprecated use #qurt_signal_wait_cancellable instead. + + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] p_returnmask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +int qurt_signal2_wait_cancellable(qurt_signal2_t *signal, + unsigned int mask, + unsigned int attribute, + unsigned int *p_returnmask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SIGNAL2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_space.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_space.h new file mode 100755 index 0000000000000..2c3f9e4496697 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_space.h @@ -0,0 +1,230 @@ +#ifndef QURT_SPACE_H +#define QURT_SPACE_H +/** + @file qurt_space.h + @brief Prototypes of QuRT process control APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** This flag is a request to the OS to suspend the processes just before calling main() +But it is going to be obsoleted and replaced by QURT_PROCESS_SUSPEND_ON_STARTUP */ +#define SPAWNN_FLAG_SUSPEND_ON_STARTUP QURT_PROCESS_SUSPEND_ON_STARTUP + +/** + * Creates and starts a process from ELF of a specified name. The slash symbols + * "/" or "\" are ignored. Do not include the directory name in the input. This function + * accepts the the SPAWN flags. Multiple SPAWN flags can be specified by OR'ing the flags. + * + * @param name ELF name of the executable. Name shall not contain directories, + * use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf" + * + * @param return + Process ID -- Success \n + Negative error code -- failure\n + #QURT_EPRIVILEGE -- Caller does not have enough privilege for this operation\n + #QURT_EMEM -- Not enough memory to perform the operation \n + #QURT_EFAILED -- Operation failed \n + #QURT_ENOTALLOWED -- Operation not allowed \n + #QURT_ENOREGISTERED -- Not registered \n + #QURT_ENORESOURCE -- Resource exhaustion \n + #QURT_EINVALID -- Invalid argument value +*/ + +int qurt_spawn_flags(const char * name, int flags); + +/** + Creates and starts a process from an ELF of the specified name. The slash symbols + "/" or "\" are ignored. Do not include the directory name in the input. + + @param name ELF name of the executable. Name shall not contain directories, + use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf". + + @return + Process ID -- Success. \m + Negative error code -- Failure. + +*/ +static inline int qurt_spawn(const char *name) +{ + return qurt_spawn_flags(name,0); +} + +/** + * Returns the process ID of the current process. + * + * @return + * Process ID + * +*/ +#define qurt_getpid qurt_process_get_id + +/** + * The qurt_wait() function waits for status change in a child process. It could be used by parent + * process to block on any child process terminates. + * + * This API returns error if there are no user processes or all user processes got detached. + * + * @param status Pointer to status variable. The variable provides the status value of child process. + * The value comes from exit() system call made by child process. + * + * @return + Process ID of the child process that changes status -- Success \n + * Negative error code -- Failure + * +*/ + +int qurt_wait(int *status); + + +/** @cond */ +/* APIs that allow registering callbacks on spawn of user pd */ +typedef void (*QURT_SPAWN_PFN)(int client_handle, void *data_ptr); //no return, since we won't be error checking it in spawn +typedef int (*QURT_CB_PFN)(int client_handle, void *user_data, void *info); +typedef union { + QURT_SPAWN_PFN spawn_pfn; + QURT_CB_PFN cb_pfn; +} qurt_process_callback_pfn_t; +/** @endcond */ + +/** @cond internal_only */ + +/**@ingroup func_qurt_event_register +Sets the specified bits by mask in the signal passed by the caller. The signal gets set +when the client handle indicated by value goes away (at process exit). Multiple clients can register for the signal +to be set. + +@datatypes + +@param[in] type QURT_PROCESS_EXIT is the only event that can be registered for. +@param[in] value Indicates the client handle of the process for which the event is registered. +@param[in] signal Pointer to the signal object to set when the event occurs. +@param[in] mask Mask bits to set in the signal. +@param[out] data Pointer to the variable that would receive the exit code of the exiting process. +@param[in] datasize Size of the data variable. + +@return +#QURT_EOK -- Success \n +#QURT_EMEM -- Not enough memory to allocate resources \n +#QURT_EVAL -- Invalid values passed to the API + +@dependencies +None. +*/ +int qurt_event_register(int type, int value, qurt_signal_t *psig, unsigned int mask, void *data, unsigned int data_size); + +/**@ingroup func_qurt_callback_register_onspawn +Allows registering for a callback on spawn of any user process. + +@datatypes +#QURT_SPAWN_PFN + +@param[in] pFn Callback function to call when any user process is spawned. +@param[in] user_data Pointer to the argument that the callback must be called with. + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_callback_register_onspawn(QURT_SPAWN_PFN pFn, void *user_data); + +/**@ingroup func_qurt_callback_deregister_onspawn +Allows de-registering callback on spawn. + +@param[in] callback_handle Handle returned by qurt_callback_register_onspawn. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_callback_deregister_onspawn(int callback_handle); + +/**@ingroup func_qurt_process_callback_register +Allows registering for a callback during or after image loading. +Generic callback types: + Functions similarly to qurt_callback_register_onspawn(). Callback is called after process is + loaded, before process thread starts. Callback has no return value and has no info provided + from OS. + pFn - QURT_SPAWN_PFN + type - QURT_PROCESS_CB_GENERIC + arg1 - not used + arg2 - not used + arg3 - not used +Note callback types: + Callback is called during process loading: before segment loading(QURT_PROCESS_NOTE_CB_PRE_MAP), + or after segment loading (QURT_PROCESS_NOTE_CB_POST_MAP). OS provides info to the callback. info + argument in callback is populated with pointer to the mapped note corresponding to the callback. + Callback has return value, loader fails if callback returns a value that is not QURT_EOK. + pFn - QURT_CB_PFN + type - QURT_PROCESS_NOTE_CB_PRE_MAP or QURT_PROCESS_NOTE_CB_POST_MAP + arg1 - note type (ex: NOTE_TYPE_POOL_INFO, NOTE_TYPE_SEGMENT_INFO, NOTE_TYPE_ARB_INFO) + arg2 - note name + arg3 - not used + +@datatypes + +@param[in] pFn Callback function to call +@param[in] type Callback type +@param[in] user_data Pointer to the argument that the callback must be called with. +@param[in] arg1 Arguments interpreted by OS based on callback type +@param[in] arg2 Arguments interpreted by OS based on callback type +@param[in] arg3 Arguments interpreted by OS based on callback type (currently not used) + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_process_callback_register(qurt_process_callback_pfn_t pFn, + qurt_process_cb_type_t type, + void *user_data, + qurt_process_callback_arg_t arg1, + qurt_process_callback_arg_t arg2, + qurt_process_callback_arg_t arg3); + + + +/**@ingroup func_qurt_process_callback_deregister +Allows de-registering callback for imate loading. +@param[in] callback_handle Handle returned by qurt_process_callback_register. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_process_callback_deregister(int callback_handle); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SPACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_consts.h new file mode 100755 index 0000000000000..48a8b6a38c402 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_consts.h @@ -0,0 +1,32 @@ +#ifndef QURT_SRM_CONSTS_H +#define QURT_SRM_CONSTS_H +/** + @file qurt_srm_consts.h + @brief Type definitions for srm + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2020-2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +#define QURT_SRM_WAKEUP_REQUEST 1U << 0 /**< Value = 1: Send wakeup request to the SRM server. */ +#define QURT_SRM_SET_HANDLE 1U << 1 /**< Value = 2: Set the client handle for a new SRM client. */ +#define QURT_SRM_ALLOC_KERNEL_PAGES 1U << 2 /**< Value = 4: Allocate pages from the kernel VA space. */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_driver.h new file mode 100755 index 0000000000000..5489e3dddbcca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_srm_driver.h @@ -0,0 +1,140 @@ +#ifndef QURT_SRM_DRIVER_H +#define QURT_SRM_DRIVER_H +/** + @file qurt_srm_driver.h + @brief Definitions, macros, and prototypes used by SRM drivers. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + + =============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Define qurt_srm_driver_t structure, which represents +|| the "registration" object for an SRM driver. +*/ +/** @cond internal_only */ +struct _qurt_srm_driver { + const char *name; + qurt_qdi_obj_t *obj; +}; + +typedef struct _qurt_srm_driver qurt_srm_driver_t; + +/* +|| qurt_srm_object_invoke() is an internal equivalent to qurt_qdi_handle_invoke(). +|| It behaves the same, but it takes a QDI object pointer instead of a handle. +*/ + +#define qurt_srm_object_invoke(o,m,...) \ + _QDMPASTE(_QDMSOI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__) +#define _QDMSOI3(a,b,c) qurt_srm_oi3(a,b,c) +#define _QDMSOI4(a,b,c,d) qurt_srm_oi4(a,b,c,(int)(d)) +#define _QDMSOI5(a,b,c,d,e) qurt_srm_oi5(a,b,c,(int)(d),(int)(e)) +#define _QDMSOI6(a,b,c,d,e,f) qurt_srm_oi6(a,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMSOI7(a,b,c,d,e,f,g) qurt_srm_oi7(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMSOI8(a,b,c,d,e,f,g,h) qurt_srm_oi8(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMSOI9(a,b,c,d,e,f,g,h,i) qurt_srm_oi9(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMSOI10(a,b,c,d,e,f,g,h,i,j) qurt_srm_oi10(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMSOI11(a,b,c,d,e,f,g,h,i,j,k) qurt_srm_oi11(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMSOI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_srm_oi12(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) + +int qurt_srm_oi3(int, qurt_qdi_obj_t *, int); +int qurt_srm_oi4(int, qurt_qdi_obj_t *, int, int); +int qurt_srm_oi5(int, qurt_qdi_obj_t *, int, int, int); +int qurt_srm_oi6(int, qurt_qdi_obj_t *, int, int, int, int); +int qurt_srm_oi7(int, qurt_qdi_obj_t *, int, int, int, int, int); +int qurt_srm_oi8(int, qurt_qdi_obj_t *, int, int, int, int, int, int); +int qurt_srm_oi9(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int); +int qurt_srm_oi10(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int); +int qurt_srm_oi11(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int); +int qurt_srm_oi12(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int, int); + +#define QDI_SRM_INIT 192 + +/* +|| QURT_SRM_DECLARE_DRIVER() declares an SRM driver to the SRM infrastructure. +|| +|| The three arguments are: +|| unique_id -- Unique C identifier, unused but must be a unique global symbol. +|| name -- Name of the driver by which an SRM client attempts to open it. +|| obj -- Pointer to the singleton object of the driver, which handles things such as +|| initialization and QDI_OPEN requests. +*/ + +#define QURT_SRM_DECLARE_DRIVER(unique_id, xname, xobj) \ + __attribute__((section(".srm.rodata.user.main.DECL"))) const qurt_srm_driver_t unique_id = \ + { .name = xname, .obj = xobj } + + +/*@ingroup func_qurt_srm_mapping_create + Creates a memory mapping in pagetable with specified attributes + + @param[in] client_handle Client handle representing the process for which + mapping would be created. + @param[in] pageno_virt pointer to the virtual page. NULL indicates SRM + would indicate the virtual memory. + @param[in] pageno_phys physical page to be used for the mapping + @param[in] page_count number of 4k pages to be mapped + @param[in] cache_attr cache attributes for the mapping + @param[in] perm permissions to be used for the mapping + + @return value greater than 0 indicates a handle which can be passed to + qdi_close() to remove the mapping. Negative value indicates + an error. + + @dependencies + None. +*/ +int qurt_srm_mapping_create(int client_handle, + unsigned *pageno_virt, + unsigned pageno_phys, + unsigned page_count, + qurt_mem_cache_mode_t cache_attr, + qurt_perm_t perm); + + +/**@ingroup func_qurt_srm_get_pid + Gets the PID for the client_handle that is passed. + + @param[in] client_handle Client handle for which PID is required. + + @return PID of the client + Negative PID value '-1' will be returned in case of Error + + @dependencies + None. +*/ +unsigned qurt_srm_get_pid(int client_handle); + + +/*@ingroup func_qurt_srm_get_thread_id + Gets the thread id of the client requesting a service from SRM + + @param[in] None. + + @return thead id of client thread + + @dependencies + None. +*/ +qurt_thread_t qurt_srm_get_client_thread_id(void); + +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_DRIVER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_stid.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_stid.h new file mode 100755 index 0000000000000..379f46aaa4b80 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_stid.h @@ -0,0 +1,73 @@ +#ifndef QURT_STID_H +#define QURT_STID_H +/** + @file qurt_stid.h + Prototypes of software thread identifier(stid) interface APIs. + A stid is 8 bit identifier that can be assigned to a software thread. + The performance monitor logic uses stid as a counting match criteria + for maskable events. stid is also used by the hardware debugger + (ISDB) to match breakpoints. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2024 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_stid_alloc + Allocate a unique stid + + @param[in] pid Process identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - Allocation success + QURT_ENORESOURCE - No stid available for allocation + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_stid_alloc(unsigned int pid, unsigned int *stid); + +/**@ingroup func_qurt_stid_release + Release the stid. + + + @param[in] pid Process identifier + @param[in] stid STID to release + + @note1hang + User shall ensure to clear the released stid from process or thread(s) + to default value (QURT_STID_DEFAULT) before releasing that stid + + @return + QURT_EOK - Release success + QURT_ENOTALLOWED - Operation not allowed for a pid + QURT_EINVALID - Invalid stid + + @dependencies + None. + */ +int qurt_stid_release(unsigned int pid, unsigned int stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_STID_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread.h new file mode 100755 index 0000000000000..499699e7c72e2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread.h @@ -0,0 +1,1260 @@ +#ifndef QURT_THREAD_H +#define QURT_THREAD_H +/** + @file qurt_thread.h + @brief Prototypes of Thread API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2020-2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +#include +#include "qurt_pmu.h" +#include "qurt_api_version.h" +#endif /* __ASSEMBLER__ */ +#include "qurt_consts.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/* + Bitmask configuration to select DSP hardware threads. + To select all the hardware threads, use #QURT_THREAD_CFG_BITMASK_ALL + and the following: \n + - For QDSP6 V2/V3, all six hardware threads are selected \n + - For QDSP6 V3L, all four hardware threads are selected \n + - For QDSP6 V4, all three hardware threads are selected + */ + +#define QURT_THREAD_CFG_BITMASK_HT0 0x00000001 /**< HTO. */ +#define QURT_THREAD_CFG_BITMASK_HT1 0x00000002 /**< HT1. */ +#define QURT_THREAD_CFG_BITMASK_HT2 0x00000004 /**< HT2. */ +#define QURT_THREAD_CFG_BITMASK_HT3 0x00000008 /**< HT3. */ +#define QURT_THREAD_CFG_BITMASK_HT4 0x00000010 /**< HT4. */ +#define QURT_THREAD_CFG_BITMASK_HT5 0x00000020 /**< HT5. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{sec:qurt_thread_cfg} */ + +#define QURT_THREAD_CFG_BITMASK_ALL 0x000000ffU /**< Select all the hardware threads. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_CFG_USE_RAM 0x00000000 /**< Use RAM. */ +#define QURT_THREAD_CFG_USE_TCM 0x00000100 /**< Use TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_BUS_PRIO_DISABLED 0 /**< Thread internal bus priority disabled. */ +#define QURT_THREAD_BUS_PRIO_ENABLED 1 /**< Thread internal bus priority enabled. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_AUTOSTACK_DISABLED 0 /**< Thread has autostack v2 feature disabled. */ +#define QURT_THREAD_AUTOSTACK_ENABLED 1 /**< Thread has autostack v2 feature enabled. */ + +/* + Macros for QuRT thread attributes. + */ +#define QURT_HTHREAD_L1I_PREFETCH 0x1 /**< Enables hardware L1 instruction cache prefetching. */ +#define QURT_HTHREAD_L1D_PREFETCH 0x2 /**< Enables hardware L1 data cache prefetching. */ +#define QURT_HTHREAD_L2I_PREFETCH 0x4 /**< Enables hardware L2 instruction cache prefetching. */ +#define QURT_HTHREAD_L2D_PREFETCH 0x8 /**< Enables hardware L2 data cache prefetching. */ +#define QURT_HTHREAD_DCFETCH 0x10 /**< Enables DC fetch to the provided virtual address. + DC fetch indicates the hardware that a data memory access is likely. + Instructions are dropped when there is high bus utilization. */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{hdr:partition_tcm} */ +/* + Below value is used to create legacy QuRT threads by default. + If a thread has this as the detach_state, the thread can be joined + on until it exits. When we are able to change default behavior of all + QuRT threads to JOINABLE (posix default), we can remove this legacy + behavior. +*/ +#define QURT_THREAD_ATTR_CREATE_LEGACY 0U /**< Create a legacy QuRT thread by default. If a thread has this as a detach state, the thread can be joined on until it exits. */ +#define QURT_THREAD_ATTR_CREATE_JOINABLE 1U /**< Create a joinable thread. */ +#define QURT_THREAD_ATTR_CREATE_DETACHED 2U /**< Create a detached thread. */ +/** @} */ /* end_addtogroup thread_macros */ + + +#define QURT_THREAD_ATTR_NAME_MAXLEN 16 /**< Maximum name length. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_RAM 0 /**< Creates threads in RAM/DDR. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_TCM 1 /**< Creates threads in TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT QURT_THREAD_ATTR_TCB_PARTITION_RAM /**< Backward compatibility. */ +#define QURT_THREAD_ATTR_PRIORITY_DEFAULT 254 /**< Priority.*/ +#define QURT_THREAD_ATTR_ASID_DEFAULT 0 /**< ASID. */ +#define QURT_THREAD_ATTR_AFFINITY_DEFAULT (-1) /**< Affinity. */ +#define QURT_THREAD_ATTR_BUS_PRIO_DEFAULT 255 /**< Bus priority. */ +#define QURT_THREAD_ATTR_AUTOSTACK_DEFAULT 0 /**< Default autostack v2 disabled thread. */ +#define QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT (-2) /**< Timetest ID. */ +#define QURT_THREAD_ATTR_STID_DEFAULT QURT_STID_DEFAULT /**< STID. */ +#define QURT_THREAD_ATTR_STID_ENABLE 1 /**< Indicate to allocate STID during thread creation. */ + +#define QURT_PRIORITY_FLOOR_DEFAULT 255U /**< Default floor. */ +/** @} */ /* end_addtogroup thread_macros */ + +// Option for suspending thread +#define QURT_THREAD_SUSPEND_SYNCHRONOUS 0x0U // bit#0 +#define QURT_THREAD_SUSPEND_ASYNCHRONOUS 0x1U // bit#0 +#define QURT_THREAD_SUSPEND_KEEP_HMX 0x0U // bit#1 +#define QURT_THREAD_SUSPEND_DETACH_HMX 0x2U // bit#1 + +// Option for resuming thread +#define QURT_THREAD_RESUME_DEFAULT 0x0 + +// Thread property IDs +#define QURT_THREAD_PROPERTY_SUSPENDABLE 0x0U +#define QURT_THREAD_PROPERTY_RESUMABLE 0x1 + +// Thread group +#define QURT_THREAD_DEFAULT_GROUP_ID 0x0U +#define QURT_THREAD_GROUP_ID_MASK 0x3FU + +/** @endcond*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup thread_types +@{ */ +/** @cond rest_reg_dist */ +typedef unsigned int qurt_cache_partition_t; /**< QuRT cache partition type. */ + +#define CCCC_PARTITION 0U /**< Use the CCCC page attribute bits to determine the main or auxiliary partition. */ +#define MAIN_PARTITION 1U /**< Use the main partition. */ +#define AUX_PARTITION 2U /**< Use the auxiliary partition. */ +#define MINIMUM_PARTITION 3U /**< Use the minimum. Allocates the least amount of cache (no-allocate policy possible) for this thread. */ +/** @endcond */ + +/** Thread ID type. */ +typedef unsigned int qurt_thread_t; + +/** @cond rest_reg_dist */ +/** Thread attributes. */ +typedef struct _qurt_thread_attr { + + char name[QURT_THREAD_ATTR_NAME_MAXLEN]; /**< Thread name. */ + unsigned char tcb_partition; /**< Indicates whether the thread TCB resides in RAM or + on chip memory (TCM). */ + unsigned char stid; /**< Software thread ID used to configure the stid register + for profiling purposes. */ + unsigned short priority; /**< Thread priority. */ + unsigned char autostack:1; /**< Autostack v2 enabled thread. */ + unsigned char group_id:6; /**< Group ID. */ + unsigned char reserved:1; /**< Reserved bits. */ + unsigned char bus_priority; /**< Internal bus priority. */ + unsigned short timetest_id; /**< Timetest ID. */ + unsigned int stack_size; /**< Thread stack size. */ + void *stack_addr; /**< Pointer to the stack address base. The range of the stack is + (stack_addr, stack_addr+stack_size-1). */ + unsigned short detach_state; /**< Detach state of the thread. */ + +} qurt_thread_attr_t; +/** @endcond */ + +/** @cond rest_reg_dist */ +/** Dynamic TLS attributes. */ +typedef struct qurt_tls_info { + unsigned int module_id; /**< Module ID of the loaded dynamic linked library. */ + unsigned int tls_start; /**< Start address of the TLS data. */ + unsigned int tls_data_end; /**< End address of the TLS RW data. */ + unsigned int tls_end; /**< End address of the TLS data. */ +}qurt_tls_info; +/** @endcond */ + +/** @} */ /* end_addtogroup thread_types */ + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_thread_attr_init + Initializes the structure used to set the thread attributes when a thread is created. + After an attribute structure is initialized, Explicity set the individual attributes in the structure + using the thread attribute operations. + + The initialize operation sets the following default attribute values: \n + - Name -- NULL string \n + - TCB partition -- QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT + - Priority -- QURT_THREAD_ATTR_PRIORITY_DEFAULT \n + - Autostack -- QURT_THREAD_ATTR_AUTOSTACK_DEFAULT \n + - Bus priority -- QURT_THREAD_ATTR_BUS_PRIO_DEFAULT \n + - Timetest ID -- QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT \n + - stack_size -- 0 \n + - stack_addr -- NULL \n + - detach state -- #QURT_THREAD_ATTR_CREATE_LEGACY \n + - STID -- #QURT_THREAD_ATTR_STID_DEFAULT + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_init (qurt_thread_attr_t *attr) +{ + + attr->name[0] = '\0'; + attr->tcb_partition = QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT; + attr->priority = QURT_THREAD_ATTR_PRIORITY_DEFAULT; + attr->autostack = QURT_THREAD_ATTR_AUTOSTACK_DEFAULT; /* Default attribute for autostack v2*/ + attr->bus_priority = QURT_THREAD_ATTR_BUS_PRIO_DEFAULT; + attr->timetest_id = (unsigned short)QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT; + attr->stack_size = 0; + attr->stack_addr = NULL; + attr->detach_state = QURT_THREAD_ATTR_CREATE_LEGACY; + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + attr->group_id = QURT_THREAD_DEFAULT_GROUP_ID; +} + +/**@ingroup func_qurt_thread_attr_set_name + Sets the thread name attribute.\n + This function specifies the name to use by a thread. + Thread names identify a thread during debugging or profiling. + Maximum name length is 16 charactes \n + @note1hang Thread names differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] name Pointer to the character string containing the thread name. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_name (qurt_thread_attr_t *attr, const char *name) +{ + strlcpy (attr->name, name, QURT_THREAD_ATTR_NAME_MAXLEN); + attr->name[QURT_THREAD_ATTR_NAME_MAXLEN - 1] = '\0'; +} + + +/**@ingroup func_qurt_thread_attr_set_tcb_partition + Sets the thread TCB partition attribute. + Specifies the memory type where a TCB of a thread is allocated. + Allocates TCBs in RAM or TCM/LPM. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] tcb_partition TCB partition. Values:\n + - 0 -- TCB resides in RAM \n + - 1 -- TCB resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_tcb_partition (qurt_thread_attr_t *attr, unsigned char tcb_partition) +{ + attr->tcb_partition = tcb_partition; +} + +/**@ingroup func_qurt_thread_attr_set_priority + Sets the thread priority to assign to a thread. + Thread priorities are specified as numeric values in the range 1 to 254, with 1 representing + the highest priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] priority Thread priority. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_priority (qurt_thread_attr_t *attr, unsigned short priority) +{ + attr->priority = priority; +} + +/**@ingroup func_qurt_thread_attr_set_detachstate + Sets the thread detach state with which thread is created. + Thread detach state is either joinable or detached; specified by the following values: + - #QURT_THREAD_ATTR_CREATE_JOINABLE \n + - #QURT_THREAD_ATTR_CREATE_DETACHED \n + + When a detached thread is created (QURT_THREAD_ATTR_CREATE_DETACHED), its thread + ID and other resources are reclaimed as soon as the thread exits. When a joinable thread + is created (QURT_THREAD_ATTR_CREATE_JOINABLE), it is assumed that some + thread waits to join on it using a qurt_thread_join() call. + By default, detached state is QURT_THREAD_ATTR_CREATE_LEGACY + If detached state is QURT_THREAD_ATTR_CREATE_LEGACY then other + thread can join before thread exits but it will not wait other thread to join. + + @note1hang For a joinable thread (QURT_THREAD_ATTR_CREATE_JOINABLE), it is very + important that some thread joins on it after it terminates, otherwise + the resources of that thread are not reclaimed, causing memory leaks. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] detachstate Thread detach state. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_detachstate (qurt_thread_attr_t *attr, unsigned short detachstate) +{ + if(detachstate == QURT_THREAD_ATTR_CREATE_JOINABLE || detachstate == QURT_THREAD_ATTR_CREATE_DETACHED){ + attr->detach_state = detachstate; + } +} + + +/**@ingroup func_qurt_thread_attr_set_timetest_id + Sets the thread timetest attribute.\n + Specifies the timetest identifier to use by a thread. + + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] timetest_id Timetest identifier value. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_thread_attr_set_timetest_id (qurt_thread_attr_t *attr, unsigned short timetest_id) +{ + attr->timetest_id = timetest_id; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute.\n + Specifies the size of the memory area to use for a call stack of a thread. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_size Size (in bytes) of the thread stack. + + @return + None. + + @dependencies + None. +*/ + +static inline void qurt_thread_attr_set_stack_size (qurt_thread_attr_t *attr, unsigned int stack_size) +{ + attr->stack_size = stack_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size2 + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute for island threads that require a higher guest OS stack size than the stack size + defined in the configuration XML.\n + Specifies the size of the memory area to use for a call stack of an island thread in User and Guest mode. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] user_stack_size Size (in bytes) of the stack usage in User mode. + @param[in] root_stack_size Size (in bytes) of the stack usage in Guest mode. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_size2 (qurt_thread_attr_t *attr, unsigned short user_stack_size, unsigned short root_stack_size) +{ + union qurt_thread_stack_info{ + unsigned int raw_size; + struct{ + unsigned short user_stack; + unsigned short root_stack; + }; + }user_root_stack_size; + user_root_stack_size.user_stack = user_stack_size; + user_root_stack_size.root_stack = root_stack_size; + + attr->stack_size = user_root_stack_size.raw_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_addr + @xreflabel{sec:set_stack_addr} + Sets the thread stack address attribute. \n + Specifies the base address of the memory area to use for a call stack of a thread. + + stack_addr must contain an address value that is 8-byte aligned. + + The thread stack address and stack size (Section @xref{sec:set_stack_size}) specify the memory area used as a + call stack for the thread. \n + @note1hang The user is responsible for allocating the memory area used for the thread + stack. The memory area must be large enough to contain the stack that the thread + creates. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_addr Pointer to the 8-byte aligned address of the thread stack. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_addr (qurt_thread_attr_t *attr, void *stack_addr) +{ + attr->stack_addr = stack_addr; +} + +/**@ingroup func_qurt_thread_attr_set_bus_priority + Sets the internal bus priority state in the Hexagon core for this software thread attribute. + Memory requests generated by the thread with bus priority enabled are + given priority over requests generated by the thread with bus priority disabled. + The default value of bus priority is disabled. + + @note1hang Sets the internal bus priority for Hexagon processor version V60 or greater. + The priority is not propagated to the bus fabric. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + + @param[in] bus_priority Enabling flag. Values: \n + - #QURT_THREAD_BUS_PRIO_DISABLED \n + - #QURT_THREAD_BUS_PRIO_ENABLED @tablebulletend + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_bus_priority ( qurt_thread_attr_t *attr, unsigned short bus_priority) +{ + attr->bus_priority = (unsigned char)bus_priority; +} + +/**@ingroup func_qurt_thread_attr_set_autostack + Enables autostack v2 feature in the thread attributes. + + When autostack is enabled by the subsystem, in the case that + an autostack enabled thread gets framelimit exception, kernel will + allocate more stack for thread and return to normal execution. + + If autostack is not enabled by the subsystem, or it is not enabled + for the thread, the framelimit exception will be fatal. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] autostack Autostack enable or disable flag. Values: \n + - #QURT_THREAD_AUTOSTACK_DISABLED \n + - #QURT_THREAD_AUTOSTACK_ENABLED @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_autostack ( qurt_thread_attr_t *attr, unsigned short autostack) +{ + attr->autostack = (unsigned char)autostack; +} +/**@ingroup qurt_thread_attr_enable_stid + Set STID in the thread attributes. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] enable_stid STID to be set. Values: \n + - #QURT_THREAD_ATTR_STID_DEFAULT (0): Default STID. \n + - #QURT_THREAD_ATTR_STID_ENABLE (1): QuRT assigns an STID that is not already in use \n + - #2 through #255 : User provided STID. @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_enable_stid ( qurt_thread_attr_t *attr, char enable_stid) +{ + if (enable_stid != '\0') { + attr->stid = enable_stid; + } + else + { + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + } +} + +/**@ingroup func_qurt_thread_attr_set_stid + Sets the stid thread attribute. + The default stid value is QURT_THREAD_ATTR_STID_DEFAULT + + @note1hang When a thread is created with non default stid , + the stid set in thread attribute will be assigned to a thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] stid Stid to be set for a thread. + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stid( qurt_thread_attr_t *attr, unsigned int stid){ + attr->stid = stid; +} + +/**@ingroup func_qurt_thread_attr_set_group_id + Sets group id in the thread attributes. + Primordial/first thread has group ID 0. + If a new thread is created without assigning group_id, it + inherits the group ID from its parent thread. + + @note1hang + 1) Group ID can only be set before creating a thread. It cannot be + changed after the thread is created. + 2) If a non-activated group_id is passed, thread creation will fail. + 3) Only a thread with Group ID #0 can set Group ID for its child threads. + 4) If thread with non-zero group ID set the group ID for its child threads, + QuRT will ingore this parameter and child threads will inherit the parent + thread's group ID. But if passed group ID is not activated, thread creation + will still fail. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] group_id Group identifier. Its valid range is 0 ~ 63 + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_group_id(qurt_thread_attr_t *attr, unsigned int group_id) +{ + attr->group_id = group_id & QURT_THREAD_GROUP_ID_MASK; +} + +/**@ingroup func_qurt_thread_set_autostack + Sets autostack enable in the TCB. + + @param[in] Pointer to UGP + + @return + None. + + @dependencies + None. +*/ + +void qurt_thread_set_autostack(void *); + + +/**@ingroup func_qurt_thread_get_name + Gets the thread name of current thread.\n + Returns the thread name of the current thread. + Thread names are assigned to threads as thread attributes, see qurt_thread_attr_set_name(). Thread names + identify a thread during debugging or profiling. + + @param[out] name Pointer to a character string, which specifies the address where the returned thread name is stored. + @param[in] max_len Maximum length of the character string that can be returned. + + @return + None. + + @dependencies + None. +*/ +void qurt_thread_get_name (char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_create + @xreflabel{hdr:qurt_thread_create} + Creates a thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + @param[in] entrypoint C function pointer, which specifies the main function of a thread. + @param[in] arg Pointer to a thread-specific argument structure + + + @return + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_thread_create (qurt_thread_t *thread_id, qurt_thread_attr_t *attr, void (*entrypoint) (void *), void *arg); + +/**@ingroup func_qurt_thread_stop + Stops the current thread, frees the kernel TCB, and yields to the next highest ready thread. + + @return + void + + @dependencies + None. + */ +void qurt_thread_stop(void); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_resume + When a demand-loading paging solution is enabled, this function + will resumes the execution of a thread that was suspended due to + a page miss. + + @param[in] thread_id Thread identifier. + + @return + #QURT_EOK -- Thread successfully resumed. \n + #QURT_EFATAL -- Resume operation failed. + + @dependencies + None. + */ +int qurt_thread_resume(unsigned int thread_id); +/** @endcond */ + +/**@ingroup func_qurt_thread_get_id + Gets the identifier of the current thread.\n + Returns the thread identifier for the current thread. + + @return + Thread identifier -- Identifier of the current thread. + + @dependencies + None. + */ +qurt_thread_t qurt_thread_get_id (void); + + +/**@ingroup func_qurt_thread_get_l2cache_partition + Returns the current value of the L2 cache partition assigned to the caller thread.\n + + @return + Value of the #qurt_cache_partition_t data type. + + @dependencies + None. + */ +qurt_cache_partition_t qurt_thread_get_l2cache_partition (void); + +/**@ingroup func_qurt_thread_set_timetest_id + Sets the timetest identifier of the current thread. + Timetest identifiers are used to identify a thread during debugging or profiling.\n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @param[in] tid Timetest identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_timetest_id (unsigned short tid); + +/**@ingroup func_qurt_thread_set_cache_partition + Sets the cache partition for the current thread. This function uses the qurt_cache_partition_t type + to select the cache partition of the current thread for the L1 Icache, L1 Dcache, and L2 cache. + + @datatypes + #qurt_cache_partition_t + + @param[in] l1_icache L1 I cache partition. + @param[in] l1_dcache L1 D cache partition. + @param[in] l2_cache L2 cache partition. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_cache_partition(qurt_cache_partition_t l1_icache, qurt_cache_partition_t l1_dcache, qurt_cache_partition_t l2_cache); + + +/**@ingroup func_qurt_thread_get_timetest_id + Gets the timetest identifier of the current thread.\n + Returns the timetest identifier of the current thread.\n + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @return + Integer -- Timetest identifier. + + @dependencies + None. + */ +unsigned short qurt_thread_get_timetest_id (void); + +/**@ingroup func_qurt_thread_exit + @xreflabel{sec:qurt_thread_exit} + Stops the current thread, awakens threads joined to it, then destroys the stopped + thread. + + Threads that are suspended on the current thread (by performing a thread join + Section @xref{sec:thread_join}) are awakened and passed a user-defined status value + that indicates the status of the stopped thread. + + @note1hang Exit must be called in the context of the thread to stop. + + @param[in] status User-defined thread exit status value. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_exit(int status); + +/**@ingroup func_qurt_thread_join + @xreflabel{sec:thread_join} + Waits for a specified thread to finish; the specified thread is another thread within + the same process. + The caller thread is suspended until the specified thread exits. When the unspecified thread + exits, the caller thread is awakened. \n + @note1hang If the specified thread has already exited, this function returns immediately + with the result value #QURT_ENOTHREAD. \n + @note1cont Two threads cannot call qurt_thread_join to wait for the same thread to finish. + If this occurs, QuRT generates an exception (see Section @xref{sec:exceptionHandling}). + + @param[in] tid Thread identifier. + @param[out] status Destination variable for thread exit status. Returns an application-defined + value that indicates the termination status of the specified thread. + + @return + #QURT_ENOTHREAD -- Thread has already exited. \n + #QURT_EOK -- Thread successfully joined with valid status value. + + @dependencies + None. + */ +int qurt_thread_join(unsigned int tid, int *status); + +/**@ingroup qurt_thread_detach + @xreflabel{sec:thread_detach} + Detaches a joinable thread. The specified thread is another thread within the + same process. Create the thread as a joinable thread; only joinable threads + can be detached. + If a joinable thread is detached, it finishes execution and exits. + + @param[in] tid Thread identifier. + + @return + #QURT_ENOTHREAD -- Thread specifed by TID does not exist. \n + #QURT_EOK -- Thread successfully detached. + + @dependencies + None. + */ +int qurt_thread_detach(unsigned int tid); + + +/**@ingroup func_qurt_thread_get_priority + Gets the priority of the specified thread. \n + Returns the thread priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. \n + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + + @return + -1 -- Invalid thread identifier. \n + 1 through 254 -- Thread priority value. + + @dependencies + None. + */ +int qurt_thread_get_priority (qurt_thread_t threadid); + +/**@ingroup func_qurt_thread_set_priority + Sets the priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. For more + information, see Section @xref{sec:AppDev}. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + @param[in] newprio New thread priority value. + + @return + 0 -- Priority successfully set. \n + -1 -- Invalid thread identifier. \n + + @dependencies + None. + */ +int qurt_thread_set_priority (qurt_thread_t threadid, unsigned short newprio); + + + +/**@ingroup func_qurt_thread_attr_get + Gets the attributes of the specified thread. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[out] attr Pointer to the destination structure for thread attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid argument. + + @dependencies + None. + */ +int qurt_thread_attr_get (qurt_thread_t thread_id, qurt_thread_attr_t *attr); + + + +/**@ingroup func_qurt_thread_get_tls_base + Gets the base address of thread local storage (TLS) of a dynamically loaded module + for the current thread. + + @datatypes + #qurt_tls_info + + @param[in] info Pointer to the TLS information for a module. + + @return + Pointer to the TLS object for the dynamically loaded module.\n + NULL -- TLS information is invalid. + + @dependencies + None. + */ +void * qurt_thread_get_tls_base(qurt_tls_info* info); + +/**@ingroup func_qurt_thread_pktcount_get + Gets the PKTCOUNT of a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + PKTCOUNT + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_get (qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_pktcount_set + Sets the PKTCOUNT for the current QuRT thread. + + @return + Value to which pktcount is set. + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_set (long long int); + +/**@ingroup func_qurt_thread_stid_get + Gets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + STID + + @dependencies + None. + */ + +char qurt_thread_stid_get(qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_stid_get2 + Returns the set stid for a thread + + @param[in] thread_id thread identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - success + QURT_ENOTALLOWED - operation not allowed for a thread + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_thread_stid_get2(unsigned int thread_id, unsigned int *stid); + +/**@ingroup func_qurt_thread_stid_set + Sets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] stid Thread identifier. + + @return + #QURT_EOK -- STID set created. \n + #QURT_EFAILED -- STID not set. + + @dependencies + None. + */ + +int qurt_thread_stid_set(char stid); + +/**@ingroup qurt_thread_stid_set2 + Sets the stid for a specified thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[in] stid Stid to be set for a thread. + + @return + QURT_EOK -- Success + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_EVAL -- Failure because of invalid inputs. + + @dependencies + None. +*/ +int qurt_thread_stid_set2(unsigned int thread_id, unsigned int stid); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_get_running_ids + Returns the thread IDs of the running threads in the system; use only during fatal error handling. + + @datatypes + #qurt_thread_t + + @param[in,out] * Array of thread identifier of size #QURT_MAX_HTHREAD_LIMIT + 1. + + @return + #QURT_EINVALID -- Incorrect argument \n + #QURT_ENOTALLOWED -- API not called during error handling \n + #QURT_EOK -- Success, returns a NULL-terminated array of thread_id + + @dependencies + None. + */ +int qurt_thread_get_running_ids(qurt_thread_t *); +/** @endcond */ + + +/**@ingroup func_qurt_thread_get_thread_id + Gets the thread identifier of the thread with the matching name in the same process + of the caller. + + @datatypes + #qurt_thread_t + + @param[out] thread_id Pointer to the thread identifier. + @param[in] name Pointer to the name of the thread. + + @return + #QURT_EINVALID -- No thread with matching name in the process of the caller \n + #QURT_EOK -- Success + + @dependencies + None. + */ +int qurt_thread_get_thread_id (qurt_thread_t *thread_id, char *name); + +/**@ingroup func_qurt_sleep + Suspends the current thread for the specified amount of time. + + @note1hang Because QuRT timers are deferrable, this call is guaranteed to block + at least for the specified amount of time. If power-collapse is + enabled, the maximum amount of time this call can block depends on + the earliest wakeup from power-collapse past the specified duration. + + @param[in] duration Duration (in microseconds) for which the thread is suspended. + + @return + None. + + @dependencies + None. + */ +void qurt_sleep (unsigned long long int duration); + + +/**@ingroup func_qurt_system_set_priority_floor + Sets a priority floor to move threads with thread priority lower than the floor out of the running state. + Running threads with thread priority lower than the priority floor are moved into the kernel ready queue, and they + are not scheduled to run when the thread priority is lower than the floor. + Later the caller should reset the priority floor back to the default value of QURT_PRIORITY_FLOOR_DEFAULT. + Threads in the kernel ready queue are scheduled to run when the thread priority is higher than the floor. + + The priority floor is set and associated to the user process of the caller. When the caller gets into QuRTOS and + sets a new floor, the new floor is associated to its original user process, not the QuRTOS process. + The floor associated to the user process is reset when the user process exits or is killed, but not at the time + when the user thread of the caller exits. + + The priority floor cannot be set to a priority higher than the thread priority of the caller. + + The priority floor cannot be set to a priority lower than the default #QURT_PRIORITY_FLOOR_DEFAULT system floor. + + This function is not supported in Island mode. + + After the system floor is set above QURT_PRIORITY_FLOOR_DEFAULT, power collapse is skipped, and sleep task + is not scheduled to run. + + @param[in] priority_floor Priority floor. + + @return + #QURT_EOK -- Success \n + #QURT_ENOTALLOWED -- Floor setting is not allowed + + @dependencies + None. + */ +int qurt_system_set_priority_floor (unsigned int priority_floor); + + +/**@ingroup func_qurt_thread_suspend_thread + Suspend a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent process. + After the target thread is suspended, the kernel will not schedule it to run until it is resumed later. + + If the target thread is set as non-suspendable, this function call returns an error without suspending + the target thread. + + If the target thread is already suspended, this function call returns success to confirm + the target thread suspend. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + suspending the target thread. + + If the target thread is running in the guest OS/root process via a QDI call, this function call does not suspend + the target thread in guest OS, but marks the target thread as suspend-pending. The target thread is + suspended when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success even with the #QURT_THREAD_SUSPEND_SYNCHRONOUS option, while the target + thread can runn in the guest OS, and is suspended when exiting the guest OS. + + QuRT debug monitor threads that are in a user process are non-suspendable. This function does not suspend + those threads. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, multiple options can be ORed. \n + #QURT_THREAD_SUSPEND_SYNCHRONOUS (default) -- set to synchronous function call, + the function returns after the thread is completely suspended.\n + #QURT_THREAD_SUSPEND_ASYNCHRONOUS -- set to asynchronous function call, the function returns + after the kernel acts to suspend the target thread. The target thread + might still be running before it is completely suspended. \n + #QURT_THREAD_SUSPEND_KEEP_HMX (default) -- keep the HMX attachment on the target thread + if it locks the HMX with qurt_hmx_lock(). In this case, the HMX cannot be re-used by other threads. \n + #QURT_THREAD_SUSPEND_DETACH_HMX -- detach HMX from the target thread if it locks the HMX with qurt_hmx_lock(). + Later when the target thread resumes, the HMX is re-attached to the thread. Note that, this option is only + supported for the caller from the same user process of the target thread, not for a caller from the parent + process of the target thread, or other processes. With the HMX detach option, Qurt does not save the HMX + context. Thus, the HMX context state will be lost. It is the responsibility of caller to ensure HMX operations + and its context state saving when calling qurt_thread_suspend_thread() with the HMX detach option. + If a thread from another process uses this detach option, QURT_EHMXNOTDETACHABLE will be returned; in this + case, if the caller is qualified to suspend the target thread, the target thread will be moved to suspended + state without HMX detached. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in secure process/CPZ process. + #QURT_EHMXNOTDETACHABLE -- Failure because HMX is not detachable from the target thread. + + @dependencies + None. + */ +int qurt_thread_suspend_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_resume_thread + Resume a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent + process. After the target thread resumes, the kernel scheduler can schedule the thread to run based on + the thread priority. + + There is an option argument in this function, with only one default option as of now, + QURT_THREAD_RESUME_DEFAULT: resume the target thread in default way. + + By default, this is an asynchronous function. The function returns after kernel moves the + target thread from suspended state to runnable state. The thread is scheduled to run based on its + thread priority. + + If the target thread is set as non-resumable, this function call does not resume the target thread. + + If the target thread has already resumed, this function confirms that the target thread resumes + by returning success. + + If the target thread is in a secure user process or CPZ process, this function call returns an error without + resuming the operation. + + If the target thread runs in the guest OS/root process via a QDI call, this function call clears the mark of + suspend-pending on the target thread, and the target thread is not suspended when it exits the + guest OS. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, #QURT_THREAD_RESUME_DEFAULT, which resumes the target thread. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + #QURT_EHMXNOTAVAIL -- Failure because when resume a HMX thread, the HMX is not available/free for the HMX thread resume. + + @dependencies + None. + */ +int qurt_thread_resume_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_set_thread_property + Set a QuRT thread property with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be from the same user process of the target thread, or from its parent process. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + changing the property of the target thread. + + @param[in] thread_id Thread identifier \n + @param[in] property_id Thread property identifier \n + #QURT_THREAD_PROPERTY_SUSPENDABLE -- thread is suspendable. Default is TRUE. \n + #QURT_THREAD_PROPERTY_RESUMEABLE -- thread is resumable. Default is TRUE + @param[in] value Proper value: \n + TRUE(1) -- TRUE for the property \n + FALSE(0) -- FALSE for the property + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_thread_set_thread_property( unsigned int thread_id, unsigned int property_id, unsigned int value ); + +/**@ingroup func_qurt_thread_get_group_id + Get the group id of the thread specified by thread_id.\n + + @param[in] thread_id Thread identifier + @param[out] group_id Pointer to the variable of group identifier + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Thread id is invalid, or the process has no groups enabled \n + #QURT_ENOTALLOWED -- Operation is not allowed \n + + @dependencies + None. +*/ +int qurt_thread_get_group_id(qurt_thread_t thread_id, unsigned int* group_id); + +#endif /* __ASSEMBLER__ */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread_context.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread_context.h new file mode 100755 index 0000000000000..bab09deec8889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_thread_context.h @@ -0,0 +1,234 @@ +#ifndef QURT_THREAD_CONTEXT_H +#define QURT_THREAD_CONTEXT_H +/** + @file qurt_thread_context.h + @brief Kernel thread context structure + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond internal_only */ + +#define THREAD_ITERATOR_END ((qurt_thread_t)(-1)) /**< Thread iterator is complete. */ + + +/**@ingroup func_qurt_thread_iterator_create +Gives the ability to the caller to enumerate threads in the system. + +@return +Handle of the newly created iterator must be passed for +subsequent operations on the iterator. + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_create(void) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_OS_THREAD_ITERATOR_CREATE); +} + +/**@ingroup func_qurt_thread_iterator_next +Iterates over the list of threads in the system. + +@datatypes +#qurt_thread_t + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#THREAD_ITERATOR_END -- iterator has reached the end of the thread list. \n +Other values indicate a valid thread_id. + +@dependencies +None. +*/ +static inline qurt_thread_t qurt_thread_iterator_next(int iter) +{ + return (qurt_thread_t)qurt_qdi_handle_invoke(iter, QDI_OS_THREAD_ITERATOR_NEXT); +} + +/**@ingroup func_qurt_thread_iterator_destroy +Cleans up thread iterator resources. + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#QURT_EOK -- Successful completion of operation \n +#QURT_EFATAL -- Invalid handle passed + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_destroy(int iter) +{ + return qurt_qdi_close(iter); +} + +/**@ingroup func_qurt_thread_context_get_tname +Gets the name of the thread from the specified thread ID. + +@param[in] thread_id Thread for which name is returned. +@param[in,out] name Pointer to the local buffer where name is copied back. +@param[in] max_len Size of the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_tname(unsigned int thread_id, char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_context_get_prio +Gets the priority for the specified thread. + +@param[in] thread_id Thread for which priority is returned. +@param[in,out] prio Pointer to the local variable where priority is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_prio(unsigned int thread_id, unsigned char *prio); + +/**@ingroup func_qurt_thread_context_get_pcycles +Gets pcycles for the specified thread. + +@param[in] thread_id Thread for which processor cycles are returned. +@param[in,out] pcycles Pointer to the local variable where processor cycles are written. + +@return +#QURT_EOK -- Success \n +Failure otherwise. + +@dependencies +None. +*/ +int qurt_thread_context_get_pcycles(unsigned int thread_id, unsigned long long int *pcycles); + +/**@ingroup func_qurt_thread_context_get_stack_base +Gets the stack base address for the specified thread. + +@param[in] thread_id Thread for which stack base address is returned. +@param[in,out] sbase Pointer to the local variable where stack base address is written. + +@return +QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_base(unsigned int thread_id, unsigned int *sbase); + +/**@ingroup func_qurt_thread_context_get_stack_size +Gets the stack size for the specified thread. + +@param[in] thread_id Thread for which stack size is returned. +@param[in,out] ssize Pointer to the local variable where stack size is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_size(unsigned int thread_id, unsigned int *ssize); + +/**@ingroup func_qurt_thread_context_get_pid +Gets the process ID for the specified thread. + +@param[in] thread_id Thread for which process ID is returned. +@param[in,out] pid Pointer to the local variable where process id is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pid(unsigned int thread_id, unsigned int *pid); + +/**@ingroup func_qurt_thread_context_get_pname +Gets the process name for the specified thread. + +@param[in] thread_id Represents the thread for which process name is returned. +@param[in, out] name Pointer to the local buffer where process name is copied back. +@param[in] len Length allocated to the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pname(unsigned int thread_id, char *name, unsigned int len); + +/** @addtogroup thread_types +@{ */ +/** Structure that defines how TCB is interpreted to crash dump tools.*/ +/* Keys are defined in consts.h */ +struct qurt_debug_thread_info { +/** @cond */ + char name[QURT_MAX_NAME_LEN]; /**< Name of the thread. */ + struct { + unsigned key; + unsigned val; + } os_info[40]; + unsigned gen_regs[32]; /**< General mode registers. */ + unsigned user_cregs[32]; /**< User mode registers. */ + unsigned guest_cregs[32]; /**< Guest mode registers. */ + unsigned monitor_cregs[64]; /**< Monitor mode registers. */ +/** @endcond */ +}; /* should add up to 1K */ +/** @} */ /* end_addtogroup thread_types */ + + +/**@ingroup func_qurt_system_tcb_dump_get +Cleans up thread iterator resources. + +@datatypes +#qurt_thread_t + +@param[in] thread_id Thread on which the operation must be performed. +@param[in, out] ptr Pointer to the local buffer where contents are written. +@param[in] size Size of the debug thread information structure obtained by calling + qurt_system_tcb_dump_get_size(). + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_system_tcb_dump_get(qurt_thread_t thread_id, void *ptr, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_CONTEXT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_timer.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_timer.h new file mode 100755 index 0000000000000..7bdfdb8f3c3df --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_timer.h @@ -0,0 +1,560 @@ +#ifndef QURT_TIMER_H +#define QURT_TIMER_H +/** + @file qurt_timer.h + @brief Prototypes of qurt_timer API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include "qurt_anysignal.h" +#include "qurt_signal2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@addtogroup timer_const_macros +@{ */ +/** + Default values. +*/ +/** @xreflabel{hdr:QURT_TIMER_ONESHOT}*/ +#define QURT_TIMER_DEFAULT_TYPE QURT_TIMER_ONESHOT /**< One shot.*/ +#define QURT_TIMER_DEFAULT_DURATION 1000uL /**< Default duration. */ +#define QURT_TIMER_DEFAULT_EXPIRY 0uL /**< Default expiration. */ + +/** + Conversion from microseconds to timer ticks. + */ +#define QURT_TIMER_TIMETICK_FROM_US(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_TIMER_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** Minimum microseconds value is 100 microseconds (sleep timer).*/ +#define QURT_TIMER_MIN_DURATION 100uL + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_TIMER_MAX_DURATION QURT_SYSCLOCK_MAX_DURATION + +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_TIMER_MAX_DURATION_TICKS QURT_SYSCLOCK_MAX_DURATION_TICKS + +/** + Sleep timer error margin for Qtimer is 1,000 ticks ~52 us. +*/ +#define QURT_TIMETICK_ERROR_MARGIN QURT_SYSCLOCK_ERROR_MARGIN + +/* + qurt_timer group defines. +*/ +#define QURT_TIMER_MAX_GROUPS 5U /**< Maximum groups.*/ +#define QURT_TIMER_DEFAULT_GROUP 0U /**< Default groups. */ +/** @} */ /* end_addtogroup timer_const_macros */ + +/** @addtogroup timer_types +@{ */ +/** + QuRT timer types. + */ +typedef enum +{ + QURT_TIMER_ONESHOT = 0, /**< One shot.*/ + /** @xreflabel{hdr:QURT_TIMER_PERIODIC}*/ + QURT_TIMER_PERIODIC /**< Periodic. */ +} qurt_timer_type_t; + + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT timer type.*/ +typedef unsigned int qurt_timer_t; + +/** QuRT timer duration type. */ +typedef unsigned long long qurt_timer_duration_t; + +/** QuRT timer time type. */ +typedef unsigned long long qurt_timer_time_t; + +typedef void (*pfn_t)(void); +/** QuRT timer attribute type. */ +typedef struct +{ + /** @cond */ + unsigned int magic; /**< Magic number to verify the qmsgq_attr_t pointer. */ + + qurt_timer_duration_t duration; /**< Specifies the duration of the new timer. */ + + qurt_timer_time_t expiry; /**< Specifies the absolute expiry of the new timer. */ + + qurt_timer_duration_t remaining; /**< Specifies the remaining time of an active timer. */ + + qurt_timer_type_t type; /**< Specifies the timer type; only #QURT_TIMER_ONESHOT and + #QURT_TIMER_PERIODIC are supported. */ + + unsigned int group; /**< Group number of the timer; the criterion used to disable or enable the set + of timers. */ + pfn_t pFn; /**< Callback other than the signal set */ + /** @endcond */ +} +qurt_timer_attr_t; + +/** @} */ /* end_addtogroup timer_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_timer_stop + @xreflabel{sec:qurt_timer_stop} + Stops a running timer. + The timer must be a one-shot timer. + + @note1hang Restart stopped timers with the timer restart operation, + see Section @xref{sec:qurt_timer_restart}. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one shot timer. \n + #QURT_EMEM -- Out of memory error. + + @dependencies + None. + */ +int qurt_timer_stop (qurt_timer_t timer); + +/**@ingroup func_qurt_timer_restart + @xreflabel{sec:qurt_timer_restart} + Restarts a stopped timer with the specified duration. The timer must be a one-shot timer. + Timers stop after they have expired or after they are explicitly stopped with qurt_timer_stop(). + A restarted timer expires after the specified duration, the starting time is when the function is called. + + @note1hang Timers stop after they have expired or after they are explicitly + stopped with the timer stop operation, see Section @xref{sec:qurt_timer_stop}. + + @datatypes + #qurt_timer_t \n + #qurt_timer_duration_t + + @param[in] timer Timer object. + @param[in] duration Timer duration (in microseconds) before the restarted timer + expires again. + The valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one-shot timer. \n + #QURT_EMEM -- Out-of-memory error. + + @dependencies + None. + */ +int qurt_timer_restart (qurt_timer_t timer, qurt_timer_duration_t duration); + + +/**@ingroup func_qurt_timer_create + Creates a timer.\n + Allocates and initializes a timer object, and starts the timer. + + @note1hang A timer event handler must be defined to wait on the specified signal + to handle the timer event. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t \n + #qurt_anysignal_t + + @param[out] timer Pointer to the created timer object. + @param[in] attr Pointer to the timer attribute structure. + @param[in] signal Pointer to the signal object set when timer expires. + @param[in] mask Signal mask, which specifies the signal to set in the signal object when the + time expires. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to create the timer. \n + #QURT_EINVALID -- One of the arguments in the attr field is invalid. \n + Other error code -- Operation failed. \n + + @dependencies + None. + */ +int qurt_timer_create (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_anysignal_t *signal, unsigned int mask); + +int qurt_timer_create_sig2 (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_timer_attr_init + Initializes the specified timer attribute structure with default attribute values: \n + - Timer duration -- #QURT_TIMER_DEFAULT_DURATION (Section @xref{dox:timers}) \n + - Timer type -- #QURT_TIMER_ONESHOT \n + - Timer group -- #QURT_TIMER_DEFAULT_GROUP + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_init(qurt_timer_attr_t *attr); + + +/*Tech Comm note: removed qurt_timer_attr_set_pfn from documentation 9/10/2020 +@ingroup func_qurt_timer_attr_set_pfn + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + @param[in] pFn pFn. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_pfn(qurt_timer_attr_t *attr, pfn_t pFn); + + +/**@ingroup func_qurt_timer_attr_set_duration + Sets the timer duration in the specified timer attribute structure.\n + + The timer duration specifies the interval (in microseconds) between the creation of the + timer object and the generation of the corresponding timer event. + + The timer duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). Otherwise, the set operation is ignored. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] duration Timer duration (in microseconds). + Valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_attr_set_expiry + Sets the absolute expiry time in the specified timer attribute structure.\n + The timer expiry specifies the absolute time (in microseconds) of the generation of the + corresponding timer event.\n + Timer expiries are relative to when the system first began executing. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_time_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] time Timer expiry. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_expiry(qurt_timer_attr_t *attr, qurt_timer_time_t time); + +/**@ingroup func_qurt_timer_attr_get_duration + Gets the timer duration from the specified timer attribute structure. + The value returned is the duration that was originally set for the timer. + + @note1hang This function does not return the remaining time of an active timer; + use qurt_timer_attr_get_remaining() to get the remaining time. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attributes object + @param[out] duration Pointer to the destination variable for timer duration. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t *duration); + +/**@ingroup func_qurt_timer_attr_get_remaining + Gets the timer remaining duration from the specified timer attribute structure. \n + + The timer remaining duration indicates (in microseconds) how much time remains before + the generation of the next timer event on the corresponding timer. + In most cases this function assumes that the timer attribute structure was obtained by + calling qurt_timer_get_attr(). + + @note1hang This attribute is read-only and thus has no set operation defined for it. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attribute object. + @param[out] remaining Pointer to the destination variable for remaining time. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_remaining(qurt_timer_attr_t *attr, qurt_timer_duration_t *remaining); + +/**@ingroup func_qurt_timer_attr_set_type + Sets the timer type in the specified timer attribute structure. + + The timer type specifies the functional behavior of the timer: \n + - A one-shot timer (#QURT_TIMER_ONESHOT) waits for the specified timer duration + and then generates a single timer event. After this the timer is nonfunctional. \n + - A periodic timer (#QURT_TIMER_PERIODIC) repeatedly waits for the specified + timer duration and then generates a timer event. The result is a series of timer + events with interval equal to the timer duration. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] type Timer type. Values are: \n + - #QURT_TIMER_ONESHOT -- One-shot timer. \n + - #QURT_TIMER_PERIODIC -- Periodic timer. @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_type(qurt_timer_attr_t *attr, qurt_timer_type_t type); + +/**@ingroup func_qurt_timer_attr_get_type + Gets the timer type from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] type Pointer to the destination variable for the timer type. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_type(qurt_timer_attr_t *attr, qurt_timer_type_t *type); + +/**@ingroup func_qurt_timer_attr_set_group + Sets the timer group identifier in the specified timer attribute structure.\n + The timer group identifier specifies the group that the timer belongs to. Timer groups are + used to enable or disable one or more timers in a single operation. \n + The timer group identifier value must be between 0 and (#QURT_TIMER_MAX_GROUPS - 1). + See Section @xref{dox:timers}. + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the timer attribute object. + @param[in] group Timer group identifier; + Valid range is 0 to (#QURT_TIMER_MAX_GROUPS - 1). + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_group(qurt_timer_attr_t *attr, unsigned int group); + +/**@ingroup func_qurt_timer_attr_get_group + Gets the timer group identifier from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] group Pointer to the destination variable for the timer group identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_group(qurt_timer_attr_t *attr, unsigned int *group); + +/**@ingroup func_qurt_timer_get_attr + @xreflabel{hdr:qurt_timer_get_attr} + Gets the timer attributes of the specified timer when it was created. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t + + @param[in] timer Timer object. + @param[out] attr Pointer to the destination structure for timer attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_get_attr(qurt_timer_t timer, qurt_timer_attr_t *attr); + +/**@ingroup func_qurt_timer_delete + Deletes the timer.\n + Destroys the specified timer and deallocates the timer object. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_delete(qurt_timer_t timer); + +/**@ingroup func_qurt_timer_sleep + Suspends the current thread for the specified amount of time. + The sleep duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). + + @datatypes + #qurt_timer_duration_t + + @param[in] duration Interval (in microseconds) between when the thread is suspended + and when it is re-awakened. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to perform the operation. + + @dependencies + None. + */ + +int qurt_timer_sleep(qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_group_disable + Disables all timers that are assigned to the specified timer group. + If a specified timer is already disabled, ignore it. + If a specified timer is expired, do not process it. + If the specified timer group is empty, do nothing. + + @note1hang When a timer is disabled its remaining time does not change, thus it + cannot generate a timer event. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_disable (unsigned int group); + +/**@ingroup func_qurt_timer_group_enable + Enables all timers that are assigned to the specified timer group. + If a specified timer is already enabled, ignore it. + If a specified timer is expired, process it. + If the specified timer group is empty, do nothing. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_enable (unsigned int group); + + +/** + Notifies the timer server recovery from power collapse. The server + must account for any missed interrupts during power collapse. + */ +void qurt_timer_recover_pc (void); + +/** + Determines whether the Qtimer is initialized. + + @return + 0 -- Not initialized. \n + Nonzero -- Initialized. + */ +static inline int qurt_timer_is_init (void) {return 1;} + +/**@ingroup func_qurt_timer_get_ticks + Gets current ticks. The ticks are accumulated since the RTOS + has started. Each tick is equal to a single timer clock + cycle, where the frequency is 32 KHz on RGPT or 19.2 MHz on Qtimer. + + @return + Ticks since system started. + */ +unsigned long long qurt_timer_get_ticks (void); + +#define qurt_timer_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TIMER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tlb.h new file mode 100755 index 0000000000000..b1b2d261d31c0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tlb.h @@ -0,0 +1,215 @@ +#ifndef QURT_TLB_H +#define QURT_TLB_H + +/** + @file qurt_tlb.h + @brief Prototypes of TLB API + The TLB APIs allow explicit control of the portion of TLB between TLB_first_replaceble and TLB_LAST_REPLACEABLE. + Both are nonconfigurable for the time being. This portion of TLB is permanently assigned/locked unless manually removed + by qurt_tlb_remove. Implementation does not change depending on the configuration, such as whether CONFIG_STATIC is set or not. + In CONFIG_STATIC=y, TLB_LAST_REPLACEABLE is set to the last TLB index, which indicates that the entire TLB is permanently + assigned and is not backed up by page table (page table does not exist). TLB indicies are maintained through a 64-bit bitmask. + A new entry is placed in the first available slot. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tlb_entry_create + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (such as if the address is not aligned with the + size), the entry is created and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the ASID argument to -1. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr Physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry is not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry is not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry is not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_t paddr, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_create_64 + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (the address is not aligned with the + size), the entry is not created, and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the asid argument to -1. + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr_64 64-bit physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry was not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry was not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry was not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create_64 (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_delete + Deletes the specified TLB entry from the TLB of the Hexagon processor. + If the specified entry does not exist, no deletion occurs and an error result is returned. + + @param[in] entry_id TLB entry identifier. + + @return + #QURT_EOK -- TLB entry successfully deleted. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_delete (unsigned int entry_id); + +/**@ingroup func_qurt_tlb_entry_query + Searches for the specified TLB entry in the TLB of the Hexagon processor. + If the TLB entry is found, its entry identifier is returned. + + @datatypes + #qurt_addr_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_query (unsigned int *entry_id, qurt_addr_t vaddr, int asid); + +/**@ingroup func_qurt_tlb_entry_set + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[in] entry 64-bit TLB entry to store. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set (unsigned int entry_id, unsigned long long int entry); + +/**@ingroup func_qurt_tlb_entry_get + Gets the TLB entry. \n + Returns the specified 64-bit TLB entry in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[out] entry 64-bit TLB entry. + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_get (unsigned int entry_id, unsigned long long int *entry); + +/**@ingroup func_qurt_tlb_get_pager_physaddrs + Searches the TLB of the Hexagon processor, and returns all physical addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_phys_addrs Pointer to the return array of pager physical addresses. + + @return + Integer -- Number of addresses returned in array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_physaddr(unsigned int** pager_phys_addrs); + +/**@ingroup func_qurt_tlb_get_pager_virtaddr + Searches the TLB of the Hexagon processor, and returns all virtual addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_virt_addrs Pointer to the return array of pager virtual addresses. + + @return + Integer -- Number of addresses returned in the array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_virtaddr(unsigned int** pager_virt_addrs); + + +/**@ingroup func_qurt_tlb_entry_set2 + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. An additional option can be passed + to lock the TLB entry in the TLB of the Hexagon processor. + + @param[in] id TLB entry identifier. + @param[in] tlb 64-bit TLB entry to store. + @param[in] lock Nonzero value indicates that the TLB entry must be locked in the hardware TLB. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set2(unsigned id, unsigned long long tlb, unsigned lock); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLB_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tls.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tls.h new file mode 100755 index 0000000000000..6ec3b39ff5cb0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_tls.h @@ -0,0 +1,100 @@ +#ifndef QURT_TLS_H +#define QURT_TLS_H +/** + @file qurt_tls.h + @brief Prototypes of TLS APIs + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tls_create_key + @xreflabel{sec:tls_create_key} + Creates a key for accessing a thread local storage data item.\n + Subsequent get and set operations use the key value. + + @note1hang The destructor function performs any clean-up operations needed by a thread + local storage item when its containing thread is deleted (Section @xref{sec:qurt_thread_exit}). + + @param[out] key Pointer to the newly created thread local storage key value. + @param[in] destructor Pointer to the key-specific destructor function. Passing NULL + specifies that no destructor function is defined for the key. + + @return + #QURT_EOK -- Key successfully created. \n + #QURT_ETLSAVAIL -- No free TLS key available. + + @dependencies + None. + */ +int qurt_tls_create_key (int *key, void (*destructor)(void *)); + +/**@ingroup func_qurt_tls_set_specific + Stores a data item to thread local storage along with the specified key. + + @param[in] key Thread local storage key value. + @param[in] value Pointer to user data value to store. + + @return + #QURT_EOK -- Data item successfully stored. \n + #QURT_EINVALID -- Invalid key. \n + #QURT_EFAILED -- Invoked from a non-thread context. + */ +int qurt_tls_set_specific (int key, const void *value); + +/**@ingroup func_qurt_tls_get_specific + Loads the data item from thread local storage. \n + Returns the data item that is stored in thread local storage with the specified key. + The data item is always a pointer to user data. + + @param[in] key Thread local storage key value. + + @return + Pointer -- Data item indexed by key in thread local storage. \n + 0 (NULL) -- Key out of range. + + @dependencies + None. + */ +void * __attribute__((section(".text.qurt_tls_get_specific "))) qurt_tls_get_specific (int key); + + +/**@ingroup func_qurt_tls_delete_key + Deletes the specified key from thread local storage. + + @note1hang Explicitly deleting a key does not execute any destructor function that is + associated with the key (Section @xref{sec:tls_create_key}). + + @param[in] key Thread local storage key value to delete. + + @return + #QURT_EOK -- Key successfully deleted. \n + #QURT_ETLSENTRY -- Key already free. + + @dependencies + None. + */ +int qurt_tls_delete_key (int key); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_trace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_trace.h new file mode 100755 index 0000000000000..541f8f1d34bf6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_trace.h @@ -0,0 +1,317 @@ +#ifndef QURT_TRACE_H +#define QURT_TRACE_H +/** + @file qurt_trace.h + @brief Prototypes of system call tracing helpers API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + GLOBAL VARIABLES +=============================================================================*/ +/** @cond internal_only */ +/** @addtogroup etm_macros +@{ */ +/* ETM trace types. */ +#define QURT_ETM_TYPE_PC_ADDR (1U<<0) /**< PC address.*/ +#define QURT_ETM_TYPE_MEMORY_ADDR (1U<<1) /**< Memory address. */ +#define QURT_ETM_TYPE_TESTBUS (1U<<2) /**< Test bus. */ +#define QURT_ETM_TYPE_CYCLE_ACCURATE (1U<<3) /**< Cycle accurate. */ +#define QURT_ETM_TYPE_CYCLE_COARSE (1U<<4) /**< Cycle coarse. */ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR) /**< PC and memory address. */ +#define QURT_ETM_TYPE_PC_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC address and test bus. */ +#define QURT_ETM_TYPE_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< Memory address and test bus.*/ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC, memory address, and test bus. */ + +/* ETM routes. */ +#define QURT_ETM_ROUTE_TO_QDSS 0U /**< ETM route to QDSS. */ +#define QURT_ETM_ROUTE_TO_Q6ETB 1U /**< ETM route to Q6ETB. */ + +/* ETM filters. */ +#define QURT_ETM_TRACE_FILTER_ALL_DEFAULT 0U /*< Filter all as default. */ +#define QURT_ETM_TRACE_FILTER_HNUM0 (1U<<0) /*< Filter HNUM0. */ +#define QURT_ETM_TRACE_FILTER_HNUM1 (1U<<1) /*< Filter HNUM1. */ +#define QURT_ETM_TRACE_FILTER_HNUM2 (1U<<2) /*< Filter HNUM2. */ +#define QURT_ETM_TRACE_FILTER_HNUM3 (1U<<3) /*< Filter HNUM3. */ +#define QURT_ETM_TRACE_FILTER_HNUM4 (1U<<4) /*< Filter HNUM4. */ +#define QURT_ETM_TRACE_FILTER_HNUM5 (1U<<5) /*< Filter HNUM5. */ +#define QURT_ETM_TRACE_FILTER_HNUM6 (1U<<6) /*< Filter HNUM6. */ +#define QURT_ETM_TRACE_FILTER_HNUM7 (1U<<7) /*< Filter HNUM7. */ +#define QURT_ETM_TRACE_FILTER_HNUM8 (1U<<8) /*< Filter HNUM8. */ +#define QURT_ETM_TRACE_FILTER_HNUM9 (1U<<9) /*< Filter HNUM9. */ +#define QURT_ETM_TRACE_FILTER_HNUM10 (1U<<10) /*< Filter HNUM10. */ +#define QURT_ETM_TRACE_FILTER_HNUM11 (1U<<11) /*< Filter HNUM11. */ +#define QURT_ETM_TRACE_FILTER_HNUM12 (1U<<12) /*< Filter HNUM12. */ +#define QURT_ETM_TRACE_FILTER_HNUM13 (1U<<13) /*< Filter HNUM13. */ +#define QURT_ETM_TRACE_FILTER_HNUM14 (1U<<14) /*< Filter HNUM14. */ +#define QURT_ETM_TRACE_FILTER_HNUM15 (1U<<15) /*< Filter HNUM15. */ +#define QURT_ETM_TRACE_FILTER_ALL QURT_ETM_TRACE_FILTER_ALL_DEFAULT + +#define QURT_ETM_TRACE_FILTER_CLUSTER0 (1<<16) /*< Filter trace cluster0 address. */ +#define QURT_ETM_TRACE_FILTER_CLUSTER1 (1<<17) /*< Filter trace cluster1 address. */ +#define QURT_ETM_TRACE_FILTER_PC_RANGE (1<<19) /*< Filter PC address range. */ + +/* ETM memory source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< ETM memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< ETM memory source of SAC* is data. */ + +/* Period between synchronization traces */ +#define QURT_ETM_ASYNC_PERIOD 0 /**< Async.*/ +#define QURT_ETM_ISYNC_PERIOD 1 /**< Isync.*/ +#define QURT_ETM_GSYNC_PERIOD 2 /**< Gsync. */ + +/* ETM enable flags */ +#define QURT_ETM_OFF 0U /**< ETM off. */ +#define QURT_ETM_ON 1U /**< ETM on. */ +/** @endcond */ +/** @} */ /* end_addtogroup etm_macros */ + +/** @addtogroup function_tracing_macro +@{ */ +/* ETM setup return values */ +#define QURT_ETM_SETUP_OK 0 /**< ETM setup OK. */ +#define QURT_ETM_SETUP_ERR 1 /**< ETM setup error. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* ETM breakpoint types */ +#define QURT_ETM_READWRITE_BRKPT 0U /**< ETM read/write breakpoint. */ +#define QURT_ETM_READ_BRKPT 1U /**< ETM read breakpoint. */ +#define QURT_ETM_WRITE_BRKPT 2U /**< ETM write breakpoint. */ +#define QURT_ETM_BRKPT_INVALIDATE 3U /**< Invalidate breakpoint. */ +/** @addtogroup function_tracing_macro +@{ */ +/* ATB status flags */ +#define QURT_ATB_OFF 0 /**< ATB off. */ +#define QURT_ATB_ON 1 /**< ATB on. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* DTM enable flags */ +#define QURT_DTM_OFF 0 /**< DTM off. */ +#define QURT_DTM_ON 1 /**< DTM on. */ + +/** @addtogroup function_tracing_datatypes +@{ */ +/**STM trace information. */ +typedef struct qurt_stm_trace_info { + /** @cond */ + unsigned int stm_port_addr[6]; /* STM port address to which trace data must be written.*/ + unsigned int thread_event_id; /* Event ID for context switches.*/ + unsigned int interrupt_event_id; /* Event ID for interrupts. */ + unsigned int marker; /* Marker value that must be written at the beginning of the trace. */ + /** @endcond */ +} qurt_stm_trace_info_t; +/** @} */ /* end_addtogroup function_tracing_datatypes */ +/*============================================================================= + GLOBAL FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_trace_get_marker + Gets the kernel trace marker.\n + Returns the current value of the kernel trace marker. + The marker consists of a hardware thread identifier and an index into the kernel trace + buffer. The trace buffer records kernel events. + + @note1hang Using this function with qurt_trace_changed() + determines whether certain kernel events occurred in a block of code. + + @return + Integer -- Kernel trace marker. + + @dependencies + None. +*/ +unsigned int qurt_trace_get_marker(void); + +/**@ingroup func_qurt_trace_changed + Determines whether specific kernel events have occurred. \n + Returns a value that indicates whether the specified kernel events are recorded in the + kernel trace buffer since the specified kernel trace marker was obtained. + + The prev_trace_marker parameter specifies a kernel trace marker that was obtained by calling + qurt_trace_get_marker(). + @cond rest_dist For more information on the mask value, see the description of the trace_mask element in + @xhyperref{80VB41992,80-VB419-92}. \n @endcond + + @note1hang Used with qurt_trace_get_marker(), this function determines whether + certain kernel events occurred in a block of code.\n + @note1cont This function cannot determine whether a specific kernel event type has + occurred unless that event type has been enabled in the trace_mask element + of the system configuration file. \n + @note1cont QuRT supports the recording of interrupt and context switch events only (such as + a trace_mask value of 0x3). + + @param[in] prev_trace_marker Previous kernel trace marker. + @param[in] trace_mask Mask value that indicates which kernel events to check for. + + @returns + 1 -- Kernel events of the specified type have occurred since the + specified trace marker was obtained.\n + 0 -- No kernel events of the specified type have occurred since the + specified trace marker was obtained. + + @dependencies + None. +*/ +int qurt_trace_changed(unsigned int prev_trace_marker, unsigned int trace_mask); + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup function_tracing_macro +@{ */ +#ifndef QURT_DEBUG +#define QURT_TRACE(str, ...) __VA_ARGS__ + /**< Function tracing is implemented with the QURT_TRACE debug macro, which + optionally generates printf statements both before and after every function call that is + passed as a macro argument. + + For example, in the following macro calls in the source code: + @code + QURT_TRACE(myfunc, my_func(33)) + + @endcode + generates the following debug output: + @code + myfile:nnn: my_func >>> calling my_func(33) + myfile:nnn: my_func >>> returned my_func(33) + @endcode + The debug output includes the source file and line number of the function call, along with + the text of the call. Compile the client source file with -D __FILENAME__ + defined for its file name. + + The library function qurt_printf() generates the debug output. + The QURT_DEBUG symbol controls generation of the debug output. If this symbol is + not defined, function tracing is not generated.\n + @note1hang The debug macro is accessed through the QuRT API header file. + */ +#else +#define QURT_TRACE(str, ...) \ + do { \ + qurt_printf("%s:%d: %s: >>> calling %s\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + __VA_ARGS__; \ + qurt_printf("%s:%d: %s: <<< %s returned\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + } while (0); +#endif +/** @} */ /* end_addtogroup function_tracing_macro */ + +/**@ingroup func_qurt_etm_set_pc_range + Sets the PC address range for ETM filtering. + Depending on the Hexagon core design, a maximum of four PC ranges are supported. + + @param[in] range_num 0 to 3. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_pc_range(unsigned int range_num, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_range + Sets the address range for ETM filtering. + It allows the user to select the source type of addresses - QURT_ETM_SOURCE_PC and QURT_ETM_SOURCE_DATA. + + @param[in] addr_source_type Type of the address source:\n + - #QURT_ETM_SOURCE_PC \n + - #QURT_ETM_SOURCE_DATA @tablebulletend + @param[in] trig_block_num 0 to 3. + @param[in] pid pid of the process + 1. Any valid PID number will enable the ASID based trace filtering. + 2. QURT_ETM_NO_PID - Disable the ASID based trace filtering. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_range(unsigned int addr_source_type, unsigned int trig_block_num, unsigned int pid, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_atb + Sets the advanced trace bus (ATB) state to notify QuRT that the ATB is actively enabled or disabled. + QuRT performs the corresponding actions at low power management. + + @param[in] flag Values: \n + #QURT_ATB_ON \n + #QURT_ATB_OFF + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure + + @dependencies + None. +*/ +unsigned int qurt_etm_set_atb(unsigned int flag); + +/**@ingroup func_qurt_etm_set_sync_period + Sets the period for types of synchronization trace packets. \n + ASYNC defines the period between alignment synchronization packets. + Period is in terms of bytes in the packet stream. \n + ISYNC defines the period between instruction synchronization packets. + Period is per thread and is defined as the bytes sent out for that thread. \n + GSYNC is the defined period in thread cycles between GSYNC packets. + + @param[in] sync_type Type of synchronization packets: \n + #QURT_ETM_ASYNC_PERIOD \n + #QURT_ETM_ISYNC_PERIOD \n + #QURT_ETM_GSYNC_PERIOD + @param[in] period Period value. + + @return + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. + */ +unsigned int qurt_etm_set_sync_period(unsigned int sync_type, unsigned int period); + +/**@ingroup func_qurt_stm_trace_set_config + Sets up a STM port for tracing events. + + @datatypes + #qurt_stm_trace_info_t + + @param[in] stm_config_info Pointer to the STM trace information used to set up the trace + in the kernel. + The strucure must have the following:\n + - One port address per hardware thread \n + - Event ID for context switches \n + - Event ID for interrupt tracing n + - Header or marker to identify the beginning of the trace. @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Failure; possibly because the passed port address is not in the page table. + + @dependencies + None. + */ +unsigned int qurt_stm_trace_set_config(qurt_stm_trace_info_t *stm_config_info); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TRACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_types.h new file mode 100755 index 0000000000000..bdb83a3fe2fb2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_types.h @@ -0,0 +1,294 @@ +#ifndef QURT_TYPES_H +#define QURT_TYPES_H +/** + @file qurt_types.h + @brief Contains types common to all configurations + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +//#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define PGA_BITFIELD_MASK(hi,lo) (((~0u)>>(31U-((hi)-(lo))))<<(lo)) +#define PGA_BITFIELD_GET(x,hi,lo) (((x)&PGA_BITFIELD_MASK((hi),(lo)))>>(lo)) +#define PGA_BITFIELD_INS(hi,lo,v) (((v)<<(lo))&PGA_BITFIELD_MASK((hi),(lo))) +#define PGA_BITFIELD_SET(x,hi,lo,v) ((x)=((x)&~PGA_BITFIELD_MASK((hi),(lo)))|PGA_BITFIELD_INS((hi),(lo),(v))) +#define QURT_PGATTR_C_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 3U, 0U) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 5U, 4U) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_C_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 3U, 0U, (v)) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 5U, 4U, (v)) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_MKRAW(v) ((qurt_pgattr_t){.pga_value = (v)}) +#define QURT_PGATTR_MK(c,a) QURT_PGATTR_MKRAW(PGA_BITFIELD_INS(3U,0U,(c))|PGA_BITFIELD_INS(5U,4U,(a))) + +/*return types for qurt_island_get_status2*/ +#define QURT_ISLAND_MODE_NORMAL 0U /**< Normal operating mode */ +#define QURT_ISLAND_MODE_ISLAND 1U /**< Island mode */ +#define QURT_ISLAND_MODE_EXITING 2U /**< In transition from Island mode to Normal mode */ + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/** @addtogroup memory_management_types +@{ */ +typedef unsigned int qurt_addr_t; /**< QuRT address type.*/ +typedef unsigned int qurt_paddr_t; /**< QuRT physical memory address type. */ +/** @cond rest_reg_dist */ +typedef unsigned long long qurt_addr_64_t; /**< QuRT 64-bit memory address type. */ +typedef unsigned long long qurt_paddr_64_t; /**< QuRT 64-bit physical memory address type. */ +typedef unsigned int qurt_mem_region_t; /**< QuRT memory regions type. */ +typedef unsigned int qurt_mem_fs_region_t; /**< QuRT memory FS region type. */ +/**@endcond */ +typedef unsigned int qurt_mem_pool_t; /**< QuRT memory pool type.*/ +typedef unsigned int qurt_size_t; /**< QuRT size type. */ +/** @cond */ +typedef unsigned long long qurt_mmu_entry_t;/**< QuRT MMU entry type. */ +#define QURT_PHYSPOOL_NAME_LEN (32) +typedef char qurt_physpool_name_t[QURT_PHYSPOOL_NAME_LEN]; + + +/* + * Mapping type + * + * QMEM_MAPPING_VIRTUAL is the default mode, in which the system + * picks up the available range of the virtual address, and maps it to + * available contiguous physical addresses. Physical-to-virtual + * is not guaranteed to be 1:1; both virtual and physical memory is + * contiguous. + * + * In QMEM_MAPPING_IDEMPOTENT mode, the user provides the physical address; + * the kernel allocates 1:1 physical-to-virtual memory. Primary use of + * of this mapping is to allocate physical-to-virtual memory 1:1. + * + * In QMEM_MAPPING_PHYS_CONTIGUOUS mode, the virtual address might + * not be the same as the physical address. But the physical address of the + * memory region is guaranteed to be contiguous starting at the provided + * address, it is required to provide a fixed physical address. The primary + * use of this mapping is to allocate physical memory from a particular + * address, where 1:1 physical-to-virtual is not required. + * + * QMEM_MAPPING_NONE mode must be used to reserve a virtual memory + * area (VMA); no physical memory is reserved or mapped to this virtual + * space; all standard qmem_region APIs apply to a VMA, however physical + * address is always INVALID_ADDR. qmem_region_create() in this mode + * returns a handle to the VMA, both virt_addr and phys_addr must + * be set to INVALID_ADDR, kernel allocates any available virtual + * memory of the specified size. Obtain the starting virtual address + * of VMA through qmem_region_attr_getvirtaddr(). + * Primary purpose of this mapping mode is to provide a mechanism for + * delayed binding in QuRT, for example reserve virtual memory and map it at + * some later time to possibly discontiguous physical blocks. Thus, a + * single VMA can be partitioned among several physical-virtual mappings + * created via qmem_region_create() with QMEM_VIRTUAL_FIXED mapping mode. + * Each VMA keeps track of associated mapped regions. + * Deletion of VMA succeeds only if all associated "virtual_fixed" + * regions are freed prior to VMA deletion. + * + * Use QMEM_MAPPING_VIRTUAL_FIXED mode to create a region + * from virtual space that has been reserved via qmem_region_create() + * with QMEM_MAPPING_NONE mapping. A valid virt_add is required, if + * phys_addr is specified, the kernel attempts to map it accordingly, + * if no phys_addr is specified, kernel maps any available physical + * memory. All standard qmem_region APIs apply to such region. Remapping + * a virtual range without prior freeing of the region is not permitted. + * When such region is deleted its corresponding VMA remains intact. + * + * QMEM_MAPPING_PHYS_DISCONTIGUOUS mode can obtain contiguous + * virtual memory but physical memory can be discontiguous. This method + * tries to club small physical memory blocks to obtain requested + * memory and is useful in case where there is no contiguous full block + * of requested size. If client does not need contiguous physical memory, + * (for example, if client does not use physical addressing), this helps + * use smaller physical memory blocks rather than using contiguous memory. + * Note: When memory is allocated through this method, physical address is + * not returned to the caller using the qurt_mem_region_attr_get() API as there might + * not be a single physical address. + * + */ +/**@endcond */ +/** QuRT memory region mapping type. */ +typedef enum { + QURT_MEM_MAPPING_VIRTUAL=0, /**< Default mode. The region virtual address range maps to an + available contiguous area of physical memory. For the most + efficient use of virtual memory, the QuRT system + chooses the base address in physical memory. This works for most memory + use cases.*/ + QURT_MEM_MAPPING_PHYS_CONTIGUOUS = 1, /**< The region virtual address space must be mapped to a + contiguous area of physical memory. This is necessary when the + memory region is accessed by external devices that bypass Hexagon + virtual memory addressing. The base address in physical + memory must be explicitly specified.*/ + QURT_MEM_MAPPING_IDEMPOTENT=2, /**< Region virtual address space maps + to the identical area of physical memory. */ + QURT_MEM_MAPPING_VIRTUAL_FIXED=3, /**< Virtual address space of the region maps either to the + specified area of physical memory or (if no area is specified) + to available physical memory. Use this mapping to create + regions from virtual space that was reserved by calling + qurt_mem_region_create() with mapping. */ + QURT_MEM_MAPPING_NONE=4, /**< Reserves a virtual memory area (VMA). Remapping a virtual range is not + permitted without first deleting the memory region. When such a region is + deleted, its corresponding virtual memory addressing remains intact. */ + QURT_MEM_MAPPING_VIRTUAL_RANDOM=7, /**< System chooses a random virtual address and + maps it to available contiguous physical addresses.*/ + QURT_MEM_MAPPING_PHYS_DISCONTIGUOUS=8, /**< While virtual memory is contiguous, allocates in discontiguous physical + memory blocks. This helps when there are smaller contiguous blocks + than the requested size. + Physical address is not provided as part of the get_attr call */ + QURT_MEM_MAPPING_INVALID=10, /**< Reserved as an invalid mapping type. */ +} qurt_mem_mapping_t; + + +/** QuRT cache mode type. */ +typedef enum { + QURT_MEM_CACHE_WRITEBACK=7, /**< Write back. */ + QURT_MEM_CACHE_NONE_SHARED=6, /**< Normal uncached memory that can be shared with other subsystems.*/ + QURT_MEM_CACHE_WRITETHROUGH=5, /**< Write through. */ + QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE=0, /**< Write back non-L2-cacheable.*/ + QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE=1, /**< Write through non-L2-cacheable. */ + QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE=QURT_MEM_CACHE_WRITEBACK, /**< Write back L2 cacheable. */ + QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE=QURT_MEM_CACHE_WRITETHROUGH, /**< Write through L2 cacheable. */ + QURT_MEM_CACHE_DEVICE = 4, /**< Volatile memory-mapped device. Access to device memory cannot be cancelled by interrupts, re-ordered, or replayed.*/ + QURT_MEM_CACHE_NONE = 4, /**< Deprecated -- use #QURT_MEM_CACHE_DEVICE instead. */ + QURT_MEM_CACHE_DEVICE_SFC = 2, /**< Enables placing limitations on the number of outstanding transactions. */ + QURT_MEM_CACHE_INVALID=10, /**< Reserved as an invalid cache type. */ +} qurt_mem_cache_mode_t; + +/** Memory access permission. */ +#define QURT_PERM_NONE 0x0U /**< No permission. */ +#define QURT_PERM_READ 0x1U /**< Read permission. */ +#define QURT_PERM_WRITE 0x2U /**< Write permission. */ +#define QURT_PERM_EXECUTE 0x4U /**< Execution permission. */ +#define QURT_PERM_NODUMP 0x8U + /**< Skip dumping the mapping. During process domain dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and DSP process + crashed before the mapping is removed. */ +#define QURT_PERM_FULL QURT_PERM_READ | QURT_PERM_WRITE | QURT_PERM_EXECUTE /**< Read, write, and execute permission. */ + +typedef unsigned char qurt_perm_t; + + +/** @cond rest_reg_dist*/ +/** QuRT cache type; specifies data cache or instruction cache. */ +typedef enum { + QURT_MEM_ICACHE, /**< Instruction cache.*/ + QURT_MEM_DCACHE /**< Data cache.*/ +} qurt_mem_cache_type_t; + +/** QuRT cache operation code type. */ +typedef enum { + QURT_MEM_CACHE_FLUSH, /**< Flush. */ + QURT_MEM_CACHE_INVALIDATE, /**< Invalidate */ + QURT_MEM_CACHE_FLUSH_INVALIDATE, /**< Flush invalidate. */ + QURT_MEM_CACHE_FLUSH_ALL, /**< Flush all. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_ALL, /**< Flush invalidate all. */ + QURT_MEM_CACHE_TABLE_FLUSH_INVALIDATE, /**< Table flush invalidate. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_L2, /**< L2 flush invalidate.*/ +} qurt_mem_cache_op_t; + +/** QuRT memory region type. */ +typedef enum { + QURT_MEM_REGION_LOCAL=0, /**< Local. */ + QURT_MEM_REGION_SHARED=1, /**< Shared.*/ + QURT_MEM_REGION_USER_ACCESS=2, /**< User access. */ + QURT_MEM_REGION_FS=4, /**< FS. */ + QURT_MEM_REGION_INVALID=10, /**< Reserved as an invalid region type. */ +} qurt_mem_region_type_t; + +/* Cache and bus attributes are combined into a value of this type for convenience, + and macros for combining and extracting fields are defined here. */ +/** @cond */ +struct qurt_pgattr { + unsigned pga_value; /**< PGA value.*/ +}; +typedef struct qurt_pgattr qurt_pgattr_t; +/** @endcond */ +/** QuRT memory region attributes type.*/ +/* QMEM_MAPPING_IDEMPOTENT and QMEM_MAPPING_PHYS_CONTIGUOUS mode can specify physaddr. + virtaddr cannot be specified for a memory region, it can only be queried by the + qmem_attr_getvirtaddr() function. + */ +typedef struct { + /** @cond */ + qurt_mem_mapping_t mapping_type; + unsigned char perms; + unsigned short owner; + qurt_pgattr_t pga; + unsigned ppn; //physical page number (physical>>12) + qurt_addr_t virtaddr; + qurt_mem_region_type_t type; + qurt_size_t size; + /** @endcond */ +} qurt_mem_region_attr_t; + + +/** QuRT user physical memory pool type. */ +typedef struct { + /** @cond */ + char name[32]; + struct ranges{ + unsigned int start; + unsigned int size; + } ranges[MAX_POOL_RANGES]; + /** @endcond */ +} qurt_mem_pool_attr_t; + +/** QuRT memory pool status type.*/ +typedef struct _qurt_mem_pool_status { + + qurt_size_t contig_size; /**< Largest contiguous free memory in bytes. */ + qurt_size_t free_size; /**< Total free memory in bytes. */ + qurt_size_t total_size; /**< Total declared memory in bytes. */ + +} qurt_mem_pool_status_t; + +typedef enum { + HEXAGON_L1_I_CACHE = 0, /**< Hexagon L1 instruction cache. */ + HEXAGON_L1_D_CACHE = 1, /**< Hexagon L1 data cache. */ + HEXAGON_L2_CACHE = 2 /**< Hexagon L2 cache. */ +} qurt_cache_type_t; + +typedef enum { + FULL_SIZE = 0, /**< Fully shared cache, without partitioning. */ + HALF_SIZE = 1, /**< 1/2 for main, 1/2 for auxiliary. */ + THREE_QUARTER_SIZE = 2, /**< 3/4 for main, 1/4 for auxiliary. */ + SEVEN_EIGHTHS_SIZE = 3 /**< 7/8 for main, 1/8 for auxiliary; for L2 cache only. */ +} qurt_cache_partition_size_t; + +typedef enum { + QURT_PROCESS_CB_GENERIC, /**< generic unconditional cb called after image loading. */ + QURT_PROCESS_NOTE_CB_PRE_MAP, /**< note cb called before segment loading. */ + QURT_PROCESS_NOTE_CB_POST_MAP /**< note cb called after segment loading. */ +} qurt_process_cb_type_t; + +typedef union { + void *ptr; + int num; +} qurt_process_callback_arg_t; + + +/**@endcond*/ + +/** @} */ /* end_addtogroup memory_management_types */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TYPES_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_user_dma.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_user_dma.h new file mode 100755 index 0000000000000..e05a6429fd703 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_user_dma.h @@ -0,0 +1,44 @@ +#ifndef QURT_USER_DMA_H +#define QURT_USER_DMA_H + +/** + @file qurt_user_dma.h + @brief Definitions, macros, and prototypes used for handling user DMA. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_user_dma_dmsyncht + Sends the DMSyncht command to the user DMA engine. + + Call this function to ensure all posted DMA memory operations are + complete. + + This stalls the current thread until the instruction + is complete and returns. + + @return + QURT_EOK - On dmsyncht completion \n + QURT_ENOTSUPPORTED - User DMA not supported + + @dependencies + None. +*/ +int qurt_user_dma_dmsyncht(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_vtlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_vtlb.h new file mode 100755 index 0000000000000..e064042e447ac --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/include/qurt/qurt_vtlb.h @@ -0,0 +1,76 @@ +/*============================================================================= + + qurt_vtlb.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef QURT_VTLB_H +#define QURT_VTLB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Names starting with "qurt_i_vtlb" are the internal low-level functions. +|| These should be considered subject to change. +*/ + +int qurt_i_vtlb_entry_create(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension); + +int qurt_i_vtlb_entry_create_with_pid(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension, + unsigned target_pid); + +int qurt_i_vtlb_entry_delete(unsigned index); + +int qurt_i_vtlb_entry_read(unsigned index, unsigned *tlbinfo); + +int qurt_i_vtlb_entry_write(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension); + +int qurt_i_vtlb_entry_write_with_pid(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension, unsigned target_pid); + +int qurt_i_vtlb_entry_probe(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex); + +int qurt_i_vtlb_entry_probe_with_pid(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex, unsigned target_pid); + + +int qurt_i_vtlb_statistics(unsigned *stats); // Returns stats[0] -- total number of VTLB entries + // stats[1] -- number of available VTLB entries + // stats[2] -- max size of VTLB tree since boot + +//can return index to an entry that was specialed, change it to take addresses instead of pages +int qurt_i_vtlb_set_special(int index, unsigned pageno, unsigned asid, unsigned size); + +int qurt_i_vtlb_queue_ppage(unsigned pageno, unsigned vtlb_index); + +#define QURT_VTLB_EXT_DEFAULT 0U +#define QURT_VTLB_EXT_LOCKED 1U +#define QURT_VTLB_EXT_EXCLUDE_DUMP 2U /* Temporary ability to skip certain mappings in pd dump */ +#define QURT_VTLB_EXT_FREELIST 0x800000u + +#define QURT_VTLB_ERR_OVERLAP -64 +#define QURT_VTLB_ERR_TREE_NO_SPACE -65 +#define QURT_VTLB_ERR_INVALID_SIZE -68 +#define QURT_VTLB_ERR_INVALID_EXT -69 +#define QURT_VTLB_ERR_DEL_PGT_LOCKED -70 +#define QURT_VTLB_ERR_PGT_LOCK_CNT -71 + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_VTLB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libposix.a new file mode 100755 index 0000000000000..6d29c02c51601 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurt.a new file mode 100755 index 0000000000000..8d97bbd7c3b58 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurtcfs.a new file mode 100755 index 0000000000000..eac612a670347 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_island.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_island.a new file mode 100755 index 0000000000000..7e5653a98850c Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_island.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_main.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_main.a new file mode 100755 index 0000000000000..f01114822787c Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/libtimer_main.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libposix.a new file mode 100755 index 0000000000000..e8007300d0e4a Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurt.a new file mode 100755 index 0000000000000..c5977b8c3cc5e Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurtcfs.a new file mode 100755 index 0000000000000..eac612a670347 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libtimer.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libtimer.a new file mode 100755 index 0000000000000..a8bd4da88cace Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev75/lib/pic/libtimer.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/confname.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/confname.h new file mode 100755 index 0000000000000..d9ca3135501e3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/confname.h @@ -0,0 +1,528 @@ +#ifndef CONFNAME_H +#define CONFNAME_H +/** + @file confname.h + @brief Named literals for 'name' argument of sysconf, pathconf + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly. Instead include unistd.h. For now since + toolchain doesnt provide a hook by including bits/confname.h, we stick this + header in QuRT's sys/types.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum +{ + _PC_LINK_MAX, +#define _PC_LINK_MAX _PC_LINK_MAX + _PC_MAX_CANON, +#define _PC_MAX_CANON _PC_MAX_CANON + _PC_MAX_INPUT, +#define _PC_MAX_INPUT _PC_MAX_INPUT + _PC_NAME_MAX, +#define _PC_NAME_MAX _PC_NAME_MAX + _PC_PATH_MAX, +#define _PC_PATH_MAX _PC_PATH_MAX + _PC_PIPE_BUF, +#define _PC_PIPE_BUF _PC_PIPE_BUF + _PC_CHOWN_RESTRICTED, +#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED + _PC_NO_TRUNC, +#define _PC_NO_TRUNC _PC_NO_TRUNC + _PC_VDISABLE, +#define _PC_VDISABLE _PC_VDISABLE + _PC_SYNC_IO, +#define _PC_SYNC_IO _PC_SYNC_IO + _PC_ASYNC_IO, +#define _PC_ASYNC_IO _PC_ASYNC_IO + _PC_PRIO_IO, +#define _PC_PRIO_IO _PC_PRIO_IO + _PC_SOCK_MAXBUF, +#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF + _PC_FILESIZEBITS, +#define _PC_FILESIZEBITS _PC_FILESIZEBITS + _PC_REC_INCR_XFER_SIZE, +#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE + _PC_REC_MAX_XFER_SIZE, +#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE + _PC_REC_MIN_XFER_SIZE, +#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE + _PC_REC_XFER_ALIGN, +#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN + _PC_ALLOC_SIZE_MIN, +#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN + _PC_SYMLINK_MAX, +#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX + _PC_2_SYMLINKS +#define _PC_2_SYMLINKS _PC_2_SYMLINKS +}; + +/* Values for the argument to `sysconf'. */ +enum +{ + _SC_ARG_MAX, +#define _SC_ARG_MAX _SC_ARG_MAX + _SC_CHILD_MAX, +#define _SC_CHILD_MAX _SC_CHILD_MAX + _SC_CLK_TCK, +#define _SC_CLK_TCK _SC_CLK_TCK + _SC_NGROUPS_MAX, +#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX + _SC_OPEN_MAX, +#define _SC_OPEN_MAX _SC_OPEN_MAX + _SC_STREAM_MAX, +#define _SC_STREAM_MAX _SC_STREAM_MAX + _SC_TZNAME_MAX, +#define _SC_TZNAME_MAX _SC_TZNAME_MAX + _SC_JOB_CONTROL, +#define _SC_JOB_CONTROL _SC_JOB_CONTROL + _SC_SAVED_IDS, +#define _SC_SAVED_IDS _SC_SAVED_IDS + _SC_REALTIME_SIGNALS, +#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + _SC_PRIORITY_SCHEDULING, +#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + _SC_TIMERS, +#define _SC_TIMERS _SC_TIMERS + _SC_ASYNCHRONOUS_IO, +#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + _SC_PRIORITIZED_IO, +#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO + _SC_SYNCHRONIZED_IO, +#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + _SC_FSYNC, +#define _SC_FSYNC _SC_FSYNC + _SC_MAPPED_FILES, +#define _SC_MAPPED_FILES _SC_MAPPED_FILES + _SC_MEMLOCK, +#define _SC_MEMLOCK _SC_MEMLOCK + _SC_MEMLOCK_RANGE, +#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + _SC_MEMORY_PROTECTION, +#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + _SC_MESSAGE_PASSING, +#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING + _SC_SEMAPHORES, +#define _SC_SEMAPHORES _SC_SEMAPHORES + _SC_SHARED_MEMORY_OBJECTS, +#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + _SC_AIO_LISTIO_MAX, +#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX + _SC_AIO_MAX, +#define _SC_AIO_MAX _SC_AIO_MAX + _SC_AIO_PRIO_DELTA_MAX, +#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX + _SC_DELAYTIMER_MAX, +#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX + _SC_MQ_OPEN_MAX, +#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX + _SC_MQ_PRIO_MAX, +#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX + _SC_VERSION, +#define _SC_VERSION _SC_VERSION + _SC_PAGESIZE, +#define _SC_PAGESIZE _SC_PAGESIZE +#define _SC_PAGE_SIZE _SC_PAGESIZE + _SC_RTSIG_MAX, +#define _SC_RTSIG_MAX _SC_RTSIG_MAX + _SC_SEM_NSEMS_MAX, +#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX + _SC_SEM_VALUE_MAX, +#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX + _SC_SIGQUEUE_MAX, +#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX + _SC_TIMER_MAX, +#define _SC_TIMER_MAX _SC_TIMER_MAX + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, +#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX + _SC_BC_DIM_MAX, +#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX + _SC_BC_SCALE_MAX, +#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX + _SC_BC_STRING_MAX, +#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX + _SC_COLL_WEIGHTS_MAX, +#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX + _SC_EQUIV_CLASS_MAX, +#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX + _SC_EXPR_NEST_MAX, +#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX + _SC_LINE_MAX, +#define _SC_LINE_MAX _SC_LINE_MAX + _SC_RE_DUP_MAX, +#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX + _SC_CHARCLASS_NAME_MAX, +#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX + + _SC_2_VERSION, +#define _SC_2_VERSION _SC_2_VERSION + _SC_2_C_BIND, +#define _SC_2_C_BIND _SC_2_C_BIND + _SC_2_C_DEV, +#define _SC_2_C_DEV _SC_2_C_DEV + _SC_2_FORT_DEV, +#define _SC_2_FORT_DEV _SC_2_FORT_DEV + _SC_2_FORT_RUN, +#define _SC_2_FORT_RUN _SC_2_FORT_RUN + _SC_2_SW_DEV, +#define _SC_2_SW_DEV _SC_2_SW_DEV + _SC_2_LOCALEDEF, +#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF + + _SC_PII, +#define _SC_PII _SC_PII + _SC_PII_XTI, +#define _SC_PII_XTI _SC_PII_XTI + _SC_PII_SOCKET, +#define _SC_PII_SOCKET _SC_PII_SOCKET + _SC_PII_INTERNET, +#define _SC_PII_INTERNET _SC_PII_INTERNET + _SC_PII_OSI, +#define _SC_PII_OSI _SC_PII_OSI + _SC_POLL, +#define _SC_POLL _SC_POLL + _SC_SELECT, +#define _SC_SELECT _SC_SELECT + _SC_UIO_MAXIOV, +#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV + _SC_IOV_MAX = _SC_UIO_MAXIOV, +#define _SC_IOV_MAX _SC_IOV_MAX + _SC_PII_INTERNET_STREAM, +#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM + _SC_PII_INTERNET_DGRAM, +#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM + _SC_PII_OSI_COTS, +#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS + _SC_PII_OSI_CLTS, +#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS + _SC_PII_OSI_M, +#define _SC_PII_OSI_M _SC_PII_OSI_M + _SC_T_IOV_MAX, +#define _SC_T_IOV_MAX _SC_T_IOV_MAX + + /* Values according to POSIX 1003.1c (POSIX threads). */ + _SC_THREADS, +#define _SC_THREADS _SC_THREADS + _SC_THREAD_SAFE_FUNCTIONS, +#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + _SC_GETGR_R_SIZE_MAX, +#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX + _SC_GETPW_R_SIZE_MAX, +#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX + _SC_LOGIN_NAME_MAX, +#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX + _SC_TTY_NAME_MAX, +#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX + _SC_THREAD_DESTRUCTOR_ITERATIONS, +#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + _SC_THREAD_KEYS_MAX, +#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + _SC_THREAD_STACK_MIN, +#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN + _SC_THREAD_THREADS_MAX, +#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + _SC_THREAD_ATTR_STACKADDR, +#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + _SC_THREAD_ATTR_STACKSIZE, +#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + _SC_THREAD_PRIORITY_SCHEDULING, +#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + _SC_THREAD_PRIO_INHERIT, +#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + _SC_THREAD_PRIO_PROTECT, +#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + _SC_THREAD_PROCESS_SHARED, +#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + + _SC_NPROCESSORS_CONF, +#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF + _SC_NPROCESSORS_ONLN, +#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN + _SC_PHYS_PAGES, +#define _SC_PHYS_PAGES _SC_PHYS_PAGES + _SC_AVPHYS_PAGES, +#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES + _SC_ATEXIT_MAX, +#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX + _SC_PASS_MAX, +#define _SC_PASS_MAX _SC_PASS_MAX + + _SC_XOPEN_VERSION, +#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION + _SC_XOPEN_XCU_VERSION, +#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION + _SC_XOPEN_UNIX, +#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX + _SC_XOPEN_CRYPT, +#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT + _SC_XOPEN_ENH_I18N, +#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + _SC_XOPEN_SHM, +#define _SC_XOPEN_SHM _SC_XOPEN_SHM + + _SC_2_CHAR_TERM, +#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM + _SC_2_C_VERSION, +#define _SC_2_C_VERSION _SC_2_C_VERSION + _SC_2_UPE, +#define _SC_2_UPE _SC_2_UPE + + _SC_XOPEN_XPG2, +#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2 + _SC_XOPEN_XPG3, +#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3 + _SC_XOPEN_XPG4, +#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4 + + _SC_CHAR_BIT, +#define _SC_CHAR_BIT _SC_CHAR_BIT + _SC_CHAR_MAX, +#define _SC_CHAR_MAX _SC_CHAR_MAX + _SC_CHAR_MIN, +#define _SC_CHAR_MIN _SC_CHAR_MIN + _SC_INT_MAX, +#define _SC_INT_MAX _SC_INT_MAX + _SC_INT_MIN, +#define _SC_INT_MIN _SC_INT_MIN + _SC_LONG_BIT, +#define _SC_LONG_BIT _SC_LONG_BIT + _SC_WORD_BIT, +#define _SC_WORD_BIT _SC_WORD_BIT + _SC_MB_LEN_MAX, +#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX + _SC_NZERO, +#define _SC_NZERO _SC_NZERO + _SC_SSIZE_MAX, +#define _SC_SSIZE_MAX _SC_SSIZE_MAX + _SC_SCHAR_MAX, +#define _SC_SCHAR_MAX _SC_SCHAR_MAX + _SC_SCHAR_MIN, +#define _SC_SCHAR_MIN _SC_SCHAR_MIN + _SC_SHRT_MAX, +#define _SC_SHRT_MAX _SC_SHRT_MAX + _SC_SHRT_MIN, +#define _SC_SHRT_MIN _SC_SHRT_MIN + _SC_UCHAR_MAX, +#define _SC_UCHAR_MAX _SC_UCHAR_MAX + _SC_UINT_MAX, +#define _SC_UINT_MAX _SC_UINT_MAX + _SC_ULONG_MAX, +#define _SC_ULONG_MAX _SC_ULONG_MAX + _SC_USHRT_MAX, +#define _SC_USHRT_MAX _SC_USHRT_MAX + + _SC_NL_ARGMAX, +#define _SC_NL_ARGMAX _SC_NL_ARGMAX + _SC_NL_LANGMAX, +#define _SC_NL_LANGMAX _SC_NL_LANGMAX + _SC_NL_MSGMAX, +#define _SC_NL_MSGMAX _SC_NL_MSGMAX + _SC_NL_NMAX, +#define _SC_NL_NMAX _SC_NL_NMAX + _SC_NL_SETMAX, +#define _SC_NL_SETMAX _SC_NL_SETMAX + _SC_NL_TEXTMAX, +#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX + + _SC_XBS5_ILP32_OFF32, +#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32 + _SC_XBS5_ILP32_OFFBIG, +#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG + _SC_XBS5_LP64_OFF64, +#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64 + _SC_XBS5_LPBIG_OFFBIG, +#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG + + _SC_XOPEN_LEGACY, +#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY + _SC_XOPEN_REALTIME, +#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME + _SC_XOPEN_REALTIME_THREADS, +#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + + _SC_ADVISORY_INFO, +#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO + _SC_BARRIERS, +#define _SC_BARRIERS _SC_BARRIERS + _SC_BASE, +#define _SC_BASE _SC_BASE + _SC_C_LANG_SUPPORT, +#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT + _SC_C_LANG_SUPPORT_R, +#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R + _SC_CLOCK_SELECTION, +#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION + _SC_CPUTIME, +#define _SC_CPUTIME _SC_CPUTIME + _SC_THREAD_CPUTIME, +#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME + _SC_DEVICE_IO, +#define _SC_DEVICE_IO _SC_DEVICE_IO + _SC_DEVICE_SPECIFIC, +#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC + _SC_DEVICE_SPECIFIC_R, +#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R + _SC_FD_MGMT, +#define _SC_FD_MGMT _SC_FD_MGMT + _SC_FIFO, +#define _SC_FIFO _SC_FIFO + _SC_PIPE, +#define _SC_PIPE _SC_PIPE + _SC_FILE_ATTRIBUTES, +#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES + _SC_FILE_LOCKING, +#define _SC_FILE_LOCKING _SC_FILE_LOCKING + _SC_FILE_SYSTEM, +#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM + _SC_MONOTONIC_CLOCK, +#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + _SC_MULTI_PROCESS, +#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS + _SC_SINGLE_PROCESS, +#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS + _SC_NETWORKING, +#define _SC_NETWORKING _SC_NETWORKING + _SC_READER_WRITER_LOCKS, +#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + _SC_SPIN_LOCKS, +#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS + _SC_REGEXP, +#define _SC_REGEXP _SC_REGEXP + _SC_REGEX_VERSION, +#define _SC_REGEX_VERSION _SC_REGEX_VERSION + _SC_SHELL, +#define _SC_SHELL _SC_SHELL + _SC_SIGNALS, +#define _SC_SIGNALS _SC_SIGNALS + _SC_SPAWN, +#define _SC_SPAWN _SC_SPAWN + _SC_SPORADIC_SERVER, +#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER + _SC_THREAD_SPORADIC_SERVER, +#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + _SC_SYSTEM_DATABASE, +#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE + _SC_SYSTEM_DATABASE_R, +#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R + _SC_TIMEOUTS, +#define _SC_TIMEOUTS _SC_TIMEOUTS + _SC_TYPED_MEMORY_OBJECTS, +#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + _SC_USER_GROUPS, +#define _SC_USER_GROUPS _SC_USER_GROUPS + _SC_USER_GROUPS_R, +#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R + _SC_2_PBS, +#define _SC_2_PBS _SC_2_PBS + _SC_2_PBS_ACCOUNTING, +#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + _SC_2_PBS_LOCATE, +#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE + _SC_2_PBS_MESSAGE, +#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE + _SC_2_PBS_TRACK, +#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK + _SC_SYMLOOP_MAX, +#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX + _SC_STREAMS, +#define _SC_STREAMS _SC_STREAMS + _SC_2_PBS_CHECKPOINT, +#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + + _SC_V6_ILP32_OFF32, +#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + _SC_V6_ILP32_OFFBIG, +#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + _SC_V6_LP64_OFF64, +#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + _SC_V6_LPBIG_OFFBIG, +#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + + _SC_HOST_NAME_MAX, +#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX + _SC_TRACE, +#define _SC_TRACE _SC_TRACE + _SC_TRACE_EVENT_FILTER, +#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + _SC_TRACE_INHERIT, +#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT + _SC_TRACE_LOG, +#define _SC_TRACE_LOG _SC_TRACE_LOG + + _SC_LEVEL1_ICACHE_SIZE, +#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE + _SC_LEVEL1_ICACHE_ASSOC, +#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC + _SC_LEVEL1_ICACHE_LINESIZE, +#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE + _SC_LEVEL1_DCACHE_SIZE, +#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE + _SC_LEVEL1_DCACHE_ASSOC, +#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC + _SC_LEVEL1_DCACHE_LINESIZE, +#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE + _SC_LEVEL2_CACHE_SIZE, +#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE + _SC_LEVEL2_CACHE_ASSOC, +#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC + _SC_LEVEL2_CACHE_LINESIZE, +#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE + _SC_LEVEL3_CACHE_SIZE, +#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE + _SC_LEVEL3_CACHE_ASSOC, +#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC + _SC_LEVEL3_CACHE_LINESIZE, +#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE + _SC_LEVEL4_CACHE_SIZE, +#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE + _SC_LEVEL4_CACHE_ASSOC, +#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC + _SC_LEVEL4_CACHE_LINESIZE, +#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE + /* Leave room here, maybe we need a few more cache levels some day. */ + + _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, +#define _SC_IPV6 _SC_IPV6 + _SC_RAW_SOCKETS, +#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS + + _SC_V7_ILP32_OFF32, +#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32 + _SC_V7_ILP32_OFFBIG, +#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG + _SC_V7_LP64_OFF64, +#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64 + _SC_V7_LPBIG_OFFBIG, +#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG + + _SC_SS_REPL_MAX, +#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX + + _SC_TRACE_EVENT_NAME_MAX, +#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + _SC_TRACE_NAME_MAX, +#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + _SC_TRACE_SYS_MAX, +#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + _SC_TRACE_USER_EVENT_MAX, +#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + + _SC_XOPEN_STREAMS, +#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS + + _SC_THREAD_ROBUST_PRIO_INHERIT, +#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT + _SC_THREAD_ROBUST_PRIO_PROTECT +#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT + +}; +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/posix1_lim.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/posix1_lim.h new file mode 100755 index 0000000000000..0739958c5a6c4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/bits/posix1_lim.h @@ -0,0 +1,34 @@ +#ifndef POSIX1_LIM_H +#define POSIX1_LIM_H +/** + @file posix1_lim.h + @brief POSIX Minimum values + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +TODO + This header should be ideally relocated under api/posix/bits (something that + doesnt exist today) and be included from api/posix/bits/limits.h which inturn + should be included from toolchain's limits.h + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +#ifndef _POSIX_PATH_MAX +/** @brief Maximum number of bytes in a pathname, including the terminating + nul character */ +#define _POSIX_PATH_MAX 256 +#endif + +#ifndef _POSIX_SEM_NSEMS_MAX +/** @brief Maximum number of semaphores that a process may have */ +#define _POSIX_SEM_NSEMS_MAX 16 +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/common/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/common/time.h new file mode 100755 index 0000000000000..76b0d39ab7039 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/common/time.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/fcntl.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/fcntl.h new file mode 100755 index 0000000000000..c80ec98a449b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/fcntl.h @@ -0,0 +1,51 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/*========================================================================== + * FILE: fcntl.h + * + * SERVICES: POSIX fcntl.h + * + * DESCRIPTION: The header is needed by the open() and fcntl() + * system calls, which have a variety of parameters and + * flags. They are described here. + * + * The formats of the calls to each of these are: + * + * open(path, oflag [,mode]) open a file + * fcntl(fd, cmd [,arg]) get or set file attributes + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Oflag values for open(). POSIX Table 6-4. */ +#define POSIX_O_CREAT 0x100 /* creat file if it doesn't exist */ +#define POSIX_O_EXCL 0x200 /* exclusive use flag */ +#define POSIX_O_NOCTTY 0x400 /* do not assign a controlling terminal */ +#define POSIX_O_TRUNC 0x1000 /* truncate flag */ + +/* File status flags for open() and fcntl(). POSIX Table 6-5. */ +#define POSIX_O_APPEND 0x2000 /* set append mode */ +#define POSIX_O_NONBLOCK 0x4000 /* no delay */ + +/* File access modes for open() and fcntl(). POSIX Table 6-6. */ +#define POSIX_O_RDONLY 0 /* open(name, POSIX_O_RDONLY) opens read only */ +#define POSIX_O_WRONLY 1 /* open(name, POSIX_O_WRONLY) opens write only */ +#define POSIX_O_RDWR 2 /* open(name, POSIX_O_RDWR) opens read/write */ + +/* Mask for use with file access modes. POSIX Table 6-7. */ +#define POSIX_O_ACCMODE 0x3 /* mask for file access modes */ + +#ifdef __cplusplus +} +#endif + +#endif /* _FCNTL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/hooks/unistd.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/hooks/unistd.h new file mode 100755 index 0000000000000..1c618bfe36b4f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/hooks/unistd.h @@ -0,0 +1,115 @@ +#ifndef UNISTD_H +#define UNISTD_H +/** + @file posix/hooks/unistd.h + @brief POSIX related declarations in that are missing in toolchain + header + +EXTERNAL FUNCTIONS + None + +INITIALIZATION AND SEQUENCING REQUIREMENTS + DONT include this header directly! Instead include unistd.h. + +Copyright (c) 2018, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include /* For various POSIX ID types from toolchain headers */ + +#ifdef __cplusplus +extern "C" { +#endif +extern long pathconf (char const * path, int name); + +/* Process*/ + +/** The getppid() function shall return the parent process ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the parent process ID + */ +pid_t getppid(void); + +/** The getpgid() function shall return the process group ID of the process whose process ID is equal to pid + * Please refer to POSIX standard for details. + * @param thread [in] process ID + * @param value_ptr [out] process group ID + */ +pid_t getpgid(pid_t pid); + +/** The getpgrp() function shall return the process group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] process group ID of the calling process + */ +pid_t getpgrp(void); + +/**The getuid() function shall return the real user ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] the real user ID of the calling process. + */ +uid_t getuid(void); + +/** The geteuid() function shall return the effective user ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective user ID of the calling process + */ +uid_t geteuid(void); + +/** The getegid() function shall return the effective group ID of the calling process. + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] effective group ID of the calling process. + */ +gid_t getegid(void); + +/** The getgid() function shall return the real group ID of the calling process + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] real group ID of the calling process. + */ + gid_t getgid(void); + +/** seteuid set effective user ID + * Please refer to POSIX standard for details. + * @param thread [in] effective user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int seteuid(uid_t uid); + +/** setpgrp - set the process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setpgrp(void); + +/** setuid - set user ID + * Please refer to POSIX standard for details. + * @param thread [in] user ID + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setuid(uid_t uid); + +/** setpgid - set process group ID for job control + * Please refer to POSIX standard for details. + * @param thread [in] PID of process, PGID to be set + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +int setpgid(pid_t pid, pid_t pgid); + +/** setsid - create session and set process group ID + * Please refer to POSIX standard for details. + * @param thread [in] none + * @param value_ptr [out] Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and errno set to indicate the error. + */ +pid_t setsid(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/mqueue.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/mqueue.h new file mode 100755 index 0000000000000..74dcc2fa202c6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/mqueue.h @@ -0,0 +1,203 @@ +#ifndef _POSIX_MQUEUE_H_ +#define _POSIX_MQUEUE_H_ + +/*========================================================================== + * FILE: mqueue.h + * + * SERVICES: POSIX Message Queue API interface + * + * DESCRIPTION: POSIX Message Queue API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technlogies, Inc. + *==========================================================================*/ + +#include /*ssize_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MQ_PRIO_MAX 255 /* max priority */ +#define MQ_PRIO_DEFAULT 0 /* default priority */ + +typedef int mqd_t; + +struct mq_attr +{ + long mq_flags; /* message queue flags */ + long mq_maxmsg; /* maximum number of messages */ + long mq_msgsize; /* maximum message size */ + long mq_curmsgs; /* number of messages currently queued */ +}; + +typedef struct mq_attr mqueue_attr; + +/** \details + * This provides POSIX Message Queue API. + * + * mq_notify is not supported. + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * it only supports Message sending and receiving within one process. + * Message sending and receiving among processes are not supported. + */ + +/** \defgroup mqueue POSIX Message Queue API */ +/** \ingroup mqueue */ +/** @{ */ + +/** Open a message queue. + * Please refer to POSIX standard for details. + */ +mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */...); + +/** Close a message queue. + * Please refer to POSIX standard for details. + */ +int mq_close(mqd_t mq_desc); + +/** Remove a message queue. + * Please refer to POSIX standard for details. + */ +int mq_unlink(const char *name); + +/** Send a message to a message queue. + * Please refer to POSIX standard for details. + * + * If the queue is full, instead of blocking the sender, this function + * will return -1 with errno EAGAIN, in this implementation. This behavior + * may change in the future. + */ +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); + +/** Send a message to a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); + +/** Receive a message from a message queue. + * Please refer to POSIX standard for details. + */ +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); + +/** Receive a message from a message queue with timeout. + * Please refer to POSIX standard for details. + * @param abs_timeout [in] Only abs_timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msg_prio, const struct timespec *restrict abs_timeout); + +/** Get message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); + +/** Set message queue attributes. + * Please refer to POSIX standard for details. + */ +int mq_setattr(mqd_t mqdes, const struct mq_attr *restrict mqstat, struct mq_attr *restrict omqstat); + +/** @} */ + +#define NBBY 8U /* number of bits in a byte */ + +/* + * Select uses bit masks of file descriptors in longs. These macros + * manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here should + * be enough for most uses. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256U +#endif + +typedef unsigned long fd_mask; +#define NFDBITS (sizeof(fd_mask) * (unsigned int)NBBY) /* bits per mask */ + +#ifndef howmany +#define howmany(x, y) (((x) + ((y) - 1U)) / (y)) +#endif + +//equivalent of fd_set fpr WINNT env +typedef struct fd_set +{ + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +/** \addtogroup mqueue */ +/** @{ */ + +/** Sets the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_SET(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] |= (1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Clears the bit for the file descriptor fd in the file descriptor set fdset. + */ +#define FD_CLR(n, p) ((p)->fds_bits[((unsigned int) (n)) / NFDBITS] &= ~(1UL << (((unsigned int) (n)) % NFDBITS))) + +/** Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise. + */ +#define FD_ISSET(n, p) ((unsigned long)(p)->fds_bits[((unsigned int) (n)) / NFDBITS] & (unsigned long)((unsigned)1U << (((unsigned int) (n)) % NFDBITS))) + +/** Copies the file descriptor set. + */ +#define FD_COPY(f, t) (void)(memcpy)((t), (f), sizeof(*(f))) + +/** Initializes the file descriptor set fdset to have zero bits for all file descriptors. + */ +#define FD_ZERO(p) (void)memset((p), 0, sizeof(*(p))) + +/** Error check the file descriptor set. + */ +#define FD_BAD(fd) ((fd) < 0 /*|| fd >= fd_arraylen || fd_array[fd].obj == 0*/) + +/*! Wait for both message queues and signals. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int pselect(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict sigmask); + +/*! Wait for multiple message queues. In this implementation, only + * message queue file descriptors are supported. + * @param nfds [in] This is an integer one more than the maximum of any file + * descriptor in any of the sets. In other words, while you are busy + * adding file descriptors to your sets, you must calculate the maximum + * integer value of all of them, then increment this value by one, and + * then pass this as nfds to select(). + * @param readfds [in] the file descriptor set on all message queues. + * @param writefds [in] ignored in this implementation. + * @param errorfds [in] ignored in this implementation. + * @param timeout [in] Only timeout={0,0} is supported in this + * implementation. This behavior may change in the future. + */ +int select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout); + +/** @} */ + +/* this function is needed for test framework which needs to clean up memory when teardown */ +void _mq_teardown(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread.h new file mode 100755 index 0000000000000..f64242e8dc683 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread.h @@ -0,0 +1,287 @@ +#ifndef QURT_PTHREAD_H +#define QURT_PTHREAD_H + +/*========================================================================== + * FILE: pthread.h + * + * SERVICES: POSIX pthread API interface + * + * DESCRIPTION: POSIX pthread API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016,2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *========================================================================== + * + * EDIT HISTORY FOR MODULE + * + * This section contains comments describing changes made to the module. + * Notice that changes are listed in reverse chronological order. + * + * + * + * when who what, where, why + * -------- --- ------------------------------------------------------- + * 10/13/08 cz Initial version. + *==========================================================================*/ + +#include +#include "sys/sched.h" /* For struct sched_param */ +#include "sys/errno.h" /* error values */ +#include +#include +#include +#include +#include +#include "pthread_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* the range of the set supported by the kernel data type used to represent CPU sets. */ +#define CONFIG_NR_CPUS QURT_THREAD_CFG_BITMASK_ALL + +#define UNIMPLEMENTED(FUNC, RETURNTYPE, ARGS) static inline RETURNTYPE FUNC ARGS { qurt_printf("Unimplemented: %s... exiting\n", __FUNCTION__); exit(1); } + +/** @brief Magic (non-portable) value for a stack's address to enable usage + of auto-stack feature (if available) */ +#define PTHREAD_AUTO_STACK_MAGIC_ADDR_NP ((void *)0xFFF) + +/** \details + * This provides POSIX thread API. + * + */ + +/** \defgroup pthread POSIX pthread API */ +/** \ingroup pthread */ +/** @{ */ + +/** Compare Two Threads. + * Please refer to POSIX standard for details. + */ +static inline int pthread_equal(pthread_t t1, pthread_t t2) +{ + return (t1 == t2) ? 1 : 0; +} + +/** Create Thread. + * Please refer to POSIX standard for details. + */ +int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void *(*start)(void *), void *arg); + +/** Terminate Calling Thread. + * Please refer to POSIX standard for details. + */ +void pthread_exit(void *value_ptr); + +/** Wait for thread termination. + * Please refer to POSIX standard for details. + * @param thread [in] the thread to be joined + * @param value_ptr [out] the pointer of the exit status + */ +int pthread_join(pthread_t thread, void **value_ptr); + +/** Detach a joinable thread. + * Please refer to POSIX standard for details. + * @param id [in] id of the tread the thread to be detached. + */ +int pthread_detach(pthread_t id); + +/** Dynamic package initialisation + * Please refer to POSIX standard for details. + */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + +pthread_t pthread_self(void); +int pthread_cancel(pthread_t thread); +static inline void pthread_yield(void) +{ + return; +} + +int pthread_kill(pthread_t thread, int sig); + +/** + * @brief Return name of thread + * @warning Donot call this in the error handling path as it may cause deadlock + * due to underlying OS calls + * @param thread [in] thread Thread whose name is to be retrieved + * @param name [out] name Buffer used to return thread name + * @param len [in] len Number of bytes available in name + * @return 0 on success, ESRCH, ERANGE on failure + */ +extern int pthread_getname_np (pthread_t thread, char * name, size_t len); + +int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param); +int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); +int pthread_setschedprio(pthread_t thread, int prio); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); + +/* Attribute functions */ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_destroy(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const sched_param *restrict param); +int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, sched_param *restrict param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr); +int pthread_attr_getstackaddr(const pthread_attr_t *attr, void ** stackaddr); +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); +int pthread_attr_setscope(pthread_attr_t *attr, int scope); +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_getguardsize(const pthread_attr_t * attr, size_t * guardsize); +int pthread_attr_setautostack(pthread_attr_t *attr); +int pthread_attr_setbuspriority(pthread_attr_t *attr, unsigned short bus_priority); + +/* Qualcomm additions to pthread get/set attribute functions */ +int pthread_attr_setthreadname(pthread_attr_t *attr, const char * name); +int pthread_attr_getthreadname(const pthread_attr_t *attr, char * name, int size); +int pthread_attr_settimetestid(pthread_attr_t *attr, unsigned int tid); +int pthread_attr_gettimetestid(const pthread_attr_t *attr, unsigned int* tid); + +/* Mutexes */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling); +int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling); + +/* For Mutex with type PTHREAD_MUTEX_NORMAL, Priority Inheritance is not + * supported even PTHREAD_PRIO_INHERIT is defined since QURT does not support + * this kind of Mutex */ +int pthread_mutexattr_init(pthread_mutexattr_t *attr); +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, int *restrict); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling); + +/* Spinlocks */ +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); + +/* Condition variables */ +int pthread_condattr_init(pthread_condattr_t *attr); +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); +int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); +int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock); +int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock); +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr); +int pthread_cond_destroy(pthread_cond_t *cond); +int pthread_cond_signal(pthread_cond_t *cond); +int pthread_cond_broadcast(pthread_cond_t *cond); +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *time); + +/* Barriers */ +int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); +int pthread_barrier_destroy(pthread_barrier_t *barrier); +int pthread_barrier_wait(pthread_barrier_t *barrier); +int pthread_barrierattr_init(pthread_barrierattr_t *attr); +int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); + + +/*Read-Write locks*/ +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *); +int pthread_rwlockattr_init(pthread_rwlockattr_t *); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +int pthread_rwlock_rdlock(pthread_rwlock_t *); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *); +int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); +int pthread_rwlock_unlock(pthread_rwlock_t *); + + +/** please refer to POSIX standard document + */ +int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/** set CPU affinity attribute in thread attributes object. + + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [in] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpuset specified a CPU that was outside the set supported + by the kernel. (The kernel configuration option + CONFIG_NR_CPUS defines the range of the set supported by + the kernel data type used to represent CPU sets.) + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); + +/** get CPU affinity attribute in thread attributes object. + * @param attr [in] pthread attributes + * @param cpusetsize [in] The argument cpusetsize is the length (in bytes) + of the buffer pointed to by cpuset. Typically, + this argument would be specified as + sizeof(cpu_set_t). + * @param cpuset [out] This data set is a bitset where each bit represents + a CPU (hw thread). How the system's CPUs are mapped + to bits in the bitset is system dependent. + For QURT kernel, Bit 0 is corresponding to hw + thread 0, and so on. If the corresponding bit is + set to 1, then the software thread is eligible to + run this hw thread. 0x3f means it can run any hw + threads 0x0 also means it can run on any hw threads. + @return On success, this function returns 0; on error, it returns a + non-zero error number. + EINVAL - cpusetsize is smaller than the size of the affinity mask + used by the kernel. + * @note This function is non-standard GNU extensions; hence the suffix "_np" + (non-portable) in the names. + */ +int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset); + +/* TLS */ +int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void *value); +void *pthread_getspecific(pthread_key_t key); +int pthread_getattr_np(pthread_t thread, pthread_attr_t * restrict attr); + +/** @} */ + +/* Calling non-pthread calls this function to create pthred tcb w/o creating actual thread */ +int pthread_fake(pthread_t * restrict thread, const pthread_attr_t * restrict attr); +int pthread_fake_destroy(pthread_t thread); + +//amitkulk: move these to unistd.h after we move that header within qurt +int posix_memalign(void **memptr, size_t alignment, size_t size); +void exit(int status); +#ifdef __cplusplus +} +#endif + +#endif /* QURT_PTHREAD_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread_types.h new file mode 100755 index 0000000000000..51c3b9dbca243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/pthread_types.h @@ -0,0 +1,193 @@ +#ifndef _PTHREAD_TYPES_H_ +#define _PTHREAD_TYPES_H_ + +/*========================================================================== + * FILE: pthread_types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2016, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ +#define restrict __restrict__ +#else +#define restrict +#endif + +#define _SSIZE_T + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PTHREAD_MAX_THREADS 512U + +#define PTHREAD_NAME_LEN 16 +#define PTHREAD_MIN_STACKSIZE 512 //4096 +#define PTHREAD_MAX_STACKSIZE 1048576 +#define PTHREAD_DEFAULT_STACKSIZE 16384 + +#define PTHREAD_STACK_MIN (4096U*2U) +#define PTHREAD_MIN_PRIORITY 0U +#define PTHREAD_MAX_PRIORITY 255U +#define PTHREAD_DEFAULT_PRIORITY 1 + +/*Mutex initialization status*/ +#define PTHREAD_MUTEX_ATTR_UNINITIALIZED 0 +#define PTHREAD_MUTEX_ATTR_INITIALIZED 1 + +/*Conditional attributes initialization status*/ +#define PTHREAD_COND_ATTR_UNINITIALIZED 0 +#define PTHREAD_COND_ATTR_INITIALIZED 1 + +#define PTHREAD_DEFAULT_NAME "Anonymous" + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFFU) + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) 0xFFFFFFFFU) + +/* mutex and cond_var shared */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* mutex type */ +#define PTHREAD_MUTEX_ERRORCHECK 0 +#define PTHREAD_MUTEX_NORMAL 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT 3 + +/* mutex protocol */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_SPINLOCK_UNLOCKED 0 +#define PTHREAD_SPINLOCK_LOCKED 1 + +#define PTHREAD_ONCE_INIT (0) + +#define PTHREAD_MUTEX_OPAQUE //ToDo: amitkulk: debug + +typedef signed int ssize_t; + +/*detatchstate of a pthread*/ +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 0 + +/*contention scope*/ +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 + +/*scheduler*/ +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Types and structure definitions + * + */ +typedef unsigned int cpu_set_t; + +typedef unsigned int pthread_t; + +typedef struct pthread_attr_t +{ + void *stackaddr; + int internal_stack; /* this flag==1 means the stack needs to be freed by posix */ + size_t stacksize; + int priority; + unsigned short timetest_id; + /* This flag indicate if thread will be autostack thread*/ + unsigned short autostack:1; + /* This flag is to indicate thread's bus_priority high/low + bus_priority = 0 -- Bus_priority is low + bus_priority = 1 -- Bus_priority is high + bus_priority = 3 -- Bus_priority is default (takes the default set for the process) + */ + unsigned short bus_priority:2; + unsigned short reserved:13; + cpu_set_t cpumask; + char name[PTHREAD_NAME_LEN]; + /* This flag indicates whether pthread lib should create thread contexts for other OSALs */ + /* This is used internally by POSIX and not available for general usage */ + int ext_context; + int detachstate; +} pthread_attr_t; + +//mutex attr +typedef struct pthread_mutexattr_t pthread_mutexattr_t; +struct pthread_mutexattr_t +{ + int is_initialized; + int type; + int pshared; + int protocol; +}; + +typedef unsigned int pthread_mutex_t; + +typedef unsigned int pthread_spinlock_t; + +typedef struct pthread_condattr_t +{ + int is_initialized; + int pshared; + clockid_t clock_id; +} pthread_condattr_t; + +typedef unsigned int pthread_cond_t; + +typedef struct pthread_barrierattr_t +{ + int is_initialized; + int pshared; +} pthread_barrierattr_t; + +typedef unsigned int pthread_barrier_t; + +typedef int pthread_key_t; + +typedef int pthread_once_t; + + +/*Read-Write locks*/ +#define PTW32_RWLOCK_MAGIC 0xfacade2 +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +#ifdef __cplusplus +} +#endif + +#endif /* _PTHERAD_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sched.h new file mode 100755 index 0000000000000..faf3365be9f82 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sched.h @@ -0,0 +1,21 @@ +/*============================================================================= + + sched.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include "sys/sched.h" + +#endif //__SCHED_H__ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/semaphore.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/semaphore.h new file mode 100755 index 0000000000000..d9145b295ae62 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/semaphore.h @@ -0,0 +1,114 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +/*========================================================================== + * FILE: semaphore.h + * + * SERVICES: POSIX semaphore API interface + * + * DESCRIPTION: POSIX semaphore API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ +#include // Get all C sys types - includes POSIX specific +#include "sys/errno.h" // error values + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** User facing semaphore container with opaque pointer to implementation */ +typedef struct +{ + unsigned int *opaque; +} sem_t; +#define _SEM_T + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* constant definitions */ +#define SEM_FAILED ((sem_t*) 0) + +/* @todo siqbal Should we put such configuration items in a common place + instead of this user-facing header? */ +#define SEM_VALUE_MAX ((unsigned int) 30) // If need be increase this + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/** \details + * POSIX standard comes with two kinds of semaphores: named and unnamed + * semaphores. + * + * This implementation of POSIX kernel API provide unnamed & named semaphore. + * + * + * sem_timedwait() is not provided. + */ + +/** \defgroup semaphore POSIX Semaphore API */ + +/** \ingroup semaphore */ +/** @{ */ + +/** Initialize an unnamed semaphore. + * Please refer to POSIX standard for details. + * @param pshared [in] This implementation does not support non-zero value, + * i.e., semaphore cannot be shared between processes in this implementation. + */ +int sem_init(sem_t *sem, int pshared, unsigned int value); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_wait(sem_t *sem); + +/** Lock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_trywait(sem_t *sem); + +/** Unlock a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_post(sem_t *sem); + +/** Get the value of a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_getvalue(sem_t *sem, int *value); + +/** Destroy an unnamed semaphore. + * Please refer to POSIX standard for details. + */ +int sem_destroy(sem_t *sem); + +/** creates and initializes a named semaphore. + * Please refer to POSIX standard for details. + */ +sem_t * sem_open(const char* name , int oflag , ...); + +/** closes a semaphore. + * Please refer to POSIX standard for details. + */ +int sem_close(sem_t *sem); + +/** unlinkes a named semaphore. + * Please refer to POSIX standard for details. + */ +int sem_unlink(const char *name); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SEMAPHORE_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/signal.h new file mode 100755 index 0000000000000..35cb1f1a9a319 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/signal.h @@ -0,0 +1,201 @@ +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/*========================================================================== + * FILE: signal.h + * + * SERVICES: POSIX Signal API interface + * + * DESCRIPTION: POSIX Signal API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016, 2023 Qualcomm Technologies, Inc. + * All Rights Reserved. + * Confidential and Proprietary - Qualcomm Technologies, Inc. + + *==========================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX signal bits */ + +#define POSIX_MSG 7 /* POSIX msg type used in Qube API */ +#define POSIX_NOTIF 8 /* POSIX msg type used in Qube API */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ + +#define SIGRTMIN 10 +#define SIGRTMAX 32 + +/* Notification Types. */ +/* No asynchronous notification is delivered when the event of interest occurs. */ +#define SIGEV_NONE 0 +/* The signal specified in sigev_signo shall be generated for the process when + the event of interest occurs. */ +#define SIGEV_SIGNAL 1 +/* A notification function is called to perform notification. */ +#define SIGEV_THREAD 2 +#define SA_SIGINFO 1 + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +typedef unsigned long int sigset_t; + +union sigval +{ + int sival_int; /* Integer signal value. */ + void *sival_ptr; /* Pointer signal value. */ +}; + +typedef struct sigevent sigevent; +struct sigevent +{ + int sigev_notify; /* Notification type. */ + int sigev_signo; /* Signal number. */ + union sigval sigev_value; /* Signal value. */ + void (*sigev_notify_function)(union sigval); /* Notification function. */ + pthread_attr_t *sigev_notify_attributes; +}; + +typedef struct siginfo_t siginfo_t; +struct siginfo_t +{ + int si_signo; + int si_code; + union sigval si_value; +/* int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band;*/ +}; +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_sigaction)(int, siginfo_t *, void *); +}; + +/* Signal functions */ + +/** \details + * This provides POSIX Signal API. Please note that this + * implementation does not fully comply with POSIX standard. + * + * In POSIX standard, Signal can be used as 'interrupt', which means + * an incoming signal will interrupt a running thread. After the + * registered signal handler is executed, the thread will resume. + * This behavior cannot be implemented w/o modifying L4 or QURT kernel. + * On the ohter hand, appliation need to be carefully written to avoid + * problems caused by 'interrupting' signals. + * + * Therefore, in this implementation of POSIX signal, thread will + * only receive signals when it explicitly waits for signals, i.e., when + * the thread calls either sigwait() or sigsuspend(). + * + * Therefore, pthread_sigmask(), which set or get signal mask for a thread, + * is not supported, since the signal mask will be set by sigwait() and + * sigsuspend(). + * + * Since this implementation of POSIX kernel API is a subset of PSE51, + * only threads can send and receive signals. The functions related to + * signal operations with processes, such as kill(), sigqueue(), + * sigprocmask(), are not provided. + * + * Queued signal is not supported. + * + * Applications will use signals from SIGRTMIN to SIGRTMAX. + * + * SIGEV_SIGNAL and SIGEV_THREAD are supported. SIGEV_NONE is not + * supported. + * + */ + +/** \defgroup signal POSIX Signal API */ +/** \ingroup signal */ +/** @{ */ + +/** Wait for signals. This implementation does not support queued signals. + * + * Please refer to POSIX standard for details. + */ +int sigwait(const sigset_t *restrict set, int *restrict sig); + +/** Examine and Change Signal Action. + * Please refer to POSIX standard for details. + * + * @param act [in] A pointer to the sigaction structure that describes the + * action to be taken for the signal. Can be NULL. + * The following flags for sa_flags field in struct sigaction are not + * supported: SA_NOCLDSTOP, SA_ONSTACK, SA_RESETHAND, SA_RESTART, + * SA_NOCLDWAIT and SA_NODEFER. Only flag SA_SIGINFO is supported. + * + * @note Define sigaction as macro to avoid a warning when included from + * C++ code - it's causing a "sigaction(...) hides constructor for + * 'struct sigaction'" warning. + */ +/*lint -esym(123,sigaction) Suppress "macro used with no arguments" */ +#define sigaction(sig,act,oact) _sigaction((sig),(act),(oact)) + +/** Wait for signals. + * Please refer to POSIX standard for details. + */ +int sigsuspend(const sigset_t *sigmask); + +/** Add Signal to Signal Set. + * Please refer to POSIX standard for details. + */ +int sigaddset(sigset_t *set, int signo); + +/** Delete Signal from Signal Set. + * Please refer to POSIX standard for details. + */ +int sigdelset(sigset_t *set, int signo); + +/** Initialize and Empty Signal Set. + * Please refer to POSIX standard for details. + */ +int sigemptyset(sigset_t *set); + +/** Initialize and Fill Signal Set. + * Please refer to POSIX standard for details. + */ +int sigfillset(sigset_t *set); + +/** Test for Signal in Signal Set. + * Please refer to POSIX standard for details. + */ +int sigismember(const sigset_t *set, int signo); + +/** @} */ + +/* this is not a public api function */ +int _sigaction(int sig, const struct sigaction *act, struct sigaction *oact); + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +/** Wait for the time interval specified in the timespec structure referenced + * by timeout. This implementation does not support queued signals. + * For struct siginfo_t, si_code and si_value are ignored in this implementation. + * + * Please refer to POSIX standard for details. + */ +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SIGNAL_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/errno.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/errno.h new file mode 100755 index 0000000000000..b9edf57bab6c3 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/errno.h @@ -0,0 +1,20 @@ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +/*========================================================================== + * FILE: errno.h + * + * SERVICES: POSIX errno header file + * + * DESCRIPTION: POSIX errno based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#include +#ifndef EOK +#define EOK 0 +#endif + +#endif /* _SYS_ERRNO_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/sched.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/sched.h new file mode 100755 index 0000000000000..2acc34d821725 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/sched.h @@ -0,0 +1,67 @@ +#ifndef _POSIX_SCHED_H_ +#define _POSIX_SCHED_H_ + +/*========================================================================== + * FILE: sched.c + * + * SERVICES: POSIX Thread sched API interface + * + * DESCRIPTION: POSIX Thread sched API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + + *==========================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCHED_FIFO 0 /* First in, first out (FIFO) scheduling policy. */ +#define SCHED_RR 1 /* Round robin scheduling policy. */ +#define SCHED_SPORADIC 2 /* Sporadic server scheduling policy. */ +#define SCHED_OTHER 3 /* Another scheduling policy. */ + +typedef struct sched_param sched_param; +struct sched_param +{ + void *unimplemented; + int sched_priority; +}; + +/** \details + * This provides POSIX sched API. + */ + +/** \defgroup sched POSIX sched API */ +/** \ingroup sched */ +/** @{ */ + +/** Relinquish the CPU. + * Please refer to POSIX standard for details. + */ +static inline int sched_yield(void) +{ + return 0; +} + +/** Get the maximum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_max(int policy); + +/** Get the minimum priority. + * Please refer to POSIX standard for details. + * @param policy [in] SCHED_FIFO is the only valid input for this implementation. + */ +int sched_get_priority_min(int policy); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SCHED_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/types.h new file mode 100755 index 0000000000000..700026f9f9e4e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/sys/types.h @@ -0,0 +1,35 @@ +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/*========================================================================== + * FILE: types.c + * + * SERVICES: types usded in POSIX API interface + * + * DESCRIPTION: POSIX API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013, 2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + + *==========================================================================*/ + +#if !defined( _PID_T ) || !defined( __pid_t_defined ) +/* POSIX defines pid_t as signed 32-bit type. Hexagon toolchain's header + defines it as unsigned 32-bit type citing conflict with QuRT POSIX + compatibility later. If any such conflicts exist, we should fix them. + pid_t is being defined *BEFORE* inclusion of generic/sys/types.h + *INTENTIONALLY* to fix this */ +typedef int pid_t; +#define _PID_T +#define __pid_t_defined +#endif +#include +#include +#include +#include + +#ifndef __DEFINED_off_t +typedef long off_t; +#define __DEFINED_off_t +#endif + +#endif /* _SYS_TYPES_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/time.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/time.h new file mode 100755 index 0000000000000..13aeb1ea9920d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/posix/time.h @@ -0,0 +1,142 @@ +#ifndef _POSIX_TIME_H_ +#define _POSIX_TIME_H_ + +/*========================================================================== + * FILE: time.h + * + * SERVICES: POSIX Timer API interface + * + * DESCRIPTION: POSIX Timer API interface based upon POSIX 1003.1-2004 + * + * Copyright (c) 2013,2016 by Qualcomm Technologies, Inc. All Rights Reserved. QUALCOMM Proprietary and Confidential. + *==========================================================================*/ + + +#include + +typedef int clockid_t; /* ignored */ +#define _CLOCKID_T +#define _PROVIDE_POSIX_TIME_DECLS 1 +#include +/* @todo anandj sys/time.h has definition for struct timeval but is not + included by generic/time.h */ +#include + +#define CLOCK_FREQ_NOT_DEFINED -1 +/* Frequency of Sclk used */ +#define TIME_CONV_SCLK_FREQ 19200000 + +#define RES_CONV_FACTOR1 1 +#define RES_CONV_FACTOR2 1000000000 + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +#endif + +#if !defined(CLOCK_MONOTONIC) +# define CLOCK_MONOTONIC 1 +#endif + +#if !defined(CLOCK_THREAD_CPUTIME_ID) +# define CLOCK_THREAD_CPUTIME_ID 2 +#endif + +#if !defined(CLOCK_PROCESS_CPUTIME_ID) +# define CLOCK_PROCESS_CPUTIME_ID 3 +#endif + +#if !defined(CLOCK_MONOTONIC_RAW) +# define CLOCK_MONOTONIC_RAW 4 +#endif + +#if !defined(CLOCK_REALTIME_COARSE) +# define CLOCK_REALTIME_COARSE 5 +#endif + +#if !defined(CLOCK_MONOTONIC_COARSE) +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +#if !defined(CLOCK_BOOTTIME) +# define CLOCK_BOOTTIME 7 +#endif + +struct itimerspec +{ + struct timespec it_interval; /* Timer period. */ + struct timespec it_value; /* Timer expiration. */ +}; + +/* have to move #include here to solve circular include problems between time.h and signal.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer functions */ + +/** \details + * POSIX timers can be either of two types: a one-shot type or a periodic + * type. + * + * A one-shot is an armed timer that is set to an expiration time relative + * to either a current time or an absolute time. The timer expires once and + * is disarmed. + * + * A periodic timer is armed with an initial expiration time and a repetition + * interval. Every time the interval timer + * expires, the timer is reloaded with the repetition interval. The timer + * is then rearmed. + */ + +/** \defgroup timer POSIX Timer API */ + +/** \ingroup timer */ +/** @{ */ + +/** Create a POSIX timer. + * Please refer to POSIX standard for details. + * @param clockid [in] ignored in this implementation + * @param evp [in] if non-NULL, points to a sigevent structure. This + * structure, allocated by the application, defines the asynchronous + * notification to occur when the timer expires. If the evp argument is + * NULL, the effect is as if the evp argument pointed to a sigevent + * structure with the sigev_notify member having the value SIGEV_SIGNAL, + * the sigev_signo having a default signal number (SIGALRM), and the + * sigev_value member having the value of the timer ID. + */ +int timer_create(clockid_t clockid, struct sigevent *restrict evp, + timer_t *restrict timerid); + +/** Delete a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_delete(timer_t timerid); + +/** Get the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + */ +int timer_gettime(timer_t timerid, struct itimerspec *value); + + +/** Set the time remaining on a POSIX timer. + * Please refer to POSIX standard for details. + * @param flags [in] ignored in this implementation + */ +int timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); +/** Obtain ID of a process CPU-time clock + * @param pid [in] Process ID + * @param clock_id [out] Clock ID + * @return Error values as per POSIX standard + */ +int clock_getcpuclockid (pid_t pid, clockid_t * clock_id); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_TIME_H_ */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qube/qube.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qube/qube.h new file mode 100755 index 0000000000000..1e31e2deedb38 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qube/qube.h @@ -0,0 +1,51 @@ +#ifndef QUBE_H +#define QUBE_H +/*============================================================================= + + qube.h -- H E A D E R F I L E + +GENERAL DESCRIPTION + Prototypes of qpd API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Define Error codes as QuRT error codes preceed with QURT_ */ +#ifndef EOK +#define EOK QURT_EOK +#endif /* EOK */ +#ifndef EVAL +#define EVAL QURT_EVAL +#endif /* EVAL */ +#ifndef EMEM +#define EMEM QURT_EMEM +#endif /* EMEM */ +#ifndef EINVALID +#define EINVALID QURT_EINVALID +#endif /* EINVALID */ + + +/*============================================================================= + FUNCTION DECLARATIONS +=============================================================================*/ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QUBE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops.h new file mode 100755 index 0000000000000..0a9a9f8ba7db5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops.h @@ -0,0 +1,197 @@ +#ifndef ATOMIC_OPS_H +#define ATOMIC_OPS_H +/** + @file atomic_ops.h + + @brief Type definitions backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * Author: Carlos Dyonisio + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_plain_word_t; + +/*-------------------------------------------------------------------------*/ + /* Atomic Ops API. */ + +/* + * IMPORTANT! + * If you plan to change the structure atomic_word_t, please add the new + * elements after value. For more information, read the comment in + * arch/arm/libs/atomic_ops/v5/src/arm_atomic_ops.spp:66 + */ + +typedef struct { + volatile atomic_plain_word_t value; +} atomic_word_t; + +#define ATOMIC_INIT(i) { (i) } + +static inline void +atomic_init(atomic_word_t *a, atomic_plain_word_t v) +{ + a->value = v; +} + +#if defined(ARCH_ARM) && defined(ARCH_VER) && (ARCH_VER < 6) && \ + (!defined(__ATOMIC_OPS_IN_KERNEL__) || defined(MACHINE_SMP)) + +/* + * If it is ARMv4/v5, the function declarations may change + * and are defined in the arch specific header file, + * as some of then cannot be declared static because of + * the assembler implementation. + */ + +#else + +/* Arithmetic operations. */ + +void atomic_sub(atomic_word_t *target, atomic_plain_word_t v); + +/* Architecture independent definitions. */ + +static inline atomic_plain_word_t atomic_read(atomic_word_t *target) +{ + return target->value; +} + +typedef unsigned long long atomic64_plain_word_t; + +typedef struct { + volatile atomic64_plain_word_t value; +} atomic64_word_t; + +static inline void +atomic64_init(atomic64_word_t *a, atomic64_plain_word_t v) +{ + a->value = v; +} + +/********************* + Support 64-bit + *********************/ + +atomic64_plain_word_t atomic64_set(atomic64_word_t* target, + atomic64_plain_word_t value); + +void atomic64_xor(atomic64_word_t* target, + atomic64_plain_word_t mask); + +/*---------------------------------------------------------------------------*/ + +/* Architecture independent definitions. */ + +static inline atomic64_plain_word_t atomic64_read(atomic64_word_t *target) +{ + return target->value; +} + +#endif + + +/* Architecture dependent definitions. */ +#include + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops_plat.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops_plat.h new file mode 100755 index 0000000000000..b54b3ff83d978 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/atomic_ops_plat.h @@ -0,0 +1,86 @@ +#ifndef ATOMIC_OPS_PLAT_H +#define ATOMIC_OPS_PLAT_H +/** + @file atomic_ops_plat.h + + @brief Prototypes of atomic operations API backwards compatible. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define atomic_set(a,b) qurt_atomic_set((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and(a,b) qurt_atomic_and((unsigned int *)(a),(unsigned int)(b)) +#define atomic_and_return(a,b) qurt_atomic_and_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or(a,b) qurt_atomic_or((unsigned int *)(a),(unsigned int)(b)) +#define atomic_or_return(a,b) qurt_atomic_or_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor(a,b) qurt_atomic_xor((unsigned int *)(a),(unsigned int)(b)) +#define atomic_xor_return(a,b) qurt_atomic_xor_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_set_bit(a,b) qurt_atomic_set_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_clear_bit(a,b) qurt_atomic_clear_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_change_bit(a,b) qurt_atomic_change_bit((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add(a,b) qurt_atomic_add((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_return(a,b) qurt_atomic_add_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_add_unless(a,b,c) qurt_atomic_add_unless((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_sub(a,b) qurt_atomic_sub((unsigned int *)(a),(unsigned int)(b)) +#define atomic_sub_return(a,b) qurt_atomic_sub_return((unsigned int *)(a),(unsigned int)(b)) +#define atomic_inc(a) qurt_atomic_inc((unsigned int *)(a)) +#define atomic_inc_return(a) qurt_atomic_inc_return((unsigned int *)(a)) +#define atomic_dec(a) qurt_atomic_dec((unsigned int *)(a)) +#define atomic_dec_return(a) qurt_atomic_dec_return((unsigned int *)(a)) +#define atomic_compare_and_set(a,b,c) qurt_atomic_compare_and_set((unsigned int *)(a),(unsigned int)(b),(unsigned int)(c)) +#define atomic_barrier qurt_atomic_barrier +#define atomic_barrier_write qurt_atomic_barrier_write +#define atomic_barrier_write_smp qurt_atomic_barrier_write_smp +#define atomic_barrier_read_smp qurt_atomic_barrier_read_smp +#define atomic_barrier_smp qurt_atomic_barrier_smp + +/*============================ + * 64 bits support + *============================ */ +#define atomic64_set(a,b) qurt_atomic64_set((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and(a,b) qurt_atomic64_and((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_and_return(a,b) qurt_atomic64_and_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or(a,b) qurt_atomic64_or((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_or_return(a,b) qurt_atomic64_or_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor(a,b) qurt_atomic64_xor((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_xor_return(a,b) qurt_atomic64_xor_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_set_bit(a,b) qurt_atomic64_set_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_clear_bit(a,b) qurt_atomic64_clear_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_change_bit(a,b) qurt_atomic64_change_bit((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add(a,b) qurt_atomic64_add((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_add_return(a,b) qurt_atomic64_add_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub(a,b) qurt_atomic64_sub((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_sub_return(a,b) qurt_atomic64_sub_return((unsigned long long *)(a),(unsigned long long)(b)) +#define atomic64_inc(a) qurt_atomic64_inc((unsigned long long *)(a)) +#define atomic64_inc_return(a) qurt_atomic64_inc_return((unsigned long long *)(a)) +#define atomic64_dec(a) qurt_atomic64_dec((unsigned long long *)(a)) +#define atomic64_dec_return(a) qurt_atomic64_dec_return((unsigned long long *)(a)) +#define atomic64_compare_and_set(a,b,c) qurt_atomic64_compare_and_set((unsigned long long *)(a),(unsigned long long )(b),(unsigned long long )(c)) +#define atomic64_barrier qurt_atomic64_barrier +#define atomic64_barrier_write qurt_atomic64_barrier_write +#define atomic64_barrier_write_smp qurt_atomic64_barrier_write_smp +#define atomic64_barrier_read_smp qurt_atomic64_barrier_read_smp +#define atomic64_barrier_smp qurt_atomic64_barrier_smp + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* ATOMIC_OPS_PLAT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt.h new file mode 100755 index 0000000000000..4d25c9b2b6243 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt.h @@ -0,0 +1,111 @@ +#ifndef QURT_H +#define QURT_H + +/** + @file qurt.h + @brief Contains kernel header files that provide kernel OS API functions, constants, and + definitions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013,2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +/*====================================================================== + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Notice that changes are listed in reverse chronological + * order. + * + * + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------ + * 2011-02-25 op Add Header file + 2012-12-16 cm (Tech Pubs) Edited/added Doxygen comments and markup. + ======================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "qurt_consts.h" +#include "qurt_api_version.h" +#include "qurt_alloc.h" +#include "qurt_futex.h" +#include "qurt_mutex.h" +#include "qurt_pipe.h" +#include "qurt_printf.h" +#include "qurt_assert.h" +#include "qurt_thread.h" +#include "qurt_trace.h" +#include "qurt_cycles.h" +#include "qurt_profile.h" +#include "qurt_sem.h" +#include "qurt_cond.h" +#include "qurt_barrier.h" +#include "qurt_fastint.h" +#include "qurt_allsignal.h" +#include "qurt_anysignal.h" +#include "qurt_signal.h" +#include "qurt_rmutex.h" +#include "qurt_pimutex.h" +#include "qurt_signal2.h" +#include "qurt_rmutex2.h" +#include "qurt_pimutex2.h" +#include "qurt_int.h" +#include "qurt_lifo.h" +#include "qurt_power.h" +#include "qurt_event.h" +#include "qurt_pmu.h" +#include "qurt_stid.h" +//#include "qurt_version.h" +#include "qurt_tlb.h" +#include "qurt_vtlb.h" +#include "qurt_memory.h" +#include "qurt_qdi.h" +#include "qurt_sclk.h" +#include "qurt_space.h" +#include "qurt_process.h" +#include "qurt_timer.h" +#include "qurt_tls.h" +#include "qurt_thread_context.h" +#include "qurt_hvx.h" +#include "qurt_hmx.h" +#include "qurt_mailbox.h" +#include "qurt_island.h" +#include "qurt_qdi_proxy.h" +#include "qurt_l2cfg.h" +#include "qurt_mmap.h" +#include "qurt_isr.h" +#include "qurt_busywait.h" +#include "qurt_ecc.h" +#include "qurt_callback.h" +#include "qurt_error.h" +#include "qurt_except.h" +#include "qurt_mq.h" +#include "qurt_user_dma.h" +#include "qurt_fs_hub.h" +#include "qurt_os_services.h" + +#ifndef MAIN_ONLY +#define INCLUDE_ISLAND_CONTENTS +#endif +#ifndef ISLAND_ONLY +#define INCLUDE_MAIN_CONTENTS +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_alloc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_alloc.h new file mode 100755 index 0000000000000..da37a4c0a714e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_alloc.h @@ -0,0 +1,145 @@ +#ifndef QURT_ALLOC_H +#define QURT_ALLOC_H + +/** + @file qurt_alloc.h + @brief Prototypes of kernel memory allocation API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_malloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated memory area. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] size Size (in bytes) of the memory area. + + @return + Nonzero -- Pointer to the allocated memory area. \n + 0 -- Not enough memory in heap to allocate memory area. + + @dependencies + None. + + */ +/* ======================================================================*/ +void *qurt_malloc( unsigned int size); + +/*======================================================================*/ +/**@ingroup func_qurt_calloc + Dynamically allocates the specified array on the QuRT system heap. + The return value is the address of the allocated array. + + @note1hang The allocated memory area is automatically initialized to zero. + + @param[in] elsize Size (in bytes) of each array element. + @param[in] num Number of array elements. + + @return + Nonzero -- Pointer to allocated array.\n + Zero -- Not enough memory in heap to allocate array. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_calloc(unsigned int elsize, unsigned int num); + +/*======================================================================*/ +/**@ingroup func_qurt_realloc + Reallocates memory on the heap. \n + Changes the size of a memory area that is already allocated on the QuRT system heap. + The reallocate memory operation is functionally similar to realloc. It accepts a pointer + to an existing memory area on the heap, and resizes the memory area to the specified size + while preserving the original contents of the memory area. + + @note1hang This function might change the address of the memory area. + If the value of ptr is NULL, this function is equivalent to + qurt_malloc(). + If the value of new_size is 0, it is equivalent to qurt_free(). + If the memory area is expanded, the added memory is not initialized. + + @param[in] *ptr Pointer to the address of the memory area. + @param[in] newsize Size (in bytes) of the reallocated memory area. + + @return + Nonzero -- Pointer to reallocated memory area. \n + 0 -- Not enough memory in heap to reallocate the memory area. + + @dependencies + None. + + */ + /* ======================================================================*/ +void *qurt_realloc(void *ptr, int newsize); + +/*======================================================================*/ +/**@ingroup func_qurt_free + Frees allocated memory from the heap.\n + Deallocates the specified memory from the QuRT system heap. + + @param[in] *ptr Pointer to the address of the memory to deallocate. + + @return + None. + + @dependencies + The memory item that the ptr value specifies must have been previously + allocated using one of the qurt_calloc(), + qurt_malloc(), or qurt_realloc() memory allocation functions. + Otherwise the behavior of QuRT is undefined. + + */ + /* ======================================================================*/ +void qurt_free( void *ptr); + + +void *qurt_memalign(unsigned int alignment, unsigned int size); + +/* +|| Macro to define a static heap for a QuRT program. +|| +|| Usage: +|| Declare at the top-level of any C source file that +|| is part of the build (and is guaranteed +|| to actually be pulled into the build). Place +|| it in the same function with main(): +|| +|| QURT_DECLARE_STATIC_HEAP(512000); +|| +|| The only argument is the size in bytes, and it is +|| rounded up to the nearest 64 bytes (size of an +|| L2 cache block). +|| +*/ + +#define QURT_DECLARE_STATIC_HEAP(sz) \ + static struct qurt_static_heap { \ + char space[(sz)] __attribute__((aligned(64))); \ + } static_heap[1]; \ + void * const override_heap_Base = &static_heap[0]; \ + void * const override_heap_Limit = &static_heap[1] + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLOC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_allsignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_allsignal.h new file mode 100755 index 0000000000000..5dc89e495130d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_allsignal.h @@ -0,0 +1,176 @@ + +#ifndef QURT_ALLSIGNAL_H +#define QURT_ALLSIGNAL_H + +/** + @file qurt_allsignal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup all_signal_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** +qurt_signal_t supersedes qurt_allsignal_t. This type definition was added for backwards compatibility. */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int waiting; /**< */ + unsigned int signals_in; /**< */ + unsigned int queue; /**< */ + unsigned int reserved; /**< */ + }X; + /** @endcond */ +} qurt_allsignal_t; +/** @} */ /* end_addtogroup all_signal_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_init + Initializes an all-signal object.\n + The all-signal object is initially cleared. + + @datatypes + #qurt_allsignal_t + + @param[out] signal Pointer to the all-signal object to initialize. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_init(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_destroy + Destroys the specified all-signal object.\n + @note1hang All-signal objects must be destroyed when they are no longer in use. + Failure to do this causes resource leaks in the QuRT kernel. \n + @note1cont All-signal objects must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_allsignal_destroy(qurt_allsignal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_get + Gets signal values from the all-signal object. + + Returns the current signal values of the specified all-signal object. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to access. + + @return + Bitmask with current signal values. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_allsignal_get(qurt_allsignal_t *signal) +{ return signal->X.signals_in; } + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_wait + Waits on the all-signal object.\n + Suspends the current thread until all of the specified signals are set. + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 that it is not to be waited on. + + If a signal is set in an all-signal object, and a thread is waiting on the all-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + Unlike any-signals, all-signals do not need to explicitly clear any set signals in an all-signal + object before waiting on them again -- clearing is done automatically by the wait + operation. + + @note1hang At most, one thread can wait on an all-signal object at any given time. + Because signal clearing is done by the wait operation, no clear operation is + defined for all-signals. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to wait on. + @param[in] mask Signal mask value, which identifies the individual signals in the all-signal object + to wait on. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_wait(qurt_allsignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_allsignal_set + Set signals in the specified all-signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit + value of 1 indicates that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_allsignal_t + + @param[in] signal Pointer to the all-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the all-signal object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_allsignal_set(qurt_allsignal_t *signal, unsigned int mask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ALLSIGNAL_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_anysignal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_anysignal.h new file mode 100755 index 0000000000000..9619e2de562b4 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_anysignal.h @@ -0,0 +1,225 @@ +#ifndef QURT_ANYSIGNAL_H +#define QURT_ANYSIGNAL_H +/** + @file qurt_anysignal.h + Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + +Copyright (c) 2021 Qualcomm Technologies, Inc. +All rights reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== +Typedefs +======================================================================*/ + +/**@ingroup anysignals_types + qurt_signal_t supersedes qurt_anysignal_t. This type definition was added for backwards compatibility. */ +typedef qurt_signal_t qurt_anysignal_t; + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_init + Initializes an any-signal object.\n + The any-signal object is initially cleared. + + @datatypes + #qurt_anysignal_t + + @param[out] signal Pointer to the initialized any-signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_init(qurt_anysignal_t *signal) +{ + qurt_signal_init(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_destroy + Destroys the specified any-signal object. + + @note1hang Any-signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Any-signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline void qurt_anysignal_destroy(qurt_anysignal_t *signal) +{ + qurt_signal_destroy(signal); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait + Wait on the any-signal object. \n + Suspends the current thread until any one of the specified signals is set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread is waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + + @return + Bitmask of current signal values. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_wait(qurt_anysignal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_set + Sets signals in the specified any-signal object. \n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be set, and 0 indicates not to set the sigmal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + set in the any-signal object. + + @return + Bitmask of old signal values (before set). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_set(qurt_anysignal_t *signal, unsigned int mask); + + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_get + Gets signal values from the any-signal object.\n + Returns the current signal values of the specified any-signal object. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to access. + + @return + A bitmask with the current signal values of the specified any-signal object. + + @dependencies + None. + */ +/* ======================================================================*/ +static inline unsigned int qurt_anysignal_get(qurt_anysignal_t *signal) +{ + return qurt_signal_get(signal); +} + + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_clear + @xreflabel{sec:anysignal_clear} + Clears signals in the specified any-signal object.\n + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object, which specifies the any-signal object to modify. + @param[in] mask Signal mask value identifying the individual signals to + clear in the any-signal object. + + @return + Bitmask -- Old signal values (before clear). + + @dependencies + None. + */ +/* ======================================================================*/ +unsigned int qurt_anysignal_clear(qurt_anysignal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_anysignal_wait_timed + Waits on the any-signal object. \n + Suspends the current thread until any of the specified signals is set or timeout expires. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait on the signal. + If a signal is set in an any-signal object, and a thread was waiting on the any-signal object for + that signal, the thread is awakened. If the awakened thread has higher priority than + the current thread, a context switch can occur. + + @note1hang At most, one thread can wait on an any-signal object at any given time. + + @datatypes + #qurt_anysignal_t + + @param[in] signal Pointer to the any-signal object to wait on. + @param[in] mask Signal mask value, which specifies the individual signals in the any-signal + object to wait on. + @param[out] signals Bitmask of current signal values. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- timeout + #QURT_EINVALID -- Duration out of range + + @dependencies + None. + */ +/* ======================================================================*/ + +int qurt_anysignal_wait_timed(qurt_anysignal_t *signal, unsigned int mask, unsigned int *signals, unsigned long long int duration); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ANYSIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_api_version.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_api_version.h new file mode 100755 index 0000000000000..dfe53ae755054 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_api_version.h @@ -0,0 +1,77 @@ +#ifndef QURT_API_VERSION_H +#define QURT_API_VERSION_H +/*============================================================================== + +qurt_api_version.h + +GENERAL DESCRIPTION + API version file + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ + +/*============================================================================== + CONSTANTS AND DEFINITIONS +==============================================================================*/ +/** + * Each field of the QURT_API_VERSION definitions is an 8-bit unsigned integer. + * Main release has first 3 fields updated - Major, Minor and Release. + * - QURT_API_VERSION = Major, Minor, Release. + * Patch releases are supported by adding the extra field. + * - QURT_API_VERSION = Major, Minor, Release, Patch. + */ +// Major version is incremented for incompatible API changes. +#define QURT_API_VER_MAJOR 1 + +// Minor version is incremented for backward-compatible enhancements in the API +// set. +#define QURT_API_VER_MINOR 4 + +// RELEASE version is incremented for each release within a `MAJOR.MINOR` +// release. +#define QURT_API_VER_RELEASE 1 + +// Patch version is incremented when new API content is introduced on older LTS +// release. +#define QURT_API_VER_PATCH 0 + +/* Update the QURT_API_VERSION function macro. */ +#define QURT_API_VERSION_ENCODE(major, minor, release, patch) \ + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | \ + (((release) & 0xFF) << 8) | ((patch) & 0xFF)) + +/* Update the QURT_API_VERSION Macro. */ +#define QURT_API_VERSION \ + QURT_API_VERSION_ENCODE(QURT_API_VER_MAJOR, QURT_API_VER_MINOR, \ + QURT_API_VER_RELEASE, QURT_API_VER_PATCH) + +/** Usage: + * + * #if QURT_API_VERSION >= QURT_API_VERSION_ENCODE(1,4,0,0) + * qurt_func_2(a,b,c); + * #else + * qurt_func(a); + * #endif + * + */ +/* + Gets the QuRT API version. + + @return + QuRT API version. + + @dependencies + None. + */ +unsigned int qurt_api_version(void); + +#endif /* QURT_API_VERSION_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_assert.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_assert.h new file mode 100755 index 0000000000000..13cc2afd2e973 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_assert.h @@ -0,0 +1,51 @@ +#ifndef QURT_ASSERT_H +#define QURT_ASSERT_H +/** + @file qurt_assert.h + @brief Prototypes of qurt_assert API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@ingroup func_qurt_assert_error + Writes diagnostic information to the debug buffer, and raises an error to the QuRT kernel. + + @datatypes + None. + + @param[in] filename Pointer to the file name string. + @param[in] lineno Line number. + + @return + None. + + @dependencies + None. + */ +void qurt_assert_error(const char *filename, int lineno) __attribute__((noreturn)); + +#define qurt_assert(cond) ((cond)?(void)0:qurt_assert_error(__QURTFILENAME__,__LINE__)) + +/** @} */ /* end_ingroup func_qurt_assert */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ASSERT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_atomic_ops.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_atomic_ops.h new file mode 100755 index 0000000000000..d9b2cff7d737c --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_atomic_ops.h @@ -0,0 +1,1298 @@ +#ifndef QURT_ATOMIC_OPS_H +#define QURT_ATOMIC_OPS_H +/** + @file qurt_atomic_ops.h + @brief Prototypes of kernel atomic operations API. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + * Author: Malcolm Purvis + * + * This file is only included by the main atomic_ops.h, so all of that + * file's definitions are available. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +///* Sanity check to ensure the smp flag is set in machines.py */ +//#if defined(__ATOMIC_OPS_IN_KERNEL__) && !defined(MACHINE_SMP) && CONFIG_NUM_UNITS > 1 +//#error CONFIG_NUM_UNITS > 1 but smp not defined in machines.py. +//#endif +#define QURT_INLINE __attribute__((always_inline)) + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_atomic_set + Sets the atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value Value to set. + + @return + Value successfuly set. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_set(unsigned int* target, unsigned int value) +{ + unsigned long tmp; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " memw_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic_and + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + None + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_and(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_and_return + Bitwise AND operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise AND. + + @return + AND result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_and_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_or + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_or(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_or_return + Bitwise OR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise OR. + + @return + Returns the OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_or_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_xor + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_xor(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic_xor_return + Bitwise XOR operation of the atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask Mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_xor_return(unsigned int* target, unsigned int mask) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_set_bit + Sets a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_set_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_clear_bit + Clears a bit in the atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_clear_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit % ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_change_bit + Toggles a bit in a atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_change_bit(unsigned int *target, unsigned int bit) +{ + unsigned int result; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1fU; + unsigned int *wtarget= (unsigned int *)&target[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_add(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_add_return + Adds an integer to atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_add_unless + Adds the delta value to an atomic variable unless the current value in the target + matches the unless variable. + + @note1hang The function retries until load lock and store conditional + are successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] delta Value to add to the current value. + @param[in] unless Perform the addition only when the current value is not + equal to this unless value. + @return + TRUE -- 1 - Addition was performed. \n + FALSE -- 0 - Addition was not done. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_add_unless(unsigned int* target, + unsigned int delta, + unsigned int unless) +{ + unsigned int current_val; + unsigned int new_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%3)\n" + " p0 = cmp.eq(%0, %5)\n" + " if p0 jump 2f\n" + " %1 = add(%0, %4)\n" + " memw_locked(%3, p0) = %1\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"=&r" (new_val),"+m" (*target) + : "r" (target), "r" (delta), "r" (unless) + : "p0"); + + return (unsigned int)(current_val != unless); +} + +/**@ingroup func_qurt_atomic_sub + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_sub(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic_sub_return + Subtracts an integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v Integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_sub_return(unsigned int *target, unsigned int v) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_inc + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_inc(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_inc_return + Increments an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_inc_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_dec + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_dec(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); +} + +/**@ingroup func_qurt_atomic_dec_return + Decrements an atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_dec_return(unsigned int *target) +{ + unsigned int result; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = add(%0, #-1)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic_compare_and_set + Compares the current value of the atomic variable with the + specified value and set to a new value when compare is successful. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val Old value to compare. + @param[in] new_val New value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE --Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned int +qurt_atomic_compare_and_set(unsigned int* target, + unsigned int old_val, + unsigned int new_val) +{ + unsigned int current_val; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memw_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (unsigned int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic_barrier + Allows the compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic_barrier(void) +{ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); +} + + +/**@ingroup func_qurt_atomic64_set + Sets the 64-bit atomic variable with the specified value. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] value 64-bit value to set. + + @return + Successfuly set value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_set(unsigned long long* target, unsigned long long value) +{ + unsigned long long tmp; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " memd_locked(%2, p0) = %3\n" + " if !p0 jump 1b\n" + : "=&r" (tmp),"+m" (*target) + : "r" (target), "r" (value) + : "p0"); + return value; +} + +/**@ingroup func_qurt_atomic64_and_return + Bitwise AND operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise AND. + + @return + AND result of 64-bit atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_and_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = and(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_or + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_or(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_or_return + Bitwise OR operation of a 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise OR. + + @return + OR result of the atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_or_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = or(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_xor_return + Bitwise XOR operation of 64-bit atomic variable with mask. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] mask 64-bit mask for bitwise XOR. + + @return + XOR result of atomic variable with mask. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_xor_return(unsigned long long* target, unsigned long long mask) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = xor(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (mask) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_set_bit + Sets a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to set. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_set_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = setbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_clear_bit + Clears a bit in a 64-bit atomic variable at a specified position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to clear. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_clear_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = clrbit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget), "r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_change_bit + Toggles a bit in a 64-bit atomic variable at a bit position. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] bit Bit position to toggle. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_change_bit(unsigned long long *target, unsigned int bit) +{ + unsigned int result; + unsigned int *wtarget; + unsigned int *pwtarget = (unsigned int *)target; + unsigned int aword = bit / ((unsigned int)sizeof(unsigned int) * 8U); + unsigned int sbit = bit & 0x1FU; + wtarget = (unsigned int *)&pwtarget[aword]; + + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n" + " %0 = togglebit(%0, %3)\n" + " memw_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*wtarget) + : "r" (wtarget),"r" (sbit) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_add(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_add_return + Adds a 64-bit integer to 64-bit atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to add. + + @return + Result of arithmetic sum. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_add_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_sub_return + Subtracts a 64-bit integer from an atomic variable. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] v 64-bit integer value to subtract. + + @return + Result of arithmetic subtraction. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_sub_return(unsigned long long *target, unsigned long long v) +{ + unsigned long long result; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = sub(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target), "r" (v) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_inc + Increments a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_inc(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); +} + +/**@ingroup func_qurt_atomic64_inc_return + Increments a 64-bit atomic variable by one + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Incremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_inc_return(unsigned long long *target) +{ + unsigned long long result; + unsigned long long inc =1; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (inc) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_dec_return + Decrements a 64-bit atomic variable by one. + + @note1hang The function retries until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + + @return + Decremented value. + + @dependencies + None. +*/ +static inline QURT_INLINE unsigned long long +qurt_atomic64_dec_return(unsigned long long *target) +{ + unsigned long long result; + long long minus1 = 0xFFFFFFFFFFFFFFFFLL; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " %0 = add(%0, %3)\n" + " memd_locked(%2, p0) = %0\n" + " if !p0 jump 1b\n" + : "=&r" (result),"+m" (*target) + : "r" (target),"r" (minus1) + : "p0"); + + return result; +} + +/**@ingroup func_qurt_atomic64_compare_and_set + Compares the current value of an 64-bit atomic variable with + the specified value and sets to a new value when compare is successful. + + @note1hang The function keep retrying until load lock and store conditional + is successful. + + @param[in,out] target Pointer to the atomic variable. + @param[in] old_val 64-bit old value to compare. + @param[in] new_val 64-bit new value to set. + + @return + FALSE -- Specified value is not equal to the current value. \n + TRUE -- Specified value is equal to the current value. + + @dependencies + None. +*/ +static inline QURT_INLINE int +qurt_atomic64_compare_and_set(unsigned long long *target, + unsigned long long old_val, + unsigned long long new_val) +{ + unsigned long long current_val; + + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n" + " p0 = cmp.eq(%0, %3)\n" + " if !p0 jump 2f\n" + " memd_locked(%2, p0) = %4\n" + " if !p0 jump 1b\n" + "2:\n" + : "=&r" (current_val),"+m" (*target) + : "r" (target), "r" (old_val), "r" (new_val) + : "p0"); + + return (int)(current_val == old_val); +} + +/**@ingroup func_qurt_atomic64_barrier + Allows compiler to enforce an ordering constraint on memory operation issued + before and after the function. + + @return + None. + + @dependencies + None. +*/ +static inline QURT_INLINE void +qurt_atomic64_barrier(void) +{ + /** @cond */ + __asm__ __volatile__ ( + "" + : + : + : + "memory"); + /** @endcond */ +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ATOMIC_OPS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_barrier.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_barrier.h new file mode 100755 index 0000000000000..7c6f787d43bc2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_barrier.h @@ -0,0 +1,140 @@ +#ifndef QURT_BARRIER_H +#define QURT_BARRIER_H + +/** + @file qurt_barrier.h + @brief Prototypes of Kernel barrier API functions. + + EXTERNALIZED FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup barrier_types +@{ */ +/*===================================================================== + Constants and macros +======================================================================*/ +#define QURT_BARRIER_SERIAL_THREAD 1 /**< Serial thread. */ +#define QURT_BARRIER_OTHER 0 /**< Other. */ + +#ifndef ASM +#include + +/*===================================================================== +Typedefs +======================================================================*/ + +/** QuRT barrier type. + */ +typedef union { + /** @cond */ + struct { + unsigned short threads_left; + unsigned short count; + unsigned int threads_total; + unsigned int queue; + unsigned int reserved; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_barrier_t; + +/** @} */ /* end_addtogroup barrier_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_init + Initializes a barrier object. + + @datatypes + #qurt_barrier_t + + @param[out] barrier Pointer to the barrier object to initialize. + @param[in] threads_total Total number of threads to synchronize on the barrier. + + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_init(qurt_barrier_t *barrier, unsigned int threads_total); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_destroy + Destroys the specified barrier. + + @note1hang Barriers must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Barriers must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to destroy. + + @return + Unused integer value. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_destroy(qurt_barrier_t *barrier); + +/*======================================================================*/ +/**@ingroup func_qurt_barrier_wait + Waits on the barrier.\n + Suspends the current thread on the specified barrier. \n + The function return value indicates whether the thread was the last one to + synchronize on the barrier. + When a thread waits on a barrier, it is suspended on the barrier: \n + - If the total number of threads waiting on the barrier is less than the assigned value + of the barrier, no other action occurs. \n + - If the total number of threads waiting on the barrier equals the assigned value of the + barrier, all threads currently waiting on the barrier are awakened, allowing them to + execute past the barrier. + + @note1hang After its waiting threads are awakened, a barrier is automatically reset + and can be used again in the program without the need for re-initialization. + + @datatypes + #qurt_barrier_t + + @param[in] barrier Pointer to the barrier object to wait on. + + @return + #QURT_BARRIER_OTHER -- Current thread awakened from barrier. \n + #QURT_BARRIER_SERIAL_THREAD -- Current thread is last caller of barrier. + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_barrier_wait(qurt_barrier_t *barrier); + + +#endif + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BARRIER_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_busywait.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_busywait.h new file mode 100755 index 0000000000000..a4dab80a2520a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_busywait.h @@ -0,0 +1,62 @@ +#ifndef QURT_BUSYWAIT_H +#define QURT_BUSYWAIT_H + +/** + @file qurt_busywait.h + @brief Implementation of the busywait() function for + hardware based blocking waits that use the QTIMER as a reference. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ============================================================================*/ +/*============================================================================= + * + * EDIT HISTORY FOR FILE + * + * This section contains comments describing changes made to the + * module. Changes are listed in reverse chronological + * order. + * + * + * when who what, where, why + * ---------- --- ------------------------------------------------------- + * 2018-03-20 pg Add Header file + ============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_busywait + Pauses the execution of a thread for a specified time.\n + Use for small microsecond delays. + + @note1hang The function does not return to the caller until + the time duration has expired. + + @param[in] pause_time_us Time to pause in microseconds. + + @return + None. + + @dependencies + None. + */ +void qurt_busywait (unsigned int pause_time_us); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_BUSYWAIT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_callback.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_callback.h new file mode 100755 index 0000000000000..dc9b896c63454 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_callback.h @@ -0,0 +1,235 @@ +#ifndef QURT_CALLBACK_H +#define QURT_CALLBACK_H + +/** + @file qurt_callback.h + Definitions, macros, and prototypes for QuRT callback framework. + + QDI framework allows the development of root process drivers and services that + a user process client can interact with in a secure manner. QDI framework does + this by elevating the priviledge of user process thread, temporarily allowing + the thread execute in root context and letting it fall back to user context once + the QDI invocation is finished. + + The QuRT callback framework provides a safe mechanism for root process drivers + to execute callback functions in a user process. The framework hosts + dedicated worker threads in corresponding processes that handle the execution + of the callback function. This ensures that the callbacks occur in context of + the appropriate process thread, in result maintaining privilege boundaries. + + Prerequisites for use of this framework are: + 1. Driver is a QDI driver and client communicates with drivers using QDI + invocations. + 2. Appropriate callback configuration is specified in cust_config.xml for + the user process that intends to use this framework. + + qurt_cb_data_t is the public data structure that allows client to store all + the required information about the callback, including the callback function + and the arguments to pass to this function when it executes. + The client uses QDI interface to register this structure with root driver. + + Callback framework provides following APIs that a root driver can use to invoke callback. + These functions are described in qurt_qdi_driver.h header file. + + qurt_qdi_cb_invoke_async() triggers an asynchronous callback wherein the + invoking thread does not wait for the callback to finish executing. + + qurt_qdi_cb_invoke_sync() triggers a synchronous callback. Upon invocation + the invoking thread gets suspended till the callback function finishes execution. + + qurt_qdi_cb_invoke_sync_with_data() invokes a synchronous callback similar to + qurt_qdi_cb_invoke_sync(). It allows user to pass large data along with + the callback invocation to be utlized during the callback execution. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int qurt_cb_result_t; + +/* Callback framework error codes. + Callback framework returns a nonzero value if callback invocation is unsuccessful. + Following macros highlight cause of failure in more detail. +*/ +#define QURT_CB_ERROR -1 /* Callback registration failed.\n*/ +#define QURT_CB_OK 0 /* Success.\n*/ +#define QURT_CB_MALLOC_FAILED -2 /* QuRTOS malloc failure.\n*/ +#define QURT_CB_WAIT_CANCEL -3 /* Process exit cancelled wait operation.\n*/ +#define QURT_CB_CONFIG_NOT_FOUND -4 /* Callback configuration for process was not found.\n*/ +#define QURT_CB_QUEUE_FULL -5 /* Callback queue is serving at maximum capacity.*/ +/** @addtogroup cb_types +@{ */ +/** Callback registration data structure. + This data structure is used by a client attempting to register a callback with a QDI driver. + It holds the address of callback function and the argument supplied to the callback + function when it executes. +*/ +typedef struct { + /** @cond */ + void* cb_func; /*< Pointer to the callback function. */ + unsigned cb_arg; /*< Not interpreted by the framework.*/ + /** @endcond */ +} qurt_cb_data_t; + +/** @cond */ +/* Defines used as default if cust_config does not specify them. */ +#define CALLBACK_WORKER_STACK_SIZE 0x2000 +/** @endcond */ +/** @} */ /* end_addtogroup cb_typess */ +/**@ingroup func_qurt_cb_data_init + Initializes the callback data structure. + Entity registering a callback with the root process driver must call this function + to initialize callback registration data structure to the default value. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_init (qurt_cb_data_t* cb_data){ + cb_data->cb_func = NULL; + cb_data->cb_arg = 0; +} + +/**@ingroup func_qurt_cb_data_set_cbfunc + Sets up the callback function in the callback registration data structure. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_func Pointer to the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbfunc (qurt_cb_data_t* cb_data, void* cb_func){ + cb_data->cb_func = cb_func; +} + +/**@ingroup func_qurt_cb_data_set_cbarg + Sets up the callback argument. + This function sets up the argument passed to the callback function when it executes. + + @datatypes + #qurt_cb_data_t + + @param[in] cb_data Pointer to the callback data structure. + @param[in] cb_arg Argument for the callback function. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_cb_data_set_cbarg (qurt_cb_data_t* cb_data, unsigned cb_arg){ + cb_data->cb_arg = cb_arg; +} + +/** @cond */ +/**@ingroup driver_support_functions + Invokes an asynchronous callback for a specified process. + A driver that resides in the root process calls this API to launch a callback in + a process described by the client_handle. + After the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is not suspended during the callback execution period. + The API returns immediately with a success/failure error code. + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_async(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process. + A driver that resides in a root process calls this API to launch a sync callback in + a process described by the client_handle. + AFter the callback is invoked, the framework queues the callback as per its + priority and subsequently executes it. + The caller of this function is suspended during the callback execution period. + If the process in which to execute the callback exits or terminates, the caller is + woken up with error code #QURT_CB_WAIT_CANCEL (refer to qurt_callback.h). + + @note1hang This function is only accessible to drivers in the root process. + User process invocations shall fail with a negative error code return value. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, callback frameowrk + executes the callback at the priority of the API caller. + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync(int client_handle, + qurt_cb_data_t* cb_data, + int prio); + +/**@ingroup driver_support_functions + Invokes a synchronous callback for a specified process, passing driver data to the user PD. + This function is similar to qurt_qdi_cb_invoke_sync() and allows the driver to pass arbitrary data to + the user process as part of the callback invocation. + + @param client_handle Obtained from the current invocation function (Section 4.3.1). + @param cb_data Pointer to the callback data structure (refer to qurt_callback.h). + @param prio Priority at which the callback should execute. + This paraemter is optional. If -1 is passed, the callback frameowrk + executes the callback at the priority of the API caller. + @param data Driver arbitrary data to pass to the user process. Memory pointed to by data + must be accessible to the user PD. The root driver can allocate such memory by + using qurt_mem_mmap(). + @param data_len Driver arbitrary data length. + + @return + QURT_EOK -- Callback was successfully communicated to the framework. + Negative error code -- Callback cannot be communicated to the framework. + */ +qurt_cb_result_t qurt_qdi_cb_invoke_sync_with_data( int client_handle, + qurt_cb_data_t* cb_data, + int prio, + void *data, + unsigned data_len + ); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_clade.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_clade.h new file mode 100755 index 0000000000000..d7442cf98dd94 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_clade.h @@ -0,0 +1,62 @@ +#ifndef QURT_CLADE_H +#define QURT_CLADE_H +/** + @file qurt_clade.h + @brief Prototypes of Cache Line Accelerated Decompression Engine (CLADE) API. + CLADE is a cache line level memory compression system that is used to + decrease DRAM usage. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_clade2_get + Reads the value of the clade2 register. + + @param[in] offset Offset from the clade2 cfg base. + @param[out] *value Pointer to the register value read from the offset. + + @return + #QURT_EOK - Successfully read the value from the register at offset \n + #QURT_EINVALID - Offset passed is incorrect + + @dependencies + None. + */ +int qurt_clade2_get(unsigned short offset, unsigned int *value); + +/**@ingroup func_qurt_clade2_set + Sets the PMU register; only PMU_SEL register can be set. + + @param[in] offset Offset from the QURTK_clade2_cfg_base. + @param[in] value Value to set at offset. + + @return + #QURT_EOK -- Successfully set the value at offset. \n + #QURT_ENOTALLOWED -- Set operation performed at an offset other than CLADE2_PMU_SELECTION_REG. + + @dependencies + None. + */ +int qurt_clade2_set(unsigned short offset, unsigned int value); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CLADE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cond.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cond.h new file mode 100755 index 0000000000000..6e65ed82a8393 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cond.h @@ -0,0 +1,219 @@ +#ifndef QURT_COND_H +#define QURT_COND_H +/** + @file qurt_cond.h + @brief Prototypes of kernel condition variable object API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup condition_variables_types +@{ */ +/*===================================================================== + Typedefs + ======================================================================*/ + +/** QuRT condition variable type. */ +typedef union { + /** @cond */ + unsigned long long raw; + struct { + unsigned int count; + unsigned int n_waiting; + unsigned int queue; + unsigned int reserved; + }X; + /** @endcond */ +} qurt_cond_t; + +/** @} */ /* end_addtogroup condition_variables_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_cond_init + Initializes a conditional variable object. + + @datatypes + #qurt_cond_t + + @param[out] cond Pointer to the initialized condition variable object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_init(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_destroy + Destroys the specified condition variable. + + @note1hang Conditions must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Conditions must not be destroyed while they are still in use. If this occurs, + the behavior of QuRT is undefined. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to destroy. + + @return + None. + + */ +/* ======================================================================*/ +void qurt_cond_destroy(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_signal + Signals a waiting thread that the specified condition is true. \n + + When a thread wishes to signal that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the signal condition operation. \n + -# Unlock the mutex. + + @note1hang Failure to properly lock and unlock a mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_signal(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_broadcast + Signals multiple waiting threads that the specified condition is true.\n + When a thread wishes to broadcast that a condition is true on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# Perform the broadcast condition operation. \n + -# Unlock the mutex.\n + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t + + @param[in] cond Pointer to the condition variable object to signal. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_broadcast(qurt_cond_t *cond); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable (suspends the thread and unlocks the mutex). + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @datatypes + #qurt_cond_t \n + #qurt_mutex_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait(qurt_cond_t *cond, qurt_mutex_t *mutex); + +/*======================================================================*/ +/**@ingroup func_qurt_cond_wait2 + Suspends the current thread until the specified condition is true. + When a thread wishes to wait for a specific condition on a shared data item, it must + perform the following procedure: \n + -# Lock the mutex that controls access to the data item. \n + -# If the condition is not satisfied, perform the wait condition operation on the + condition variable, which suspends the thread and unlocks the mutex. + + @note1hang Failure to properly lock and unlock the mutex of a condition variable can cause + the threads to never be suspended (or suspended but never awakened). + + @note1cont Use condition variables only with regular mutexes -- attempting to use + recursive mutexes or priority inheritance mutexes results in undefined behavior. + + @note1cont This is the same API as qurt_cond_wait(), use this version + when using mutexes of type #qurt_rmutex2_t. + + @datatypes + #qurt_cond_t \n + #qurt_rmutex2_t + + @param[in] cond Pointer to the condition variable object to wait on. + @param[in] mutex Pointer to the mutex associated with the condition variable to wait on. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_cond_wait2(qurt_cond_t *cond, qurt_rmutex2_t *mutex); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_COND_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_consts.h new file mode 100755 index 0000000000000..b1e35998e73b6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_consts.h @@ -0,0 +1,315 @@ +#ifndef QURT_CONSTS_H +#define QURT_CONSTS_H + +/** + @file qurt_consts.h + @brief QuRT constants and definitions + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* Definitions of system events. System events suspend + a thread and put it into suspending_list. + The system event number is saved in CONTEXT::error::cause field + of the suspended thread. An event handler thread such as + page fault handler or system error handler can wake up the suspended + thread. + */ +#define QURT_EVENT_PAGEFAULT 0x1 /* Page fault event. */ +#define QURT_EVENT_SYSTEM_ERR 0x2 /* System error event. */ +#define QURT_EVENT_SUSPEND 0x3 +#define QURT_EVENT_PROCESS_EXIT 0x4 /* Process termination event.*/ + +#define QURT_SYSENV_MAX_THREADS_TYPE 1 /* Maximum threads object. */ +#define QURT_SYSENV_PROCNAME_TYPE 2 /* Process name object. */ +#define QURT_SYSENV_MAX_PI_PRIO_TYPE 3 /* Maximum pi priority object. */ +#define QURT_SYSENV_ARCH_REV_TYPE 4 /* Architecture version object. */ +#define QURT_SYSENV_APP_HEAP_TYPE 5 /* Application heap object. */ +#define QURT_SYSENV_REGION_ATTR_DEFAULT 7 /* Default region attributes. */ +#define QURT_SYSENV_STACK_PROFILE_COUNT_TYPE 8 /* Stack profile count type. */ +#define QURT_SYSENV_ISLAND_CONFIG_TYPE 9 /*island configuration check*/ +#define QURT_SYSENV_HTHREADS_TYPE 10 /* Active threads objec */ +#define QURT_SYSENV_CONFIG_IMAGE_START_LO 11 /* Config image start address for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_START_HI 12 /* Config Image start address for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_LO 13 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_CHIPPARAMS_HI 14 /* ChipParams for DTB parsing */ +#define QURT_SYSENV_PLATPARAMS 15 /* Platformparams for DTB parsing */ +#define QURT_SYSENV_CONFIG_IMAGE_SIZE 16 /* Config image Size for DTB parsing */ +#define QURT_SYSENV_L2_CACHE_LINE_SIZE 17 /*L2 cache line size*/ + +/* Get q6 regs */ +#define QURT_GET_SSR 1 +#define QURT_GET_CCR 2 +#define QURT_GET_CFGBASE 3 +#define QURT_GET_SYSCFG 4 +#define QURT_GET_REV 5 + + +/** @cond rest_reg_dist */ +/** @addtogroup performance_monitor_macros +@{ */ + +/* PMU */ +#define QURT_PMUCNT0 0 /**< */ +#define QURT_PMUCNT1 1 /**< */ +#define QURT_PMUCNT2 2 /**< */ +#define QURT_PMUCNT3 3 /**< */ +#define QURT_PMUCFG 4 /**< */ +#define QURT_PMUEVTCFG 5 /**< */ + +/* new since V55 */ +#define QURT_PMUCNT4 6 /**< */ +#define QURT_PMUCNT5 7 /**< */ +#define QURT_PMUCNT6 8 /**< */ +#define QURT_PMUCNT7 9 /**< */ +#define QURT_PMUEVTCFG1 10 /**< */ + +/* new since V61 */ +#define QURT_PMUSTID0 11 /**< */ +#define QURT_PMUSTID1 12 /**< */ + +#define QURT_PMUCNTSTID0 13 /**< */ +#define QURT_PMUCNTSTID1 14 /**< */ +#define QURT_PMUCNTSTID2 15 /**< */ +#define QURT_PMUCNTSTID3 16 /**< */ +#define QURT_PMUCNTSTID4 17 /**< */ +#define QURT_PMUCNTSTID5 18 /**< */ +#define QURT_PMUCNTSTID6 19 /**< */ +#define QURT_PMUCNTSTID7 20 /**< */ + +/** @} */ /* end_addtogroup performance_monitor_macros */ +/** @endcond */ + +/* + Power collapse operation +*/ +#define QURT_POWER_SHUTDOWN 0 /**< */ +#define QURT_TCXO_SHUTDOWN 1 /**< */ +#define QURT_POWER_CMD_PREPARE 0 /**< */ +#define QURT_POWER_CMD_PERFORM 1 /**< */ +#define QURT_POWER_CMD_EXIT 2 /**< */ +#define QURT_POWER_CMD_FAIL_EXIT 3 /**< */ +#define QURT_POWER_CMD_PERFORM_L2_RETENTION 4 /**< */ +#define QURT_POWER_CMD_PERFORM_SAVE_TCM 5 /**< */ +#define QURT_POWER_CMD_DEEP_SLEEP 6 /**< */ + + +/** @addtogroup thread_macros +@{ */ +#define QURT_MAX_HTHREAD_LIMIT 8U /**< Limit on the maximum number of hardware threads supported by QuRT for any + Hexagon version. Use this definition to define arrays, and so on, in + target independent code. */ +/** @} */ /* end_addtogroup thread_macros */ + +/** @cond internal_only */ +/** @addtogroup power_management_macros +@{ */ +/** + L2 cache retention mode +*/ +#define QURT_POWER_SHUTDOWN_TYPE_L2NORET QURT_POWER_CMD_PERFORM /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_L2RET QURT_POWER_CMD_PERFORM_L2_RETENTION /**< */ +#define QURT_POWER_SHUTDOWN_TYPE_SAVETCM QURT_POWER_CMD_PERFORM_SAVE_TCM /**< */ +/** @} */ /* end_addtogroup power_management_macros */ +/** @endcond */ + +/* + QURT_system_state + Use for debugging the shutdown/startup process. + + State transition for cold boot: + QURT_BOOT_SETUP_ISDB --> QURT_CBOOT_BSP_INIT --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT --> + QURT_CBOOT_KERNEL_INIT_DONE --> QURT_CBOOT_PLAT_CONFIG_DONE --> + QURT_CBOOT_ROOT_TASK_STARTED + + State transition for power collapse: + QURT_PREPARE_SINGLE_MODE --> QURT_PERFORM_IPEND --> + QURT_PERFORM_SAVE_TLB --> QURT_PERFORM_SWITCH_PC --> + cache flush states (dependent on L2 retention config) + + State transition for warm boot: + QURT_BOOT_SETUP_ISDB --> QURT_WBOOT_INIT_TLB --> + QURT_WBOOT_SET_1TO1_MAP --> QURT_WBOOT_REMOVE_1TO1_MAP --> + QURT_CBOOT_END_CLEAN_INIT --> QURT_CBOOT_END_OS_INIT +*/ +#define QURT_PREPARE_SINGLE_MODE 1 /**< */ +#define QURT_PREPARE_END 2 /**< */ +#define QURT_PERFORM_IPEND 3 /**< */ +#define QURT_PERFORM_SAVE_ISDP 4 /**< */ +#define QURT_PERFORM_SAVE_PMU 5 /**< */ +#define QURT_PERFORM_SAVE_TLB 6 /**< */ +#define QURT_PERFORM_SWITCH_PC 7 /**< */ +#define QURT_PERFORM_EXIT 8 /**< */ +#define QURT_FLUSH_L1CACHE 9 /**< */ +#define QURT_FLUSH_L2CACHE 0xA /**< */ +#define QURT_FLUSH_CACHE_DONE 0xB /**< */ +#define QURT_SWITCH_PC_DONE 0xC /**< */ +#define QURT_BOOT_SETUP_ISDB 0xD /**< */ +#define QURT_WBOOT_INIT_TLB 0xE /**< */ +#define QURT_WBOOT_SET_1TO1_MAP 0xF /**< */ +#define QURT_WBOOT_CFG_ADV_SYSCFG 0x10 /**< */ +#define QURT_WBOOT_REMOVE_1TO1_MAP 0x11 /**< */ +#define QURT_CBOOT_BSP_INIT 0x12 /**< */ +#define QURT_CBOOT_END_CLEAN_L1CACHE 0x13 /**< */ +#define QURT_CBOOT_END_CLEAN_INIT 0x14 /**< */ +#define QURT_CBOOT_END_OS_INIT 0x15 /**< */ +#define QURT_CBOOT_TLB_DUMP_LOAD 0x16 /**< */ +#define QURT_CBOOT_TLB_STATIC_LOAD 0x17 /**< */ +#define QURT_CBOOT_KERNEL_INIT_DONE 0x18 /**< */ +#define QURT_CBOOT_PLAT_CONFIG_DONE 0x19 /**< */ +#define QURT_CBOOT_ROOT_TASK_STARTED 0x1A /**< */ +#define QURT_IMPRECISE_EXCEPTION 0x1B /**< */ +#define QURT_WBOOT_DEBUG_L2_START 0x1C /**< */ +#define QURT_WBOOT_DEBUG_L2_END 0x1D /**< */ +#define QURT_NMI_SAVE_L2VIC_COMPLETE 0x1E /**< */ +#define QURT_NMI_HANDLER_COMPLETE 0x1F /**< */ +#define QURT_NMI_AFTER_SAVE_GLOBAL 0x20 /**< */ +#define QURT_WBOOT_START 0x21 /**< */ +#define QURT_ENTER_ISLAND 0x22 /**< */ +#define QURT_EXIT_ISLAND 0x23 /**< */ +#define QURT_LOAD_NOTIFIER_TCB 0x24 /**< */ +#define QURT_ABNORMAL_RESET 0x25 /**< */ +/* + Thread attributes +*/ + +#define QURT_THREAD_ATTR_GP 0x00000002 /*< */ +#define QURT_THREAD_ATTR_UGP 0x00000003 /*< User general pointer (UGP)*/ +#define QURT_THREAD_ATTR_PREFETCH 0x00000004 /*< */ +#define QURT_THREAD_ATTR_TID 0x00000005 /*< */ +#define QURT_THREAD_ATTR_CACHE_PART 0x00000007 /*< */ +#define QURT_THREAD_ATTR_COPROCESSOR 0x00000008 /*< */ +#define QURT_THREAD_ATTR_GET_L2CACHE_PART 0x00000009 /*< */ +#define QURT_THREAD_ATTR_SET_FRML 0x0000000A /*< */ +#define QURT_THREAD_ATTR_STID_GET 0x0000000B /*< */ +#define QURT_THREAD_ATTR_STID_SET 0x0000000C /*< */ +#define QURT_THREAD_ATTR_AUTOSTACK 0x0000000D /*< */ +#define QURT_THREAD_ATTR_SYSTEM_THREAD 0x0000000E /*< */ +#define QURT_THREAD_ATTR_STID_SET2 0x0000000F /*< */ +#define QURT_THREAD_ATTR_STID_SET2_ACKNOWLEDGE 0x00000010 /*< */ +#define QURT_THREAD_ATTR_STID_GET2 0x00000011 /*< */ + +/** Cache operations*/ +#define QURT_DCCLEAN 0U /* Clean Dcache. */ +#define QURT_DCINV 1U /* Invalidate Dcache. */ +#define QURT_DCCLEANINV 2U /* Clean and invalidate Dcache. */ +#define QURT_ICINV 3U /* Invalidate Icache. */ +#define QURT_DUMP_DCTAGS 4U /* For testing purpose. */ +#define QURT_FLUSH_ALL 5U /* Flush entire L1 and L2 cache. */ +#define QURT_TABLE_FLUSH 6U /* Flush based on table of physical pages */ +#define QURT_CLEAN_INVALIDATE_ALL 7U /* Flush and invalidate entire L1 and L2 cache. */ +#define QURT_L2CACHE_LOCK_LINES 8U /* l2 cache lock lines */ +#define QURT_L2CACHE_UNLOCK_LINES 9U /* l2 cache unlock lines */ +#define QURT_CLEAN 10U /* Flush L1 and L2 cache */ +#define QURT_CLEAN_INVALIDATE 11U /* Flush and invalidate L1 and L2 cache. */ +#define QURT_CLEAN_INVALIDATE_L2 12U /* Flush and invalidate entire L2 cache. */ + +/**@ingroup chapter_prefined_symbols */ +/**@xreflabel{hdr:QURT_API_VERSION}*/ + + +/* Process state. */ +#define QURT_UPDATE_PROCESS_STATE 0 /**< */ +#define QURT_MP_INIT 1 /*< */ +#define QURT_MP_RUNNING 2 /*< */ +#define QURT_MP_STOPPED 3 /*< */ + +/* QuRT reset reason. */ +#define QURT_NORMAL_BOOT 0 /* Normal boot. */ +#define QURT_WARM_BOOT 1 /* Power collapse warm boot. */ +#define QURT_WARM_BOOT_L2_RETENTION 2 /* Power collapse with L2 retention warm boot. */ +#define QURT_WARM_BOOT_SAVE_TCM 3 /* Power collapse with saving TCM. */ +#define QURT_QUICK_BOOT 4 /* Deep sleep. */ + +/* QuRT Wait for Idle command */ +#define QURT_WAIT_FOR_IDLE_DISABLE 0 /*< */ +#define QURT_WAIT_FOR_IDLE_ENABLE 1 /*< */ +#define QURT_WAIT_FOR_IDLE 2 /*< */ +#define QURT_WAIT_FOR_IDLE_CANCEL 3 /*< */ + +/*QuRT island exit stages */ +#define QURT_ISLAND_EXIT_STAGE1 1 /*< */ +#define QURT_ISLAND_EXIT_STAGE2 2 /*< */ + +#define QURT_MAX_NAME_LEN 64 /*< */ + +#define MAX_POOL_RANGES 16 /*< */ + +/* key definitions for debug thread info */ +//#define MAX_TCB_KEY 40 //whatever is a good number or makes debug thread structure be 1K +#define KEY_SCHDULER_STATE 1 /*< */ +#define KEY_PRIORITY 2 /*< */ +#define KEY_PRIORITY_ORIG 3 /*< */ +#define KEY_STACK_BOTTOM 4 // Currently not populated +#define KEY_STACK_TOP 5 // Currently not populated +#define KEY_HVX_STATE 6 /*< */ +#define KEY_FUTEX_OBJECT 7 /*< */ +#define KEY_THREAD_ID 8 /*< */ +#define KEY_PROFILE_CYCLE_LO 9 // Currently not populated +#define KEY_PROFILE_CYCLE_HI 10 // Currently not populated +#define KEY_ERROR_ADDRESS 11 // This holds the BADVA +#define KEY_ERROR_CAUSE 12 // This is the same as QURT_error_info.cause +#define KEY_ERROR_CAUSE2 13 // This is the same as QURT_error_info.cause2 +#define KEY_ERROR_SSR 14 /*< Holds the SSR value */ +#define QURT_RESERVED -1 + +/* VTLB method IDs. */ +#define QURT_VTLB_ENTRY_CREATE 0U +#define QURT_VTLB_ENTRY_DELETE 1U +#define QURT_VTLB_ENTRY_READ 2U +#define QURT_VTLB_ENTRY_WRITE 3U +#define QURT_VTLB_ENTRY_PROBE 4U +#define QURT_VTLB_ENTRY_SPLIT 5U +#define QURT_VTLB_ENTRY_MERGE 6U +#define QURT_VTLB_ENTRY_STATISTICS 7U +#define QURT_VTLB_ENTRY_SET_SPECIAL 8U +#define QURT_VTLB_QUEUE_PPAGE 9U +#define QURT_VTLB_RECLAIM_STACK_PAGES 10U +#define QURT_VTLB_ASID_SET_STATE_FAST 11U +#define QURT_VTLB_ASID_SET_STATE 12U +#define QURT_VTLB_ENTRY_SET_EXTENSION 13U +#define QURT_VTLB_ENTRY_CLEAR_EXTENSION 14U + +/* VTCM window access control HWIO programming. */ +#define QURT_VTCM_WINDOW_ENABLE 1U +#define QURT_VTCM_WINDOW_DISABLE 0U +#define QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT 0xFFFU +#define QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT 0U + +/** @cond */ +/* ETM source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< Memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< Memory source of SAC* is data. */ + +/* ETM PID status flags */ +#define QURT_ETM_NO_PID 0xFFFFFFFF /**< No PID is selected. */ +/** @endcond */ + +/* execution context */ +#define QURT_CTX_USER 1 +#define QURT_CTX_GUEST 2 + +/* Profiling STID */ +#define QURT_STID_DEFAULT 0U + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cycles.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cycles.h new file mode 100755 index 0000000000000..b599493f5d563 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_cycles.h @@ -0,0 +1,301 @@ + +#ifndef QURT_CYCLES_H +#define QURT_CYCLES_H 1 +/** + @file qurt_cycles.h + Prototypes of kernel pcycle API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ + +/**@ingroup func_qurt_profile_reset_idle_pcycles + @xreflabel{hdr:qurt_profile_reset_idle_pcycles} + Sets the per-hardware-thread idle cycle counts to zero. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_idle_pcycles (void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_thread_pcycles + @xreflabel{hdr:qurt_profile_get_thread_pcycles} + Gets the count of the running processor cycles for the current thread.\n + Returns the current running processor cycle count for the current QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @return + Integer -- Running processor cycle count for current thread. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_profile_get_thread_pcycles(void); + + +/*======================================================================*/ +/**@ingroup func_qurt_get_core_pcycles + @xreflabel{hdr:qurt_get_core_pcycles} + Gets the count of core processor cycles executed.\n + Returns the current number of running processor cycles executed since the Hexagon + processor was last reset. + + This value is based on the hardware core clock, which varies in speed according to the + processor clock frequency. + + @note1hang Because the hardware core clock stops running when the processor shuts + down (due to all of the hardware threads being idle), treat the cycle values returned + by this operation as relative rather than absolute. + + @note1cont Thread cycle counts are valid only in the V4 Hexagon processor version. + + @return + Integer -- Current count of core processor cycles. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long int qurt_get_core_pcycles(void); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles + + @deprecated use #qurt_profile_get_idle_pcycles2 instead + + Gets the current idle processor cycle counts for a maximum of 6 hardware threads. Use + #qurt_profile_get_idle_pcycles2 for reading pcycles without limitation on maximum hardware threads. + + This operation accepts a pointer to a user-defined array, and writes to the array the current + idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling is enabled or not, + and resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be a minimum of the number of hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_idle_pcycles (unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_idle_pcycles2 + Gets the current idle processor cycle counts for maximum available hardware threads. + + This operation accepts a pointer to a user-defined array with length in bytes, and writes + to the array the current idle cycle count for each hardware thread. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been in Wait mode.\n + + @note1hang This operation does not return the idle cycles that occur when the Hexagon + processor shuts down (due to all of the hardware threads being idle). + Idle cycle counts gets accumulated irrespective of profiling enable status, and + resets on #qurt_profile_reset_idle_pcycles + + @param[out] pcycles User array where the function stores the current idle cycle count values. + Array size should be equivalent to the number of hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, + it returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_idle_pcycles2 (unsigned long long *pcycles, unsigned int length_in_bytes); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles + + @deprecated use #qurt_profile_get_threadid_pcycles2 instead + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for a maximum of 6 hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Valid thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be a minimum of the number of + hardware threads intended. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_get_threadid_pcycles (int thread_id, unsigned long long *pcycles); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_get_threadid_pcycles2 + + Gets the current per-hardware-thread running cycle counts for the specified QuRT + thread for maximum available hardware threads. + + Each count value represents the number of processor cycles that have elapsed on the + corresponding hardware thread while that thread has been scheduled for the specified + QuRT thread. + + @note1hang Profiling shall be enabled first to start the cycle counting. + The cycles are accumulated once the profiling is enabled and + resets on #qurt_profile_reset_threadid_pcycles + + @param[in] thread_id Thread identifier. + @param[out] pcycles Pointer to a user array where the function stores the current running + cycle count values. Array size should be equivalent to the number of + hardware threads intended. + Call #qurt_sysenv_get_max_hw_threads to determine the array size required. + @param[in] length_in_bytes Length of pcycles array in bytes. If the array size is smaller + than the required for the maximum available hardware threads, it + returns error code. + + @return + #QURT_EOK -- Successful operation. Stored all the data to the destination array + #QURT_EFAILED -- Operation failed due to smaller #pcycles array + #QURT_ENOTHREAD -- Operation failed due to invalid #thread_id + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_profile_get_threadid_pcycles2 (int thread_id, unsigned long long *pcycles, unsigned int length_in_bytes); + + +/*======================================================================*/ +/**@ingroup func_qurt_profile_reset_threadid_pcycles + @xreflabel{hdr:qurt_profile_reset_threadid_pcycles} + Sets the per-hardware-thread running cycle counts to zero for the specified QuRT thread. + + @param[in] thread_id Thread identifier. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_reset_threadid_pcycles (int thread_id); + +/*======================================================================*/ +/**@ingroup func_qurt_profile_enable + @xreflabel{hdr:qurt_profile_enable} + Enables profiling.\n + Enables or disables cycle counting of the running and idle processor cycles. + Profiling is disabled by default. \n + + @note1hang Enabling profiling does not automatically reset the cycle counts -- this must be + done explicitly by calling the reset operations before starting cycle counting. + Cycle counting starts from the instant of it was enabled using this API, and + halts on profiling disable. + + @param[in] enable Profiling. Values: \n + - 0 -- Disable profiling \n + - 1 -- Enable profiling @tablebulletend + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_profile_enable (int enable); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_pcycles + @xreflabel{hdr:qurt_get_hthread_pcycles} + Reads the GCYCLE_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values are 1 through . + + + @return + Value read from GCYCLE_nT register. This value indicates the total number of pcycles that got executed + from reset to current point of execution when n threads are in run mode + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_pcycles(int n); + +/*======================================================================*/ +/**@ingroup func_qurt_get_hthread_commits + @xreflabel{hdr:qurt_get_hthread_commits} + Reads the GCOMMIT_nT register to allow performance measurement when N threads are in run mode.\n + + @note1hang Returns 0 when architecture is earlier than v67 or for invalid HW thread id. + + @param[in] n Threads in run mode. Valid values: 1 through . + + @return + Value read from the GCOMMIT_nT register. This value indicates the total number of packets + committed from reset to current point of execution when n threads are in run mode. + + @dependencies + PMU must be enabled. +*/ +/* ======================================================================*/ +unsigned int qurt_get_hthread_commits(int n); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_devtree.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_devtree.h new file mode 100755 index 0000000000000..4adee45bb44a2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_devtree.h @@ -0,0 +1,161 @@ +#ifndef QURT_DEVTREE_H +#define QURT_DEVTREE_H +/** + @file qurt_devtree.h + @brief Prototypes and structures for device tree aware QuRT library function. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +*/ +/*qurt_callback is included by qurt_qdi_driver.h and depends on NULL being def. + callback is not used here, so define NULL here to avoid including the world*/ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "libfdt.h" +#include "DTBExtnLib.h" +#include "qurt_qdi_ext.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INVALID_BLOB_ID (-1) +#define DEFAULT_BLOB_ID 0 + +/** QURT Device Tree Mapping Macros */ +#define QURT_DT_MAPPING_FAILED (-1) +#define QURT_DT_FLAG_ISLAND 0x1 +#define QURT_DT_FLAG_PHYSADDR 0x2 + +/** Device Tree type for Root PD Device tree. +    Root PD Device Tree will typically describe the hardware in the subsystem. +    This is the /soc portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_ROOT 0 + +/** Device Tree type for Local Device tree. +    Local Device Tree will typically contain the software settings. +    This is the /sw portion of the Device Tree. */ +#define QURT_DT_BLOB_TYPE_LOCAL 1 + +int qurt_devtree_init(void); + +/**@ingroup func_qurt_dt_mapping_create + Creates a memory mapping from the specified property of the specified device + tree node. Returns virtual addresses and sizes. + + @param[in] offset Device tree node offset. + @param[in] flags Flags to configure memory. Overloaded as property + index if reg_name is NULL. + @param[in] reg_name Identifies property to use for mapping, should + resemble a region. + @param[out] vaddr Return pointer for the virtual region address. + @param[out] size Return pointer for the virtual region size. + + @return + Result code indicating success or failure \n +*/ +int qurt_dt_mapping_create(fdt_node_handle *devtreeNode, int flags, char *regionName, int regionIdx, + unsigned long long *vaddr, unsigned long long *size); + +/**@ingroup func_qurt_dt_mapping_create2 + + Creates a memory mapping from the specified property of the specified device + tree node. + + Returns virtual addresses and sizes according to architecture (i.e either 32 bit or 64 bit). + + @param[in] devtreeNode Device Tree node + + @param[in] dt_map_flags Flags to configure memory mapping and are reserved for future purpose. + (0) - Default value assumes details from DT node are phys address, size. + QURT_DT_FLAG_ISLAND + + NOTE: The PA needs to be added to corresponding island spec to create an island mapping + + @param[in] regionName NULL or name of index in range to return, should + resemble a region. Ex.reg-names = "base", "rx", "tx"; + + @param[in] regionIdx Index of range to return. Ex reg = <0x1000 0x20>, <0x10000 0x100>, <0x18000 0x100 >; + + NOTE: If client specifies both re_name & regionIdx. The precedence of + region name is taken over and region index is ignored. + + @param[in] dt_map_perm Mapping access permissions(R/W), + QURT_PERM_READ + QURT_PERM_WRITE + + @param[in] cache_attr QuRT cache mode type's : + QURT_MEM_CACHE_DEVICE + QURT_MEM_CACHE_WRITEBACK + Other required cache type enums in qurt_types.h can also be passed. + + NOTE: No default value for cache & perm is present. + Client always needs to pass any of defined the flags. + + @param[out] vaddr Return pointer to the variable that holds the virtual address + @param[out] size Return pointer for the virtual region size. + + @return + #QURT_EOK Success indicating mapping created properly. + #QURT_DT_MAPPING_FAILED Failed to create mapping. + #QURT_EINVALID Mismatch in the architecture. + + else FdtLib or thirdparty error code. + +*/ +int qurt_dt_mapping_create2(fdt_node_handle *devtreeNode, unsigned int dt_map_flags, + char *regionName, int regionIdx, unsigned int dt_map_perm, int cache_attr, void **vaddr, size_t *size); + +/**@ingroup func_qurt_dt_isr_register + Device tree aware registration of an interrupt service routine (ISR) to an ISR thread. + The interrupt defined in the specified device tree node is enabled when this function returns success. + + @datatypes + #qurt_thread_t \n + #fdt_node_handle + + @param[in] dt_node Device tree node that specifies the interrupt property. + @param[in] dt_int_index Index of the specific interrupt to use within the device tree node structure. + Specify either this or int_name, use -1 if string is used. + @param[in] dt_int_name Name of the specific interrupt to use within the device tree node structure. + Either this or int_index should be specified, use NULL if index is used + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create(), defined by qurt_isr_register2(). + @param[in] prio Priority of the ISR, defined by qurt_isr_register2(). + @param[in] flags Defines ACK type. Values : \n + #QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the kernel. + #QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + Defined by qurt_isr_register2(). + @param[in] isr ISR with proto type void isr (void *arg, int int_num), defined by qurt_isr_register2(). + @param[in] arg First argument of the ISR when it is called to service the interrupt, defined by qurt_isr_register2(). + + @return + #QURT_EOK -- Successfully registered the ISR for the interrupt \n + #QURT_EINT -- Interrupt not configured \n + #QURT_EINVALID -- Invalid thread ID \n + #QURT_EDISABLED -- The feature is disabled \n + #QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Create the thread ID qurt_isr_create(). + ISR registration completed with qurt_isr_register2(). + */ +int qurt_dt_isr_register(fdt_node_handle *dt_node, int dt_int_index, char * dt_int_name, qurt_thread_t isr_thread_id, + unsigned short prio, unsigned short flags, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_dt_blob_id_get + Returns the Blob ID for the Blob type passed. + The value returned from this API can be passed as Blob ID parameter to DTBExtnLib APIs. + + @param[in] blob_type  Blob type to look up. + @return Blob ID for the passed Blob Type. +*/ +int qurt_dt_blob_id_get(unsigned int blob_type); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ecc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ecc.h new file mode 100755 index 0000000000000..09312684e99af --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ecc.h @@ -0,0 +1,168 @@ +#ifndef QURT_ECC_H +#define QURT_ECC_H + + +/*===================================================================== + + @file qurt_ecc.h + @brief Prototypes of QuRT memory ECC API functions + + Copyright (c) 2018, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup exception_handling_types +@{ */ +// ECC memory definition +typedef enum { + QURT_ECC_MEM_L1_ICACHE = 0, /**< ECC memory L1 ICache. */ + QURT_ECC_MEM_L1_DCACHE = 1, /**< ECC memory L1 DCache.*/ + QURT_ECC_MEM_L2_CACHE = 2, /**< ECC memory L2 Cache.*/ + QURT_ECC_MEM_VTCM = 3 /**< ECC memory VTCM.*/ +} qurt_ecc_memory_t; +/** @} */ /* end_addtogroup exception_handling_types */ + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup exception_handling_macros +@{ */ + +#define QURT_ECC_ERR_DETECTED_STATUS 0 /**< ECC error detected. */ +#define QURT_ECC_ERR_TYPE 1 /**< ECC error type.*/ +// ECC status type + +#define QURT_ECC_CORRECTABLE_COUNT (1<<0) /**< ECC correctable count.*/ +#define QURT_ECC_UNCORRECTABLE_COUNT (1<<1) /**< ECC uncorrectable count.*/ +#define QURT_ECC_REGION_LOGGING (1<<2) /**< ECC region logging.*/ +// ECC enable/disable definition + +#define QURT_ECC_PROTECTION_DISABLE (0<<0) /**< Bit 0. */ +#define QURT_ECC_PROTECTION_ENABLE (1<<0) /**< Bit 0. */ +/** @} */ /* end_addtogroup exception_handling_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_ecc_enable + Enables or disables ECC protection on a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] enable Set to one of the following values: + - #QURT_ECC_PROTECTION_ENABLE + - #QURT_ECC_PROTECTION_DISABLE @tablebulletend + + @return + - #QURT_EOK -- ECC enabling or disabling setup is performed successfully + - Others -- Failure + + @dependencies + None. + */ +int qurt_ecc_enable( qurt_ecc_memory_t memory, unsigned int enable ); + + +/**@ingroup func_qurt_ecc_get_error_status + Gets ECC error status for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following: + - #QURT_ECC_MEM_L1_ICACHE + - #QURT_ECC_MEM_L1_DCACHE + - #QURT_ECC_MEM_L2_CACHE + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following: + - #QURT_ECC_ERR_DETECTED_STATUS + - #QURT_ECC_ERR_TYPE @tablebulletend + + @return + Returns the following when the type is #QURT_ECC_ERR_DETECTED_STATUS: + - 0 -- No error detected \n + - 1 -- At least one error detected \n + Returns the following when the type is #QURT_ECC_ERR_TYPE: \n + - 0 through 1 -- Correctable error \n + - 2 -- Uncorrectable error + + @dependencies + None. + */ +int qurt_ecc_get_error_status( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_get_error_count + Gets the ECC error count for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values:\n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT @tablebulletend + + @return + Error count for the specified error type. + + @dependencies + None. + */ +int qurt_ecc_get_error_count( qurt_ecc_memory_t memory, unsigned int type ); + + +/**@ingroup func_qurt_ecc_clear_error_count + Clears ECC error count or region logging for a specified memory. + + @datatypes + #qurt_ecc_memory_t + + @param[in] memory Set to one of the following values: \n + - #QURT_ECC_MEM_L1_ICACHE \n + - #QURT_ECC_MEM_L1_DCACHE \n + - #QURT_ECC_MEM_L2_CACHE \n + - #QURT_ECC_MEM_VTCM @tablebulletend + + @param[in] type Set to one or multiple OR'ed of the following values: \n + - #QURT_ECC_CORRECTABLE_COUNT \n + - #QURT_ECC_UNCORRECTABLE_COUNT \n + - #QURT_ECC_REGION_LOGGING @tablebulletend + + @return + #QURT_EOK -- Error count successfully cleared \n + Others -- Failure at clearing the error count + + @dependencies + None. + */ +int qurt_ecc_clear_error_count( qurt_ecc_memory_t memory, unsigned int type ); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ECC_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_error.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_error.h new file mode 100755 index 0000000000000..f4666b396c378 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_error.h @@ -0,0 +1,149 @@ +#ifndef QURT_ERROR_H +#define QURT_ERROR_H + +/** + @file qurt_error.h + Error results- QURT defines a set of standard symbols for the error result values. This file lists the + symbols and their corresponding values. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021-2022 , 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ +#include "qurt_except.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup chapter_error +@{ */ + +/*===================================================================== +Constants and macros +======================================================================*/ +#define QURT_EOK 0 /**< Operation successfully performed. */ +#define QURT_EVAL 1 /**< Wrong values for the parameters. The specified page does not exist. */ +#define QURT_EMEM 2 /**< Not enough memory to perform the operation.*/ + +#define QURT_EINVALID 4 /**< Invalid argument value; invalid key. */ +/** @cond */ +#define QURT_EUNKNOWN 6 /**< Defined but never used in QuRT. */ +#define QURT_ENOMSGS 7 /**< Message queue is empty. */ +#define QURT_EBADF 9 /**< Bad message queue descriptor. */ +/** @endcond */ +#define QURT_EFAILED 12 /**< Operation failed. */ + +#define QURT_ENOTALLOWED 13 /**< Operation not allowed. */ + +/** @cond */ +#define QURT_EDUPCLSID 14 /*< Duplicate class ID. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOREGISTERED 20 /**< No registered interrupts.*/ +/** @endcond */ + + +/** @cond */ +#define QURT_EISDB 21 /*< Power collapse failed due to ISDB being enabled. */ +#define QURT_ESTM 22 /*< Power collapse failed in a Single-threaded mode check. */ +/** @endcond */ + + +/** @cond rest_reg_dist */ +#define QURT_ETLSAVAIL 23 /**< No free TLS key is available. */ +#define QURT_ETLSENTRY 24 /**< TLS key is not already free. */ +/** @endcond */ + +#define QURT_EINT 26 /**< Invalid interrupt number (not registered). */ +/** @cond rest_reg_dist */ +#define QURT_ESIG 27 /**< Invalid signal bitmask (cannot set more than one signal at a time). */ +/** @endcond */ + +/** @cond */ +#define QURT_EHEAP 28 /**< No heap space is available. */ +#define QURT_ENOSPC 28 /**< No space to create another queue in the system. */ +#define QURT_EMEMMAP 29 /**< Physical address layout is not supported by the kernel. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_ENOTHREAD 30 /**< Thread no longer exists. */ +/** @endcond */ +/** @cond */ +#define QURT_EL2CACHE 31 /**< L2cachable is not supported in kernel invalidate/cleaninv. */ +/** @endcond */ +/** @cond rest_reg_dist */ +#define QURT_EALIGN 32 /**< Not aligned. */ +#define QURT_EDEREGISTERED 33 /**< Interrupt is already deregistered.*/ +/** @endcond */ + +/** @cond internal_only */ + +#define QURT_ETLBCREATESIZE 34 /**< TLB create error -- Incorrect size.*/ +#define QURT_ETLBCREATEUNALIGNED 35 /**< TLB create error -- Unaligned address.*/ +/** @endcond */ +/** @cond rest_reg_dist*/ +#define QURT_EEXISTS 35 /**< File or message queue already exists. */ +#define QURT_ENAMETOOLONG 36 /**< Name too long for message queue creation. */ +#define QURT_EPRIVILEGE 36 /**< Caller does not have privilege for this operation.*/ + +#define QURT_ECANCEL 37 /**< A cancellable request was canceled because the associated process was asked to exit.*/ +/** @endcond */ + +/** @cond */ +#define QURT_EISLANDTRAP 38 /*< Unsupported TRAP is called in Island mode.*/ + +#define QURT_ERMUTEXUNLOCKNONHOLDER 39 /*< Rmutex unlock by a non-holder.*/ +#define QURT_ERMUTEXUNLOCKFATAL 40 /*< Rmutex unlock error, all except the non-holder error.*/ +#define QURT_EMUTEXUNLOCKNONHOLDER 41 /*< Mutex unlock by a non-holder.*/ +#define QURT_EMUTEXUNLOCKFATAL 42 /*< Mutex unlock error, all except the non-holder error.*/ +#define QURT_EINVALIDPOWERCOLLAPSE 43 /*< Invalid power collapse mode requested. */ +/** @endcond */ +#define QURT_EISLANDUSEREXIT 44 /**< User call has resulted in island exit.*/ +#define QURT_ENOISLANDENTRY 45 /**< Island mode had not yet been entered.*/ +#define QURT_EISLANDINVALIDINT 46 /**< Exited Island mode due to an invalid island interrupt.*/ +/** @cond rest_reg_dist */ +#define QURT_ETIMEDOUT 47 /**< Operation timed-out. */ +#define QURT_EALREADY 48 /**< Operation already in progress. */ +/** @endcond */ + +#define QURT_ERETRY 49 /*< Retry the operation. */ +#define QURT_EDISABLED 50 /*< Resource disabled. */ +#define QURT_EDUPLICATE 51 /*< Duplicate resource. */ +#define QURT_EBADR 53 /*< Invalid request descriptor. */ +#define QURT_ETLB 54 /*< Exceeded maximum allowed TLBs. */ +#define QURT_ENOTSUPPORTED 55 /*< Operation not supported. */ +/** @cond rest_reg_dist */ +#define QURT_ENORESOURCE 56 /**< No resource. */ +/** @endcond */ + +#define QURT_EDTINIT 57 /**< Problem with device tree intialization. */ +#define QURT_EBUFLOCK 58 /*< Buffer lock failed because it was already locked many times. */ +#define QURT_ELOCKED 59 /**< Current operation failed as the buffer is locked. */ +#define QURT_EMSGSIZE 90 /*< Message queue msg_len is greater than mq_msgsize attribute of the message queue. */ + + +#define QURT_ENOTCONFIGURED 91 /*< Interrupt is NOT configured. */ + +#define QURT_EBANDWIDTHLIMIT 92 /*< Message queue send exceed the bandwidth limit. */ + +#define QURT_ECFIVIOLATION 93 /*< CFI violation detected. */ + +#define QURT_EDESTROY 94 /**< A destroy request was made to waiting threads.*/ + +#define QURT_EHMXNOTAVAIL 95 /**< HMX is not available to target thread.*/ +#define QURT_EHMXNOTDETACHABLE 96 /**< HMX is not detachable from target thread.*/ + +#define QURT_EFATAL -1 /**< Fatal error. */ + +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ERROR_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_event.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_event.h new file mode 100755 index 0000000000000..987f0fe79f227 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_event.h @@ -0,0 +1,452 @@ +#ifndef QURT_EVENT_H +#define QURT_EVENT_H +/** + @file qurt_event.h + @brief Prototypes of kernel event API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "qurt_consts.h" +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System environment object type. + */ +/**@addtogroup sys_env_types +@{ */ +/** QuRT swap pool information type. */ +typedef struct qurt_sysenv_swap_pools { + /** @cond */ + unsigned int spoolsize; /* Swap pool size.*/ + unsigned int spooladdr; /* Swap pool start address.*/ + /** @endcond */ +}qurt_sysenv_swap_pools_t; + +/**QuRT application heap information type. */ +typedef struct qurt_sysenv_app_heap { + /** @cond */ + unsigned int heap_base; /* Heap base address.*/ + unsigned int heap_limit; /* Heap end address.*/ + /** @endcond */ +} qurt_sysenv_app_heap_t ; + +/** QuRT architecture version information type. */ +typedef struct qurt_sysenv_arch_version { + /** @cond */ + unsigned int arch_version; /*Architecture version.*/ + /** @endcond */ +}qurt_arch_version_t; + +/** QuRT maximum hardware threads information type. */ +typedef struct qurt_sysenv_max_hthreads { + /** @cond */ + unsigned int max_hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_max_hthreads_t; + +/** QuRT active hardware threads information type. */ +typedef struct qurt_sysenv_hthreads { + /** @cond */ + unsigned int hthreads; /*Maximum number of hardware threads.*/ + /** @endcond */ +}qurt_sysenv_hthreads_t; + +/** QuRT maximum pi priority information type. */ +typedef struct qurt_sysenv_max_pi_prio { + /** @cond */ + unsigned int max_pi_prio; /*Maximum pi priority.*/ + /** @endcond */ +}qurt_sysenv_max_pi_prio_t; + +/** QuRT process name information type. */ +typedef struct qurt_sysenv_procname { + /** @cond */ + union { + unsigned int asid; /*Address space ID.*/ + unsigned int pid; /*Process ID.*/ + }; + char name[QURT_MAX_NAME_LEN]; /* Process name.*/ + /** @endcond */ +}qurt_sysenv_procname_t; + +/** QuRT stack profile count information type. */ +typedef struct qurt_sysenv_stack_profile_count { + /** @cond */ + unsigned int count; /*Stack profile count for usage.*/ + unsigned int count_watermark; /*Stack profile count for watermark.*/ + /** @endcond */ +}qurt_sysenv_stack_profile_count_t; + +/** + QuRT system error event type. + */ +typedef struct _qurt_sysevent_error_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + } qurt_sysevent_error_t ; + +typedef struct _qurt_sysevent_error_1_t +{ + unsigned int thread_id; /**< Thread ID. */ + unsigned int fault_pc; /**< Fault PC. */ + unsigned int sp; /**< Stack pointer. */ + unsigned int badva; /**< Virtual data address where the exception occurred. */ + unsigned int cause; /**< QuRT error result. */ + unsigned int ssr; /**< Supervisor status register. */ + unsigned int fp; /**< Frame pointer. */ + unsigned int lr; /**< Link register. */ + unsigned int pid; /**< PID of the process to which this thread belongs.*/ + unsigned int fkey; /**< Framekey.*/ + unsigned int reserved1; /**< Reserved.*/ + unsigned int reserved2; /**< Reserved.*/ + unsigned int reserved3; /**< Reserved.*/ + } qurt_sysevent_error_1_t ; + +/** QuRT page fault error event information type. */ +typedef struct qurt_sysevent_pagefault { + qurt_thread_t thread_id; /**< Thread ID of the page fault thread. */ + unsigned int fault_addr; /**< Accessed address that caused the page fault. */ + unsigned int ssr_cause; /**< SSR cause code for the page fault. */ +} qurt_sysevent_pagefault_t ; +/** @} */ /* @endaddtogroup sys_env_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/*======================================================================*/ +/** + Gets the environment swap pool 0 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool0 (qurt_sysenv_swap_pools_t *pools ); + +/* + Gets the environment swap pool 1 information from the kernel. + + @datatypes + #qurt_sysenv_swap_pools_t + + @param[out] pools Pointer to the pools information. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_swap_spool1(qurt_sysenv_swap_pools_t *pools ); + +/**@ingroup func_qurt_sysenv_get_app_heap + Gets information on the program heap from the kernel. + + @datatypes + #qurt_sysenv_app_heap_t + + @param[out] aheap Pointer to information on the program heap. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_app_heap(qurt_sysenv_app_heap_t *aheap ); + +/**@ingroup func_qurt_sysenv_get_arch_version + Gets the Hexagon processor architecture version from the kernel. + + @datatypes + #qurt_arch_version_t + + @param[out] vers Pointer to the Hexagon processor architecture version. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter + + @dependencies + None. +*/ +int qurt_sysenv_get_arch_version(qurt_arch_version_t *vers); + +/**@ingroup func_qurt_sysenv_get_max_hw_threads + Gets the maximum number of hardware threads supported in the Hexagon processor. + The API includes the disabled hardware threads to reflect the maximum + hardware thread count. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, only HW0 and HW2 are initialized by QuRT. + HW1 and HW3 are not used at all. Under such a scenario, + qurt_sysenv_get_max_hw_threads() still returns four. + + @datatypes + #qurt_sysenv_max_hthreads_t + + @param[out] mhwt Pointer to the maximum number of hardware threads supported in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_hw_threads(qurt_sysenv_max_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_hw_threads + Gets the number of hardware threads initialized by QuRT in Hexagon processor. + For example, if the image is configured for four hardware threads and hthread_mask is set to 0x5 in + cust_config.xml, QuRT only initializes HW0 and HW2. + HW1 and HW3 are not used. In this scenario, qurt_sysenv_get_hw_threads() returns 2. + + @datatypes + #qurt_sysenv_hthreads_t + + @param[out] mhwt Pointer to the number of hardware threads active in the Hexagon processor. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_hw_threads(qurt_sysenv_hthreads_t *mhwt ); + +/**@ingroup func_qurt_sysenv_get_max_pi_prio + Gets the maximum priority inheritance mutex priority from the kernel. + + @datatypes + #qurt_sysenv_max_pi_prio_t + + @param[out] mpip Pointer to the maximum priority inheritance mutex priority. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_max_pi_prio(qurt_sysenv_max_pi_prio_t *mpip ); + +/**@ingroup func_qurt_sysenv_get_process_name2 + Gets information on the system environment process names based on the client_handle argument. + + @datatypes + #qurt_sysenv_procname_t + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name2(int client_handle, qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_process_name + Gets information on the system environment process names from the kernel. + + @datatypes + #qurt_sysenv_procname_t + + @param[out] pname Pointer to information on the process names in the system. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Invalid parameter. + + @dependencies + None. +*/ +int qurt_sysenv_get_process_name(qurt_sysenv_procname_t *pname ); + +/**@ingroup func_qurt_sysenv_get_stack_profile_count + Gets information on the stack profile count from the kernel. + + @datatypes + #qurt_sysenv_stack_profile_count_t + + @param[out] count Pointer to information on the stack profile count. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_sysenv_get_stack_profile_count(qurt_sysenv_stack_profile_count_t *count ); + +/**@ingroup func_qurt_exception_wait + Registers the program exception handler. + This function assigns the current thread as the QuRT program exception handler and suspends the + thread until a program exception occurs. + + When a program exception occurs, the thread is awakened with error information + assigned to the parameters of this operation. + + @note1hang If no program exception handler is registered, or if the registered handler + calls exit, QuRT raises a kernel exception. + If a thread runs in Supervisor mode, any errors are treated as kernel + exceptions. + + @param[out] ip Pointer to the instruction memory address where the exception occurred. + @param[out] sp Stack pointer. + @param[out] badva Pointer to the virtual data address where the exception occurred. + @param[out] cause Pointer to the QuRT error result code. + + @return + Registry status: \n + Thread identifier -- Handler successfully registered. \n + #QURT_EFATAL -- Registration failed. + + @dependencies + None. +*/ +unsigned int qurt_exception_wait (unsigned int *ip, unsigned int *sp, + unsigned int *badva, unsigned int *cause); + +unsigned int qurt_exception_wait_ext (qurt_sysevent_error_t * sys_err); + +/**@ingroup func_qurt_exception_wait3 + Registers the current thread as the QuRT program exception handler, and suspends the thread until a + program exception occurs. + When a program exception occurs, the thread is awakened with error information assigned to the specified + error event record. + If a program exception is raised when no handler is registered (or when a handler is registered, but it calls + exit), the exception is treated as fatal.\n + @note1hang If a thread runs in Monitor mode, all exceptions are treated as kernel exceptions.\n + @note1cont This function differs from qurt_exception_wait() by returning the error information in a data + structure rather than as individual variables. It also returns additional information (for example, SSR, FP, and LR). + + @param[out] sys_err Pointer to the qurt_sysevent_error_1_t type structure. + @param[in] sys_err_size Size of the qurt_sysevent_error_1_t structure. + + @return + Registry status: \n + - #QURT_EFATAL -- Failure. \n + - Thread ID -- Success. + + @dependencies + None. +*/ + +unsigned int qurt_exception_wait3(void * sys_err, unsigned int sys_err_size); + +/**@ingroup func_qurt_exception_raise_nonfatal + Raises a nonfatal program exception in the QuRT program system. + + For more information on program exceptions, see Section @xref{dox:exception_handling}. + + This operation never returns -- the program exception handler is assumed to perform all + exception handling before terminating or reloading the QuRT program system. + + @note1hang The C library function abort() calls this operation to indicate software + errors. + + @param[in] error QuRT error result code (Section @xref{dox:error_results}). + + @return + Integer -- Unused. + + @dependencies + None. +*/ +int qurt_exception_raise_nonfatal (int error) __attribute__((noreturn)); + + +/**@ingroup func_qurt_exception_raise_fatal + Raises a fatal program exception in the QuRT system. + + Fatal program exceptions terminate the execution of the QuRT system without invoking + the program exception handler. + + For more information on fatal program exceptions, see Section @xref{dox:exception_handling}. + + This operation always returns, so the calling program can perform the necessary shutdown + operations (data logging, on so on). + + @note1hang Context switches do not work after this operation has been called. + + @return + None. + + @dependencies + None. +*/ +void qurt_exception_raise_fatal (void); + +unsigned int qurt_enable_floating_point_exception(unsigned int mask); + +/**@ingroup func_qurt_exception_enable_fp_exceptions + Enables the specified floating point exceptions as QuRT program exceptions. + + The exceptions are enabled by setting the corresponding bits in the Hexagon + control user status register (USR). + + The mask argument specifies a mask value identifying the individual floating + point exceptions to set. The exceptions are represented as defined symbols + that map into bits 0 through 31 of the 32-bit flag value. + Multiple floating point exceptions are specified by OR'ing together the individual + exception symbols.\n + @note1hang This function must be called before performing any floating point operations. + + @param[in] mask Floating point exception types. Values: \n + - #QURT_FP_EXCEPTION_ALL \n + - #QURT_FP_EXCEPTION_INEXACT \n + - #QURT_FP_EXCEPTION_UNDERFLOW \n + - #QURT_FP_EXCEPTION_OVERFLOW \n + - #QURT_FP_EXCEPTION_DIVIDE0 \n + - #QURT_FP_EXCEPTION_INVALID @tablebulletend + + @return + Updated contents of the USR. + + @dependencies + None. +*/ + +static inline unsigned int qurt_exception_enable_fp_exceptions(unsigned int mask) +{ + return qurt_enable_floating_point_exception(mask); +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EVENT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_except.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_except.h new file mode 100755 index 0000000000000..e1684c80e3d50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_except.h @@ -0,0 +1,185 @@ +#ifndef QURT_EXCEPT_H +#define QURT_EXCEPT_H + +/** + @file qurt_except.h + @brief Defines Cause and Cause2 codes for error-handling. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. + + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + QuRT supports error handling to handle CPU detected exceptions and software errors. + QuRT treats all errors as either fatal errors or nonfatal errors. + + @section sec1 Fatal errors + All supervisor mode exceptions are treated as fatal errors. + If a registered exception handler calls qurt_exit(), it is treated as a fatal error. + Fatal errors result in saving the context of primary hardware thread to QURT_error_info and the rest of the thread contexts to the corresponding TCBs. + All hardware threads are eventually stopped and the cache is flushed. + NMI exception is treated little differently from other fatal errors. QuRT saves the contexts of all the hardware threads into QURT_error_info.\n + + @subsection subsection1 Debugging fatal errors + - QURT_error_info.status.status -- Indicates that an error occured. + - QURT_error_info.status.cause -- Cause code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.cause2 -- Cause2 code for fatal error; Cause and Cause 2 details are listed below. + - QURT_error_info.status.fatal -- Indicates whether a fatal error occurred. A user error can result in a fatal error if the exceptional handler is not registered. + - QURT_error_info.status.hw_tnum -- Indicates the index of QURT_error_info.locregs[], where the context is saved when the error is fatal error. + - QURT_error_info.global_regs -- Contains the values of the global registers of Q6 + - QURT_error_info.local_regs[QURT_error_info.status.hw_tnum] -- Provides the CPU context when the error is a supervisor error. + + + + @subsection subsection2 Debugging nonfatal errors + - QURT_error_info.user_errors -- All user errors are logged here. + - QURT_error_info.user_errors.counter -- Index to last logged error. + - QURT_error_info.user_errors.entry[0...counter] -- Structure for logged error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb -- TCB for the user error. + - QURT_error_info.user_errors.entry[0...counter].error_tcb.error -- Information about the error; Cause, Cause2, Badva and hardware thread ID. + - QURT_error_info.user_errors.entry[0...counter].error_code -- ((cause2 << 8) 'Logical Or' (cause) ); Cause and Cause 2 details are listed below. + - QURT_error_info.user_errors.entry[0...counter].hw_thread -- Hardware thread ID for error. + - QURT_error_info.user_errors.entry[0...counter].pcycle -- Pcycle for error. + +@note + Important usage note: + Cause and Cause2 are error codes to distinguish multiple errors. + SSR and BADAVA are inconclusive without the vector number. + All cause and cause2 can range from 1 to 255 and every cause can have 1 to 255 error code. + Hence the system can have up to 255 * 255 unique error codes. + The cominations is representated as ((cause2 << 8) 'Logical OR' (cause) ) + Some Cause2 codes are statically defined, whereas some are obtaned from SSR[7:0] cause codes. It depends on cause codes. + SSR cause codes are defined in Hexagon reference manual. + All possible combinations are listed below. +*/ +/** @addtogroup chapter_error +@{ */ +/* cause - error type - 8-bits*/ +#define QURT_EXCEPT_PRECISE 0x01U /**< Precise exception occurred. For this cause code, Cause2 is SSR[7:0].*/ +#define QURT_EXCEPT_NMI 0x02U /**< NMI occurred; Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS 0x03U /**< TLBMISS RW occurred; for this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_RSVD_VECTOR 0x04U /**< Interrupt raised on a reserved vector, which must never occur. Cause2 is not defined. */ +#define QURT_EXCEPT_ASSERT 0x05U /**< Kernel assert. Cause2 QURT_ABORT_* are listed below. */ +#define QURT_EXCEPT_BADTRAP 0x06U /**< trap0(num) called with unsupported num. Cause2 is 0. */ +#define QURT_EXCEPT_UNDEF_TRAP1 0x07U /**< Trap1 is not supported. Using Trap1 causes this error. Cause2 is not defined. */ +#define QURT_EXCEPT_EXIT 0x08U /**< Application called qurt_exit() or qurt_exception_raise_nonfatal(). Can be called from C library. Cause2 is "[Argument passed to qurt_exception_raise_nonfatal() & 0xFF]". */ +#define QURT_EXCEPT_TLBMISS_X 0x0AU /**< TLBMISS X (execution) occurred. Cause2 is not defined. */ +#define QURT_EXCEPT_STOPPED 0x0BU /**< Running thread stopped due to fatal error on other hardware thread. Cause2 is not defined. */ +#define QURT_EXCEPT_FATAL_EXIT 0x0CU /**< Application called qurt_fatal_exit(). Cause2 is not defined. */ +#define QURT_EXCEPT_INVALID_INT 0x0DU /**< Kernel received an invalid L1 interrupt. Cause2 is not defined. */ +#define QURT_EXCEPT_FLOATING_POINT 0x0EU /**< Kernel received an floating point error. Cause2 is not defined. */ +#define QURT_EXCEPT_DBG_SINGLE_STEP 0x0FU /**< Cause2 is not defined. */ +#define QURT_EXCEPT_TLBMISS_RW_ISLAND 0x10U /**< Read write miss in Island mode. Cause2 QURT_TLB_MISS_RW_MEM* are listed below. */ +#define QURT_EXCEPT_TLBMISS_X_ISLAND 0x11U /**< Execute miss in Island mode. For this cause code, Cause2 is SSR[7:0]. */ +#define QURT_EXCEPT_SYNTHETIC_FAULT 0x12U /**< Synthetic fault with user request that kernel detected. Cause2 QURT_SYNTH_* are listed below. */ +#define QURT_EXCEPT_INVALID_ISLAND_TRAP 0x13U /**< Invalid trap in Island mode. Cause2 is trap number. */ +#define QURT_EXCEPT_UNDEF_TRAP0 0x14U /**< trap0(num) was called with unsupported num. Cause2 is trap number. */ +#define QURT_EXCEPT_PRECISE_DMA_ERROR 0x28U /**< Precise DMA error. Cause2 is DM4[15:8]. Badva is DM5 register. */ + +#define QURT_ECODE_UPPER_LIBC (0U << 16) /**< Upper 16 bits is 0 for libc. */ +#define QURT_ECODE_UPPER_QURT (0U << 16) /**< Upper 16 bits is 0 for QuRT. */ +#define QURT_ECODE_UPPER_ERR_SERVICES (2U << 16) /**< Upper 16 bits is 2 for error service. */ +/** @cond */ +#define QURT_ECODE_ISLAND_INVALID_QDI 3U /**< Passing invalid QDI method in island. */ +/** @endcond */ + +/* Cause2 for QURT_EXCEPT_SYNTHETIC_FAULT cause- 8bits */ +#define QURT_SYNTH_ERR 0x01U /**< */ +#define QURT_SYNTH_INVALID_OP 0x02U /**< */ +#define QURT_SYNTH_DATA_ALIGNMENT_FAULT 0x03U /**< */ +#define QURT_SYNTH_FUTEX_INUSE 0x04U /**< */ +#define QURT_SYNTH_FUTEX_BOGUS 0x05U /**< */ +#define QURT_SYNTH_FUTEX_ISLAND 0x06U /**< */ +#define QURT_SYNTH_FUTEX_DESTROYED 0x07U /**< */ +#define QURT_SYNTH_PRIVILEGE_ERR 0x08U /**< */ + +/* Cause2 - Abort cause reason - 8 bits */ +/* ERR_ASSERT cause */ +#define QURT_ABORT_FUTEX_WAKE_MULTIPLE 0x01U /**< Abort cause - futex wake multiple. */ +#define QURT_ABORT_WAIT_WAKEUP_SINGLE_MODE 0x02U /**< Abort cause - thread waiting to wake up in Single Threaded mode. */ +#define QURT_ABORT_TCXO_SHUTDOWN_NOEXIT 0x03U /**< Abort cause - call TCXO shutdown without exit. */ +#define QURT_ABORT_FUTEX_ALLOC_QUEUE_FAIL 0x04U /**< Abort cause - futex allocation queue failure - QURTK_futexhash_lifo empty. */ +#define QURT_ABORT_INVALID_CALL_QURTK_WARM_INIT 0x05U /**< Abort cause - invalid call QURTK_warm_init() in NONE CONFIG_POWER_MGMT mode. */ +#define QURT_ABORT_THREAD_SCHEDULE_SANITY 0x06U /**< Abort cause - sanity schedule thread is not supposed to run on the current hardware thread. */ +#define QURT_ABORT_REMAP 0x07U /**< Remap in the page table; the correct behavior must remove mapping if necessary. */ +#define QURT_ABORT_NOMAP 0x08U /**< No mapping in page table when removing a user mapping. */ +#define QURT_ABORT_OUT_OF_SPACES 0x09U +#define QURT_ABORT_INVALID_MEM_MAPPING_TYPE 0x0AU /**< Invalid memory mapping type when creating qmemory. */ +#define QURT_ABORT_NOPOOL 0x0BU /**< No pool available to attach. */ +#define QURT_ABORT_LIFO_REMOVE_NON_EXIST_ITEM 0x0CU /**< Cannot allocate more futex waiting queue. */ +#define QURT_ABORT_ARG_ERROR 0x0DU +#define QURT_ABORT_ASSERT 0x0EU /**< Assert abort. */ +#define QURT_ABORT_FATAL 0x0FU /**< Fatal error; must never occur. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_QUEUE 0x10U /**< Abort cause - invalid queue ID in futex resume. */ +#define QURT_ABORT_FUTEX_WAIT_INVALID_QUEUE 0x11U /**< Abort cause - invalid queue ID in futex wait. */ +#define QURT_ABORT_FUTEX_RESUME_INVALID_FUTEX 0x12U /**< Abort cause - invalid futex object in hashtable. */ +#define QURT_ABORT_NO_ERHNDLR 0x13U /**< No registered error handler. */ +#define QURT_ABORT_ERR_REAPER 0x14U /**< Exception in the reaper thread. */ +#define QURT_ABORT_FREEZE_UNKNOWN_CAUSE 0x15U /**< Abort in thread freeze operation. */ +#define QURT_ABORT_FUTEX_WAIT_WRITE_FAILURE 0x16U /**< During futex wait processing, could not perform a necessary write operation to userland data; most likely due to a DLPager eviction. */ +#define QURT_ABORT_ERR_ISLAND_EXP_HANDLER 0x17U /**< Exception in Island exception handler task. */ +#define QURT_ABORT_L2_TAG_DATA_CHECK_FAIL 0x18U /**< Detected error in L2 tag/data during warm boot. The L2 tag/data check is done when CONFIG_DEBUG_L2_POWER_COLLAPSE is enabled. */ +#define QURT_ABORT_ERR_SECURE_PROCESS 0x19U /**< Abort error in secure process. */ +#define QURT_ABORT_ERR_EXP_HANDLER 0x20U /**< No exception handler, or the handler caused an exception. */ +#define QURT_ABORT_ERR_NO_PCB 0x21U /**< PCB of the thread context failed initialization, PCB was NULL. */ +#define QURT_ABORT_NO_PHYS_ADDR 0x22U /**< Unable to find the physical address for the virtual address. */ +#define QURT_ABORT_OUT_OF_FASTINT_CONTEXTS 0x23U /**< Fast interrupt contexts exhausted. */ +#define QURT_ABORT_CLADE_ERR 0x24U /**< Fatal error seen with CLADE interrupt. */ +#define QURT_ABORT_ETM_ERR 0x25U /**< Fatal error seen with ETM interrupt. */ +#define QURT_ABORT_ECC_DED_ASSERT 0x26U /**< ECC two-bit DED error. */ +#define QURT_ABORT_VTLB_ERR 0x27U /**< Fatal error in the VTLB layer. */ +#define QURT_ABORT_TLB_ENCODE_DECODE_FAILURE 0x28U /**< Failure during the TLB encode or decode operation. */ +#define QURT_ABORT_VTLB_WALKOBJS_BOUND_FAILURE 0x29U /**< Failure to lookup entry in the page table. */ +#define QURT_ABORT_PHY_MEMORY_OWNERSHIP_FAILURE 0x30U /**< Failure to claim phy memory ownership. */ +#define QURT_ABORT_JTLB_SIZE_CHECK_FAIL 0x31U /**< JTLB size configured is more than actual size in hardware */ +#define QURT_ABORT_AUTOSTACK_ASSERT 0x32U /**< Error while handling stack flimit exception. */ + +/* Cause2 - TLB-miss_X - 8bits */ +#define QURT_TLB_MISS_X_FETCH_PC_PAGE 0x60U /**< */ +#define QURT_TLB_MISS_X_2ND_PAGE 0x61U /**< */ +#define QURT_TLB_MISS_X_ICINVA 0x62U /**< */ + +/* Cause2 - TLB-miss_RW - 8bits */ +#define QURT_TLB_MISS_RW_MEM_READ 0x70U /**< */ +#define QURT_TLB_MISS_RW_MEM_WRITE 0x71U /**< */ + +/** @cond rest_reg_dist */ +/* Cause2 - Floating point exception - 8 bits */ +#define QURT_FLOATING_POINT_EXEC_ERR 0xBFU /**< Execute floating-point. */ +/** @endcond */ + +/** Cause2 - autostackv2 - 8 bits */ +#define QURT_AUTOSTACKV2_CANARY_NOT_MATCH 0xC1U +#define QURT_AUTOSTACKV2_POOL_IDX_OFF_RANGE 0xC2U + +/** Cause2 - CFI violation - 8 bits */ +#define QURT_CFI_VIOLATION 0xC3U + +/** @cond rest_reg_dist*/ +/* Enable floating point exceptions */ +#define QURT_FP_EXCEPTION_ALL 0x1FU << 25 /**< */ +#define QURT_FP_EXCEPTION_INEXACT 0x1U << 29 /**< */ +#define QURT_FP_EXCEPTION_UNDERFLOW 0x1U << 28 /**< */ +#define QURT_FP_EXCEPTION_OVERFLOW 0x1U << 27 /**< */ +#define QURT_FP_EXCEPTION_DIVIDE0 0x1U << 26 /**< */ +#define QURT_FP_EXCEPTION_INVALID 0x1U << 25 /**< */ + +/** @endcond */ +/** @} */ /* end_addtogroup chapter_error */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_EXCEPT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fastint.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fastint.h new file mode 100755 index 0000000000000..ea65dc0917fc0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fastint.h @@ -0,0 +1,71 @@ +#ifndef QURT_FASTINT_H +#define QURT_FASTINT_H + +/** + @file qurt_fastint.h + @brief QuRT fast interrupt functions + + Copyright (c) 2013-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + + ======================================================================*/ + +/*======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_fastint_register + Register fast interrupt callback function + + Fast interrupt callback should be designed to perform the minimal necessary + actions for the interrupt, and/or perform some operations, such as signaling + another regular software thread to start any additional processing. + The callback should be a fast and short function. When a fast interrupt callback + is running, the corresponding interrupt cannot be re-enabled until the callback + returns. + + The fast interrupt callback must not use any system blocking calls, such as + mutex lock or signal wait. Otherwise, it results in errors. + + The fast interrupt callback function has a single integer argument and the + function ends with no return. The argument value passed in is the interrupt + number, and therefore a single callback function can handle + multiple fast interrupts. + + @param[in] intno Interrupt number to register. + @param[in] fn Interrupt callback function. + + @return + #QURT_EOK -- Fast interrupt registration is successful. \n + #QURT_EINVALID -- Interrupt is already registered. \n + #QURT_EINT -- Invalid interrupt number. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_register(int intno, void (*fn)(int)); + + +/*======================================================================*/ +/**@ingroup func_qurt_fastint_deregister + Deregisters the fast interrupt callback function. + + @param[in] intno Level-one interrupt number to deregister. Valid range is 1 and 10 through 31 + (simulator only). + + @return + #QURT_EOK -- Interrupt deregistration is successful. \n + #QURT_EINT -- Invalid interrupt number (not registered). \n + #QURT_EINVALID -- Invalid interrupt number (already deregistered). + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_fastint_deregister(int intno); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FASTINT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fs_hub.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fs_hub.h new file mode 100755 index 0000000000000..aaa050a6c838b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_fs_hub.h @@ -0,0 +1,58 @@ +#ifndef QURT_FS_HUB_H +#define QURT_FS_HUB_H + +/** + @file qurt_fs_hub.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver that provides file-system functionality. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + This structure tracks a file-designator for a FS-hub QDI driver. + File system's QDI interface should use this object to encapsulate + true file-descriptor and return back a QDI handle. This QDI handle + will be used as file-descriptor by File-systm-hub. + */ + +typedef struct qurt_qdi_fs_obj +{ + qurt_qdi_obj_t qdi_obj; + int client_handle; + int fd; +}qurt_qdi_fs_obj_t; + + +/**@ingroup fs_hub_support_functions + This function allows a file-system to register it's QDI interface with file-system-hub. + Once registered, all file open operations for any filenames containing the mountpoint will + be forwarded to the QDI inteface. + + Mountpoint string must be encased in two forward slashes e.g. "/mountpoint/" + + @param mtpoint mount point for the file-system being registered. + @param opener opener structure for the QDI driver interface + + @return + QURT_EOK -- Successfully registered QDI driver with file-system-hub. + Negative error code -- Failed to register with file-system-hub + */ +int qurt_fs_hub_mtpoint_register(const char *mtpoint, qurt_qdi_obj_t *opener); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_futex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_futex.h new file mode 100755 index 0000000000000..1fdcc79a43f01 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_futex.h @@ -0,0 +1,82 @@ +#ifndef QURT_FUTEX_H +#define QURT_FUTEX_H +/** + @file qurt_futex.h + + @brief Prototypes of QuRT futex API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2020-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Functions +======================================================================*/ + + +/**@ingroup func_qurt_futex_wait + Moves the caller thread into waiting state when a memory object address + contains a value that is the same as a specified value. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait(void *lock, int val); + + +/**@ingroup func_qurt_futex_wait_cancellable + If a memory object address contains a value that is same as a specified + value, move the caller thread into waiting state. + The kernal can cancel the waiting state when there is a special need. + + @param[in] lock Pointer to the object memory. + @param[in] val Value to check against the object content. + + @return + #QURT_EOK -- Success \n + Other values -- Failure + + @dependencies + None. + */ +int qurt_futex_wait_cancellable(void *lock, int val); + + +/**@ingroup func_qurt_futex_wake + Wakes up a specified number of threads that have been waiting + for the object change with qurt_futex_wait(). + + @param[in] lock Pointer to the object memory. + @param[in] n_to_wake Maximum number of threads to wake up. + + @return + number of threads to be woken up by this function + + @dependencies + None. + */ +int qurt_futex_wake(void *lock, int n_to_wake); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_FUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hmx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hmx.h new file mode 100755 index 0000000000000..e4037dbeae514 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hmx.h @@ -0,0 +1,226 @@ +#ifndef QURT_HMX_H +#define QURT_HMX_H +/** + @file qurt_hmx.h + @brief Prototypes of Qurt HMX API. + +Copyright (c) 2019-2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + + +/** @addtogroup hmx_types +@{ */ +/* HMX locking type */ +#define QURT_HMX_NON_SHARED_LOCK 0U /**< HMX locking type.*/ +#define QURT_HMX_SHARED_LOCK 1U /**< HMX locking type.*/ + +/* HMX unlocking type */ +#define QURT_HMX_NON_SHARED_UNLOCK 0U /**< HMX unlocking type.*/ +#define QURT_HMX_SHARED_UNLOCK 1U /**< HMX unlocking type.*/ + +/* HMX hardware context */ +#define QURT_HMX_UNIT_0 0U /**< HMX hardware context #0 */ +#define QURT_HMX_UNIT_1 1U /**< HMX hardware context #1 */ + /** @} */ /* end_addtogroup hmx_types */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_hmx_lock2 + Locks a HMX unit with the specified locking type. + + #QURT_HMX_NON_SHARED_LOCK: + - If a HMX unit is available, lock the unit and return success of #QURT_EOK. + - If the HMX unit is already locked by another thread, the caller thread is suspended + until the HMX is available and gets locked by this function. + - If there is no HMX hardware supported, returns #QURT_EVAL; + + #QURT_HMX_SHARED_LOCK: + - If a HMX unit is available, enables HMX access for the caller thread, and returns + success of #QURT_EOK. + - If the HMX is enabled on the caller thread, return #QURT_EFAILED. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_SHARED_LOCK, enable HMX access for the caller + thread, and return success of #QURT_EOK. + - If the HMX is locked by another thread in the same user process of the caller + thread with locking type of #QURT_HMX_NON_SHARED_LOCK, return #QURT_EFAILED. + - If the HMX is locked by a thread from another user process different from the + user process of the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX lock successful.\n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_lock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_unlock2 + Unlocks a HMX unit with the unlocking type. + + #QURT_HMX_NON_SHARED_UNLOCK: + - If there is a HMX unit locked by the caller thread, unlock the HMX unit and clear the + HMX accumulators (assuming a fixed point type). + - If there is no HMX unit locked by the caller thread, return #QURT_EFAILED. + - If there is no HMX hardware supported, return #QURT_EVAL. + + #QURT_HMX_SHARED_UNLOCK: + - If the caller thread has locked HMX with type #QURT_HMX_SHARED_LOCK, disable the + HMX access on the caller thread, and return success of #QURT_EOK. + Note: If the caller thread is the last thread that unlocks for #QURT_HMX_SHARED_LOCK + in its user process, the unlock function clears the HMX accumulators. + - If the caller thread has locked HMX with type #QURT_HMX_NON_SHARED_LOCK, return + failure of #QURT_EFAILED. + - If the caller thread has not locked HMX, return failure of #QURT_EFAILED. + - If there is no HMX hardware supported, returns #QURT_EVAL. + + @param[in] type Locking type. + + @return + #QURT_EOK -- HMX is unlocked successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + + */ +int qurt_hmx_unlock2(unsigned int type); + + +/**@ingroup func_qurt_hmx_lock + Locks a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away. + If there is no HMX unit available, the caller is blocked until a HMX is available + and is locked by the function. + + @return + #QURT_EOK -- HMX lock successful. \n + #QURT_EFAILED -- Failure due to wrong locking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_lock(void); + + +/**@ingroup func_qurt_hmx_unlock + Unlocks a HMX unit. + If a HMX unit is locked by the caller thread, unlock the HMX unit and clear its + accumulators(assuming fixed point type). + If there is no HMX unit locked by the caller thread, return failure. + + @return + #QURT_EOK -- HMX unlock successful. \n + #QURT_EFAILED -- Failure due to wrong unlocking condition. \n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_unlock(void); + + +/**@ingroup func_qurt_hmx_try_lock + Tries to lock a HMX unit. + If a HMX unit is available, this function locks the unit and returns right away; + if there is no HMX unit available, the function returns failure without blocking the caller. + + @return + #QURT_EOK -- HMX lock successful \n + #QURT_EFAILED -- Failure due to wrong locking condition.\n + #QURT_EVAL -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_try_lock(void); + + +/**@ingroup func_qurt_hmx_assign + Assign a HMX unit to a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + If the requested hmx_unit is already assigned to another thread with QURT_HMX_NON_SHARED_LOCK, + kernel will detach it from the thread, and re-assign it to the target thread. + If the target thread has HVX enabled, it cannot have HMX enabled. + + Locking type + #QURT_HMX_NON_SHARED_LOCK: + - If the HMX unit is available, lock the HMX unit and return success of #QURT_EOK. + - If the HMX unit is already enabled on the target thread, return #QURT_EOK. + - If the HMX unit is already locked by another thread, detach the HMX from the thread. + Re-assign the HMX unit to the target thread, and return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] type Locking type + #QURT_HMX_NON_SHARED_LOCK -- non-shared lock + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is assigned successfully. This includes the case that \n + the target thread already has HMX assigned. \n + #QURT_EFAILED -- Failure due to wrong assigning conditions. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_assign ( unsigned int thread_id, unsigned int type, unsigned int hmx_unit ); + + +/**@ingroup func_qurt_hmx_release + Release a HMX unit from a target thread specified by its thread identifier. + The HMX unit (HMX hardware context) is specified by hmx_unit. + The caller of this function is limited to the SRM process. + + Qurt detaches the specified HMX unit from the target thread, and return success of + #QURT_EOK. If the HMX unit is already released from the target thread, return #QURT_EOK. + + @param[in] thread_id Thread identifier + @param[in] hmx_unit HMX hardware context number + #QURT_HMX_UNIT_0 + #QURT_HMX_UNIT_1 + + @return + #QURT_EOK -- The HMX is released successfully. This includes the case that \n + the target thread already has the HMX released. \n + #QURT_EFAILED -- Failure due to wrong assigning condition. \n + #QURT_EINVALID -- Failure because no HMX hardware is supported. + + @dependencies + None. + */ +int qurt_hmx_release ( unsigned int thread_id, unsigned int hmx_unit ); + + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HMX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hvx.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hvx.h new file mode 100755 index 0000000000000..13c213d49ac84 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_hvx.h @@ -0,0 +1,421 @@ +#ifndef QURT_HVX_H +#define QURT_HVX_H +/** + @file qurt_hvx.h + @brief Prototypes of QuRT HVX API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @cond */ + +typedef enum { + QURT_HVX_MODE_64B = 0, /**< HVX mode of 64 bytes */ + QURT_HVX_MODE_128B = 1 /**< HVX mode of 128 bytes */ +} qurt_hvx_mode_t; +/** @endcond */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @cond internal_only*/ +/** @addtogroup hvx_macros +@{ */ +#define QURT_HVX_HW_UNITS_2X128B_4X64B 0x00000204 /**< Bits 15 through 8 are for the number of 128B units. */ + /**< Bits 7 through 0 are for the number of 64B units. */ +#define QURT_HVX_HW_UNITS_4X128B_0X64B 0x00000400 +#define QURT_HVX_HW_UNITS_6X128B_0X64B 0x00000600 + +/* HVX locking status */ + +#define QURT_HVX_UNLOCKED (0) /* Has not locked HVX unit */ +#define QURT_HVX_LOCKED (1) /* Has locked HVX unit */ +#define QURT_HVX_ERROR (-1) /* Error, no HVX support */ + +/* Input value for HVX reservation */ + +#define QURT_HVX_RESERVE_ALL (4) /* All the HVX units in terms of 64B_MODE are requested to be reserved */ +#define QURT_HVX_RESERVE_ALL_AVAILABLE (0xff) /* All remaining unlocked HVX units in terms of 64B_MODE are requested to be reserved */ + +/* Return values for HVX reservation */ + +#define QURT_HVX_RESERVE_NOT_SUPPORTED (-1) /* There is no HVX hardware, or less units in the hardware than requested */ +#define QURT_HVX_RESERVE_NOT_SUCCESSFUL (-2) /* Some HVX units are already locked/reserved by other PD, thus not enough units left for the reservation. */ +#define QURT_HVX_RESERVE_ALREADY_MADE (-3) /* There is already a HVX reservation made. */ +#define QURT_HVX_RESERVE_CANCEL_ERR (-4) /* The action of cancling the reservation fails because this protection domain has no reservation made before. */ + +// HVX set requests + +#define QURT_HVX_64B 0 /**< */ +#define QURT_HVX_128B 1 /**< */ +#define QURT_HVX_NO_USE 2 /**< */ +#define QURT_HVX_RELEASE_CONTEXT 3 /**< */ +#define QURT_HVX_IMMEDIATE_USE 4 /**< */ + +// HVX set masks + +#define QURT_HVX_64B_PREFERRED (1<<(QURT_HVX_64B + 8))/**< */ +#define QURT_HVX_128B_PREFERRED (1<<(QURT_HVX_128B + 8))/**< */ +#define QURT_HVX_64B_ACCEPTABLE (1<<(QURT_HVX_64B + 12))/**< */ +#define QURT_HVX_128B_ACCEPTABLE (1<<(QURT_HVX_128B + 12))/**< */ + +// HVX set return "result" + +#define QURT_EOK 0 /**< */ +#define QURT_HVX_SET_ERROR 0xFF /**< */ + +// hvx_mode_assigned for QURT_HVX_IMMEDIATE_USE +#define QURT_HVX_64B_ASSIGNED (1<<(QURT_HVX_64B + 8)) /**< */ +#define QURT_HVX_128B_ASSIGNED (1<<(QURT_HVX_128B + 8)) /**< */ + +// Sizes of HVX dump buffer + +#define QURT_HVX_V65_64B_VSIZE 2084U /**< 64 x 32 + 8 x 4 + 4 (version). */ +#define QURT_HVX_V65_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V66_128B_VSIZE 4420U /**< 128 x (32 +2) + 16 x 4 + 4 (version). */ +#define QURT_HVX_V68_128B_VSIZE 4164U /**< 128 x 32 + 16 x 4 + 4 (version). */ +#define QURT_HVX_V79_128B_VSIZE 4740U /**< 128 x (32+4+1) + 4 (version). */ +#define QURT_HVX_VREG_BUF_SIZE QURT_HVX_V79_128B_VSIZE /**< */ + +// HVX dump versions + +#define QURT_HVX_DUMP_V65_64B 1U /**< */ +#define QURT_HVX_DUMP_V65_128B 2U /**< */ +#define QURT_HVX_DUMP_V66_128B 3U /**< */ +#define QURT_HVX_DUMP_V68_128B 4U /**< */ +#define QURT_HVX_DUMP_V79_128B 5U /**< */ +/** @} */ /* end_addtogroup hvx_macros */ +/** @endcond */ +/** @cond */ +// Qurt data struct for hvx_set input +typedef struct qurt_hvx_set_struct_ { + unsigned char set_req; // LSB + struct { + unsigned char preferred_mask:4; + unsigned char acceptable_mask:4; + }; + unsigned short resvd; // MSB +} qurt_hvx_set_struct_t; // 4 bytes + + +// Qurt data struct for hvx_set return +typedef struct qurt_hvx_set_return_str_ { + unsigned char result; // LSB + unsigned char hvx_mode_assigned; + unsigned short resvd; // MSB +} qurt_hvx_set_return_struct_t; // 4 bytes +/** @endcond */ + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_hvx_lock + Locks one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns right away. + If the current HVX mode is different from the requested mode, the current + thread is blocked. When all HVX units become idle, QuRT changes + the mode, locks the HVX unit, and returns. + + Starting from Q6v65 with HVX context switch support, qurt_hvx_lock() is + mapped as qurt_hvx_set(64_BYTE or 128_BYTE). + + @datatypes + #qurt_mode_t + + @param[in] lock_mode #QURT_HVX_MODE_64B or #QURT_HVX_MODE_128B. + + @return + #QURT_EOK -- Success \n + Other value -- Failure + + @dependencies + None. + + */ +int qurt_hvx_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_unlock + Unlocks the HVX unit held by this software thread. + + @note1hang Starting from Q6v65 with HVX context switch support, qurt_hvx_unlock() + maps as qurt_hvx_set(QURT_HVX_RELEASE_CONTEXT). + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_unlock(void); + +/**@ingroup func_qurt_hvx_try_lock + Tries to lock one HVX unit specified by the HVX mode. + + @note1hang Input variable can be 128B_MODE or 64B_MODE. If an HVX unit in this mode + is available, this function locks the unit and returns #QURT_EOK; Otherwise, + the function returns a failure, but does not block the current software + thread to wait for the HVX unit. + Starting from Q6v65 with HVX context switch support, qurt_hvx_try_lock() + maps to qurt_hvx_set(FOR_IMMEDIATE_USE| preferred_mask | acceptable_mask); + + @datatypes + #qurt_mode_t + + @return + #QURT_EOK -- Successful return \n + Other values -- Failure + + @dependencies + None. + + */ +int qurt_hvx_try_lock(qurt_hvx_mode_t lock_mode); + +/**@ingroup func_qurt_hvx_get_mode + Gets the current HVX mode configured by QuRT. + + @note1hang Returns #QURT_HVX_MODE_128B or #QURT_HVX_MODE_64B, based on + the current HVX configuration. + + @param[out] + None. + + @return + #QURT_HVX_MODE_128B \n + #QURT_HVX_MODE_64B \n + -1 -- Not available. + + @dependencies + None. + */ +int qurt_hvx_get_mode(void); + + +/**@ingroup func_qurt_hvx_get_units + Gets the HVX hardware configuration that the chipset supports. + + @note1hang The function returns the HVX hardware configuration supported by the chipset. + + @return + Bitmask of the units: 1X64, 2X64, 4X64, 1X128, 2X128, and so on.\n + - QURT_HVX_HW_UNITS_2X126B_4X64B -- V60, V62, or V65 HVX \n + - QURT_HVX_HW_UNITS_4X128B_0X64B -- V66 CDSP or newer \n + - 0 -- not available + + @dependencies + None. + + */ +int qurt_hvx_get_units(void); + + +/**@ingroup func_qurt_hvx_reserve + Reserves HVX units in terms of 64-byte mode for the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + If one HVX unit is already locked by the application in the same PD, the unit is + added to the returned count as one reserved unit for the PD. + Starting from Q6v65 with HVX context switch support, qurt_hvx_reserve() + only does basic sanity checks on HVX units. + + @datatypes + None. + + @param[in] num_units Number of HVX units in terms of 64B_MODE to reserve for the PD. + QURT_HVX_RESERVE_ALL to reserve all the HVX units. + QURT_HVX_RESERVE_ALL_AVAILABLE to reserve the remaining unlocked units. + + @return + Number of units successfully reserved, including the units already locked in the same PD. \n + #QURT_HVX_RESERVE_NOT_SUPPORTED \n + #QURT_HVX_RESERVE_NOT_SUCCESSFUL \n + #QURT_HVX_RESERVE_ALREADY_MADE + + + @dependencies + None. + + */ +int qurt_hvx_reserve(int num_units); + + +/**@ingroup func_qurt_hvx_cancel_reserve + Cancels the HVX reservation in the protection domain (PD) of the caller. + + @note1hang Only one HVX reservation in the system is supported. + + @return + 0 -- Success \n + #QURT_HVX_RESERVE_CANCEL_ERR -- Failure + + @dependencies + None. + + */ +int qurt_hvx_cancel_reserve(void); + + +/**@ingroup func_qurt_hvx_get_lock_val + Gets the HVX locking status value of the thread of the caller. + + @note1hang Returns the status of whether the thread of the caller already locks a HVX unit or not. + + @datatypes + None. + + @return + #QURT_HVX_UNLOCKED \n + #QURT_HVX_LOCKED \n + #QURT_HVX_ERROR + + @dependencies + None. + */ +int qurt_hvx_get_lock_val(void); + +/** @cond internal_only*/ +/**@ingroup func_qurt_hvx_set + Sets the HVX configuration for the software thread of the caller. + + @datatypes + None. + + @param[in] input_arg Composed of set_request | hvx_preferred_mode_mask + | hvx_acceptable_mode_mask where set_request can be set to: \n + - #QURT_HVX_64B \n + - #QURT_HVX_128B \n + - #QURT_HVX_NO_USE \n + - #QURT_HVX_RELEASE_CONTEXT \n + - #QURT_HVX_IMMEDIATE_USE \n + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_preferred_mode_mask can be set to: \n + - #QURT_HVX_64B_PREFERRED \n + - #QURT_HVX_128B_PREFERRED + When set_request is QURT_HVX_IMMEDIATE_USE, + hvx_acceptable_mode_mask can be set to: \n + - #QURT_HVX_64B_ACCEPTABLE \n + - #QURT_HVX_128B_ACCEPTABLE @tablebulletend + + @return + Result of the HVX setting in the least significant 8 bits of the returned data. \n + #QURT_EOK -- 0 \n + #QURT_HVX_SET_ERROR -- 0xFF \n + When #QURT_HVX_IMMEDIATE_USE has a result of #QURT_EOK, + bit 8 to bit 15 of the returned data contain hvx_mode_assigned:\n + - #QURT_HVX_64B_ASSIGNED \n + - #QURT_HVX_128B_ASSIGNED + + @dependencies + None. + */ +unsigned int qurt_hvx_set(unsigned int input_arg); + + +/**@ingroup func_qurt_system_hvx_regs_get_maxsize + Returns the maximum buffer size for saving HVX registers. + + @datatypes + None. + + @return + 0 -- No HVX supported in the target. \n + #QURT_HVX_VREG_BUF_SIZE -- Maximum buffer size for saving HVX registers. + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get_maxsize(void); + + +/**@ingroup func_qurt_system_hvx_regs_get_size + Returns the buffer size for saving HVX registers for a specified thread. + + @param[in] thread_id Thread ID of the target thread. + + @return + 0 -- No HVX assgined to the thread. \n + size -- Size of the buffer in bytes for saving HVX registers for the specified thread: \n + - #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + - #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + - #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + - #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + + @dependencies + None. + + */ +unsigned int qurt_system_hvx_regs_get_size(unsigned int thread_id); + + + +/**@ingroup func_qurt_system_hvx_regs_get + Saves the HVX registers into the specified buffer. + Returns the size of the data saved into the buffer. + After calling this function for the first time on a specified thread_id, the QuRT kernel removes the internal HVX saving buffer + from the specified thread. When calling the function on the same thread_id for the second time, this function returns 0. + + @param[in] thread_id Thread ID of the target thread. + @param[in] pBuf Pointer to the buffer for HVX register saving. + The first four bytes of the buffer are for saving the HVX version. HVX registers are saved from + the fifth byte of the buffer. The address of the fifth byte should be 256 bytes aligned. + For example, a buffer can be declared at first as: \n + unsigned char vbuf[QURT_HVX_VREG_BUF_SIZE+256];\n + unsigned char *pBuf; \n + then align the buffer pointer to: \n + pBuf = vbuf; \n + pBuf += (256 - 4 - (unsigned)pBuf%256); + @param[in] size Size of the buffer provided, which is pointed by *pBuf. The buffer size should not be smaller than that + returned from qurt_system_hvx_regs_get_size(), and pBuf should be aligned as described above. + @param[out] pBuf Buffer returned with the saved HVx registers (unsigned char hvx_regs[];), which are saved from the fith + byte of the buffer, and the HVX version (unsigned int hvx_version;), which in the first four bytes + contain one of the HVX dump versions:\n + - #QURT_HVX_DUMP_V65_64B \n + - #QURT_HVX_DUMP_V65_128B \n + - #QURT_HVX_DUMP_V66_128B \n + - #QURT_HVX_DUMP_V68_128B \n + - #QURT_HVX_DUMP_V79_128B \n + @tablebulletend + + @return + Total bytes of the data saved in the provided buffer. \n + 0 -- No HVX assigned to the thread \n + #QURT_HVX_V65_64B_VSIZE -- 64 x 32 + 8 x 4 + 4 (version) \n + #QURT_HVX_V65_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V66_128B_VSIZE -- 128 x (32 +2) + 16 x 4 + 4 (version) \n + #QURT_HVX_V68_128B_VSIZE -- 128 x 32 + 16 x 4 + 4 (version) \n + #QURT_HVX_V79_128B_VSIZE -- 128 x (32+4+1) + 4 (version) + + @dependencies + None. + */ +unsigned int qurt_system_hvx_regs_get(unsigned int thread_id, void *pBuf, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_HVX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_int.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_int.h new file mode 100755 index 0000000000000..386aeda1051eb --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_int.h @@ -0,0 +1,509 @@ +#ifndef QURT_INT_H +#define QURT_INT_H +/** + @file qurt_int.h + @brief QuRT interrupt functions. + + + + Copyright (c) 2013-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/** @cond rest_reg_dist */ +/** @addtogroup interrupts_constants +@{ */ +#define SIG_INT_ABORT 0x80000000 /**< */ +#define QURT_INT_NON_DELAYED_ACK 0 +#define QURT_INT_DELAYED_ACK 1 +#define QURT_INT_ACK_DEFAULT QURT_INT_NON_DELAYED_ACK +#define QURT_INT_DRV_DEFAULT 0 +#define QURT_INT_PRIORITY_DEFAULT 0xFF + +/** QuRT interrupt property. */ +#define QURT_INT_CONFIGID_POLARITY 0x1U /**< */ +#define QURT_INT_CONFIGID_LOCK 0x2U /**< */ + +/** QuRT interrupt lock.*/ +#define QURT_INT_LOCK_DEFAULT 0x0 /**< Default. */ +#define QURT_INT_LOCK_DISABLE 0x0 /**< Interrupt can be enabled or disabled or deregistered. */ +#define QURT_INT_LOCK_ENABLE 0x1 /**< Interrupt is locked and cannot be enabled, disabled, or deregistered.*/ +/** @} */ /* end_addtogroup interrupts_constants */ + +/** @addtogroup Qurt_interrupt_type +@{ */ +/** Trigger type bit fields for a PDC interrupt:\n + @verbatim + Polarity Edge Output\n + 0 00 Level sensitive active low + 0 01 Rising edge sensitive + 0 10 Falling edge sensitive + 0 11 Dual edge sensitive + 1 00 Level sensitive active high + 1 01 Falling edge sensitive + 1 10 Rising edge sensitive + 1 11 Dual edge sensitive + @endverbatim +*/ +#define QURT_INT_TRIGGER_TYPE_SET(pol, edge) ((((pol) & 0x01U) << 2) | ((edge) & 0x03U)) /**< */ + +#define QURT_INT_TRIGGER_LEVEL_LOW QURT_INT_TRIGGER_TYPE_SET(0U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_LEVEL_HIGH QURT_INT_TRIGGER_TYPE_SET(1U, 0x00U) /**< */ +#define QURT_INT_TRIGGER_RISING_EDGE QURT_INT_TRIGGER_TYPE_SET(1U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_FALLING_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x02U) /**< */ +#define QURT_INT_TRIGGER_DUAL_EDGE QURT_INT_TRIGGER_TYPE_SET(0U, 0x03U) /**< */ +#define QURT_INT_TRIGGER_USE_DEFAULT 0xffU /**< */ +/** @} */ /* end_addtogroup Qurt_interrupt_type */ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_interrupt_register + @xreflabel{sec:interrupt_register} + Registers the interrupt.\n + Enables the specified interrupt and associates it with the specified QuRT signal object and + signal mask. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register(int int_num, qurt_anysignal_t *int_signal, int signal_mask); + +/**@ingroup func_qurt_interrupt_register2 + @xreflabel{sec:interrupt_register2} + Registers the interrupt.\n + Enables the specified interrupt, associates it with the specified QuRT signal object and + signal mask, and sets interrupt flags. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be waited on, and 0 indicates not to wait. + + When the interrupt occurs, the signal specified in the signal mask is set in the signal + object. An IST conventionally waits on that signal to + handle the interrupt. The thread that registers the interrupt is set as the IST. + + Up to 31 separate interrupts can be registered to a single signal object, as determined by + the number of individual signals that the object can store. QuRT reserves signal 31. Thus a + single IST can handle several different interrupts. + + QuRT reserves some interrupts for internal use -- the remainder are available for use by + applications, and thus are valid interrupt numbers. If the specified interrupt number is + outside the valid range, the register operation returns the status value #QURT_EINT. + + Only one thread can be registered at a time to a specific interrupt. Attempting to register + an already-registered interrupt returns the status value #QURT_EVAL. + + Only one signal bit in a signal object can be registered at a time to a specific interrupt. + Attempting to register multiple signal bits to an interrupt returns the status value + #QURT_ESIG. + + When the signal registers an interrupt, QuRT can only set its signal bits + when receiving the interrupt. The QuRT signal API from another + software thread cannot set the signal even for unused signal bits. + + @note1hang The valid range for an interrupt number can differ on target execution + environments other than the simulator. For more information, see the + appropriate hardware document. + + @datatypes + #qurt_anysignal_t + + @param[in] int_num L2VIC interrupt to deregister; valid range is 0 to 1023. + @param[in] int_signal Any-signal object to wait on (Section @xref{dox:any_signals}). + @param[in] signal_mask Signal mask value indicating signal to receive the interrupt. + @param[in] flags Defines interrupt property, supported property is interrupt lock enable/disable. + Possible values for flags: \n + - #QURT_INT_LOCK_ENABLE + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Interrupt successfully registered.\n + #QURT_EINT -- Invalid interrupt number. \n + #QURT_ESIG -- Invalid signal bitmask (cannot set more than one + signal at a time). \n + #QURT_EVAL -- Interrupt already registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_register2(int int_num, qurt_anysignal_t *int_signal, int signal_mask, unsigned int flags); +/* + * Waits for registered interrupt signal + + * Suspend the current thread until one of its registered interrupts occurs. The second input mask, + * contains the interrupt signals the IST expects to receive. The interrupt signals are registered + * with interrupts via qurt_register_interrupt API. + * + * The signals returned in the signal variable indicate which interrupts occurred. Use function + * qurt_anysignal_get to read the signals. IST must locally maintain a table that maps a signal to + * a specific interrupt. IST also checks if signal #SIG_INT_ABORT is received. If so, the IST + * must quit from interrupt receiving loop. + * + * For detail information on this API, see QuRT User Manual Section 4.2.5 + * + * Prototype + * + * unsigned int qurt_anysignal_wait(qurt_anysignal_t *int_signal, unsigned int mask) + */ + +/**@ingroup func_qurt_interrupt_acknowledge + Acknowledges an interrupt after it has been processed.\n + Re-enables an interrupt and clears its pending status. This is done after an interrupt is + processed by an IST. + + Interrupts are automatically disabled after they occur. To re-enable an interrupt, an IST + performs the acknowledge operation after it has finished processing the interrupt and + just before suspending itself (such as by waiting on the interrupt signal). + + @note1hang To prevent losing or reprocessing subsequent occurrences of the interrupt, + an IST must clear the interrupt signal (Section @xref{sec:anysignal_clear}) before + acknowledging the interrupt. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Interrupt acknowledge was successful. \n + #QURT_EDEREGISTERED -- Interrupt is already de-registered. + + @dependencies + None. +*/ +int qurt_interrupt_acknowledge(int int_num); + +/**@ingroup func_qurt_interrupt_deregister + Disables the specified interrupt and disassociates it from a QuRT signal object. + If the specified interrupt was never registered (Section @xref{sec:interrupt_register}), the deregister operation + returns the status value #QURT_EINT. + + @note1hang If an interrupt is deregistered while an IST waits + to receive it, the IST might wait indefinitely for the interrupt to occur. To avoid + this problem, the QuRT kernel sends the signal #SIG_INT_ABORT to awaken an + IST after determining that it has no interrupts registered. + + @param[in] int_num L2VIC to deregister; valid range is 0 to 1023. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number (not registered). + + @dependencies + None. + +*/ +unsigned int qurt_interrupt_deregister(int int_num); +/** @endcond */ + +/**@ingroup func_qurt_interrupt_disable + Disables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + After qurt_interrupt_disable() returns, the Hexagon subsystem + can no longer send the corresponding interrupt to the Hexagon + core, until qurt_interrupt_enable() is called + for the same interrupt. + + Avoid calling qurt_interrupt_disable() and qurt_interrupt_enable() frequently within + a short period of time.\n + - A pending interrupt can already be in the Hexagon core when qurt_interrupt_disable() + is called. Therefore, some time later, the pending interrupt is received on a Hexagon + hardware thread.\n + - After the Hexagon subsystem sends an interrupt to the Hexagon core, the Hexagon + hardware automatically disables the interrupt until kernel software re-enables the interrupt + at the interrupt acknowledgement stage. If qurt_interrupt_enable() is called from a certain + thread at an ealier time, the interrupt is re-enabled earlier and can trigger + sending a new interrupt to the Hexagon core while kernel software is still processing + the previous interrupt. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully disabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. +*/ + unsigned int qurt_interrupt_disable(int int_num); + + +/**@ingroup func_qurt_interrupt_enable + Enables an interrupt with its interrupt number.\n + The interrupt must be registered prior to calling this function. + + @param[in] int_num Interrupt number. + + @return + #QURT_EOK -- Interrupt successfully enabled.\n + #QURT_EINT -- Invalid interrupt number.\n + #QURT_ENOTALLOWED -- Interrupt is locked. \n + #QURT_EVAL -- Interrupt is not registered. + + @dependencies + None. + +*/ + unsigned int qurt_interrupt_enable(int int_num); + + +/**@ingroup func_qurt_interrupt_status + Returns a value that indicates the pending status of the specified interrupt. + + @param[in] int_num Interrupt number that is being checked. + @param[out] status Interrupt status; 1 indicates that an interrupt is + pending, 0 indicates that an interrupt is not pending. + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_status(int int_num, int *status); + + +/**@ingroup func_qurt_interrupt_get_status + Gets the status of the specified interrupt in L2VIC. + + @param[in] int_num Interrupt number that is being checked. + @param[in] status_type 0 -- interrupt pending status \n + 1 -- interrupt enabling status + @param[out] status 0 -- OFF \n + 1 -- ON + + @return + #QURT_EOK -- Success. \n + #QURT_EINT -- Failure; invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_status(int int_num, int status_type, int *status); + +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_interrupt_clear + Clears the pending status of the specified interrupt. + + @note1hang This operation is intended for system-level use, and must be used with care. + + @param[in] int_num Interrupt that is being re-enabled. + + @return + #QURT_EOK -- Success.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_clear(int int_num); + + +/**@ingroup func_qurt_interrupt_get_config + Gets the L2VIC interrupt configuration. \n + This function returns the type and polarity of the specified L2VIC interrupt. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[out] int_type Pointer to an interrupt type. \n + 0 -- Level-triggered interrupt \n + 1 -- Eedge-triggered interrupt + @param[out] int_polarity Pointer to interrupt polarity.\n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt. + + @return + #QURT_EOK -- Configuration successfully returned.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_get_config(unsigned int int_num, unsigned int *int_type, unsigned int *int_polarity); + +/**@ingroup func_qurt_interrupt_set_config + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang Deregister L2VIC interrupts before reconfiguring them. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Interrupt type. \n + 0 -- Level-triggered interrupt\n + 1 -- Edge-triggered interrupt + @param[in] int_polarity Interrupt polarity. \n + 0 -- Active-high interrupt \n + 1 -- Active-low interrupt + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config(unsigned int int_num, unsigned int int_type, unsigned int int_polarity); + +/**@ingroup func_qurt_interrupt_set_config2 + Sets the type and polarity of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured. + + @param[in] int_num L2VIC interrupt that is being re-enabled. + @param[in] int_type Notified to the hardware configuration callback function and used to + modify the L2VIC type. Possible values: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. + */ +unsigned int qurt_interrupt_set_config2(unsigned int int_num, unsigned int int_type); + +/**@ingroup func_ qurt_interrupt_set_config3 + Sets the specified configuration value for the specified property of the specified L2VIC interrupt. + + @note1hang L2VIC interrupts must be deregistered before they can be reconfigured for polarity. + + @param[in] int_num L2VIC interrupt to re-enable. + @param[in] config_id Property to configure: \n + - #QURT_INT_CONFIGID_POLARITY \n + - #QURT_INT_CONFIGID_LOCK @tablebulletend + @param[in] config_val Dependent on the second argument config_id, specifies the value to set. \n + Values for #QURT_INT_CONFIGID_POLARITY: \n + - #QURT_INT_TRIGGER_USE_DEFAULT \n + - #QURT_INT_TRIGGER_LEVEL_HIGH \n + - #QURT_INT_TRIGGER_LEVEL_LOW \n + - #QURT_INT_TRIGGER_RISING_EDGE \n + - #QURT_INT_TRIGGER_FALLING_EDGE \n + - #QURT_INT_TRIGGER_DUAL_EDGE \n + + Values for #QURT_INT_CONFIGID_LOCK: \n + - #QURT_INT_LOCK_ENABLE\n + - #QURT_INT_LOCK_DISABLE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_ENOTALLOWED -- Not allowed; the interrupt is being registered or is locked for enable/disable.\n + #QURT_EINT -- Invalid interrupt number. + + @dependencies + None. +*/ +unsigned int qurt_interrupt_set_config3(unsigned int int_num, unsigned int config_id, unsigned int config_val); + + +/**@ingroup func_qurt_interrupt_raise + Raises the interrupt. \n + This function triggers a level-triggered L2VIC + interrupt, and accepts interrupt numbers in the range of 0 to 1023. + + @param[in] interrupt_num Interrupt number. + + @return + #QURT_EOK -- Success \n + -1 -- Failure; the interrupt is not supported. + + @dependencies + None. + */ +int qurt_interrupt_raise(unsigned int interrupt_num); + +/**@ingroup func_qurt_interrupt_raise2 + Raises the interrupt and returns the current pcycle value. + + @param[in] interrupt_num Interrupt number. + + @return + 0xFFFFFFFFFFFFFFFF -- Failure; the interrupt is not supported.\n + Other value -- pcycle count at the time the interrupt is raised. + + @dependencies + None. + */ +unsigned long long qurt_interrupt_raise2(unsigned int interrupt_num); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_isr_subcall + Indicates whether the current function is called from a callback procedure (either short or long). + + @return + #QURT_EOK -- TRUE \n + #QURT_EVAL -- FALSE. + + @dependencies + None. + */ +int qurt_isr_subcall(void); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_INT_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_island.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_island.h new file mode 100755 index 0000000000000..f0c8ee27cf8b0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_island.h @@ -0,0 +1,122 @@ +#ifndef QURT_ISLAND_H +#define QURT_ISLAND_H + +/** + @file qurt_island.h + @brief Prototypes of power API + The APIs allow entering and exiting island mode where the memory + accesses are limited to local memory. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + +=============================================================================*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_island_get_status + Gets Island mode status. + + Returns a value that indicates whether the QuRT system executes in Island mode. + + @return + 0 - Normal mode. \n + 1 - Island mode. + + @dependencies + None. +*/ +unsigned int qurt_island_get_status (void); + +/**@ingroup func_qurt_island_get_status2 + Gets Island mode status especially that differentiates between island partial exit and complete exit. + + Returns a value that indicates the current state. + + @note1hang Transition from NORMAL mode to ISLAND mode happens in single + threaded mode. Whereas transition from ISLAND mode to other modes + happen in multi-threaded mode. So, a thread that gets island mode + status as NORMAL can assume the same status till it continues to + run. A thread that gets island mode status as ISLAND should + assume that the status may change to EXITING or NORMAL while it + runs. A thread that gets island mode status as EXITING should + assume that the status may change to NORMAL while it runs. If + the thread goes to wait state in after reading the status, it should get + the island mode state again and not assume the previous state. + @note2hang This api returns more intrinsic states than qurt_island_get_status, + when qurt_island_get_status returns 0, this api could return + QURT_ISLAND_MODE_EXITING or QURT_ISLAND_MODE_ISLAND + + @param[in/out] data field is reserved for future use. If NULL pointer is passed, + the field will be ignored. If a valid pointer is passed, + QuRT will return back a bitmask which can be interpreted as follows: + data[31] - Valid bit. Set to 1 to indicate data[30:0] are valid. + Otherwise set to 0. + data[30:0] – Reserved for future definition. + + @return + QURT_ISLAND_MODE_NORMAL - Main mode \n + QURT_ISLAND_MODE_ISLAND - Island mode \n + QURT_ISLAND_MODE_EXITING - Exiting Island mode \n + + @dependencies + None. +*/ +unsigned int qurt_island_get_status2 (unsigned int *data); + + + +/**@ingroup func_qurt_island_get_exit_status + Gets the reason for the last Island mode exit status. + + @param[out] cause_code Pointer that returns the cause code of the last + island exit reason. \n + - #QURT_EISLANDUSEREXIT -- Island exit due to user call for island exit.\n + - #QURT_ENOISLANDENTRY -- API called before exiting island. \n + - #QURT_EISLANDINVALIDINT -- Island exit due to an invalid interrupt in Island mode. @tablebulletend + + @param[out] int_num Pointer that holds the invalid interrupt number that caused + island exit when the cause code is #QURT_EISLANDINVALIDINT. + For other cases, it is -1. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_exit_status(unsigned int *cause_code, int *int_num); + +/**@ingroup func_qurt_island_get_enter_timestamp + Gets the recent timestamp when the system exits STM during island enter. + + @param[out] island_enter_timestamp Returns a pointer to the recent timestamp + recorded after the system exits STM during island enter. If the system never + attempts to enter island, the island_enter_timestamp return pointer holds a value + of zero. + + @return + None. + + @dependencies + None. +*/ +void qurt_island_get_enter_timestamp(unsigned long long *island_enter_timestamp); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISLAND_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_isr.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_isr.h new file mode 100755 index 0000000000000..db29ea2f265d7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_isr.h @@ -0,0 +1,177 @@ +#ifndef QURT_ISR_H +#define QURT_ISR_H + +/*===================================================================== + + @file qurt_isr.h + + @brief Prototypes of Qurt ISR API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2017, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + Functions +=============================================================================*/ + + +/**@ingroup func_qurt_isr_set_hw_config_callback + Set callback function for the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_config_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_enable_callback + Set callback function for enabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_enable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_set_hw_disable_callback + Set callback function for disabling the configuration related to interrupt hardware. + In a process, the callback function can only be set once. + + @param[in] cb_addr address of the callback function. + + @return + #QURT_EOK -- the callback function is set succssfully. \n + #QURT_EFAILED -- Failure. The callback function has been set before. + + @dependencies + None. + */ +int qurt_isr_set_hw_disable_callback(unsigned int cb_addr); + + +/**@ingroup func_qurt_isr_create + Creates an ISR thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + + @return + #QURT_EVAL -- Invalid arguments + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_isr_create (qurt_thread_t *thread_id, qurt_thread_attr_t *pAttr); + +/**@ingroup func_qurt_isr_register2 + Registers an Interrupt Service Routine to an ISR thread. ISR callback with the specified attributes. + The interrupt is enabled when this function returns success. + + @datatypes + qurt_thread_t + + @param[in] isr_thread_id ISR thread ID, returned from qurt_isr_create() + @param[in] int_num The interrupt number + @param[in] prio Priority of the ISR + @param[in] flags Defines ACK type. Values : \n + QURT_INT_NON_DELAYED_ACK - ISR is acknowledged by the interrupt handle routine + in the Kernel. + QURT_INT_DELAYED_ACK - Client chooses to acknowledge. + @param[in] int_type. Notifies it to registered function. Values: \n + - QURT_INT_TRIGGER_USE_DEFAULT + - QURT_INT_TRIGGER_LEVEL_HIGH + - QURT_INT_TRIGGER_LEVEL_LOW + - QURT_INT_TRIGGER_RISING_EDGE + - QURT_INT_TRIGGER_FALLING_EDGE + - QURT_INT_TRIGGER_DUAL_EDGE + @param[in] isr Interrupt Service Routine with proto type void isr (void *arg, int int_num) + @param[in] arg 1st argument of the ISR when it is called to service the interrupt + + @return + QURT_EOK -- Successfully registered the ISR for the interrupt + QURT_EINT -- Interrupt not configured + QURT_EINVALID -- Invalid Thread ID + QURT_EDISABLED -- The feature is disabled + QURT_EDUPLICATE -- Interrupt is already registered + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_register2 (qurt_thread_t isr_thread_id, int int_num, unsigned short prio, unsigned short flags, unsigned int int_type, void (*isr) (void *, int), void *arg); + +/**@ingroup func_qurt_isr_deregister2 + De-registers the ISR for the specified interrupt. + The interrupt is disabled when this function returns success. + + @param[in] int_num The interrupt number + + @return + QURT_EOK -- ISR deregistered successfully + QURT_ENOREGISTERED -- Interrupt with int_num is not registered + + @dependencies + None. + */ +int qurt_isr_deregister2 (int int_num); + +/**@ingroup func_qurt_isr_delete + ISR thread will exit and releases Kernel resources + + @note1hang The ISR thread shouldn't be actively processing interrupts, + otherwise the call will fail and return an error. + + @param[in] thread-id of the ISR thread that needs to be deleted. + + @return + QURT_ENOTALLOWED -- ISR thread is processing an interrupt + QURT_EINVALID -- Invalid ISR thread ID + QURT_EOK -- Success + + @dependencies + Thread ID should be created using qurt_isr_create() + */ +int qurt_isr_delete (qurt_thread_t isr_tid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_ISR_H */ + + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_l2cfg.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_l2cfg.h new file mode 100755 index 0000000000000..7e26b30a580d9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_l2cfg.h @@ -0,0 +1,98 @@ +#ifndef QURT_L2CFG_H +#define QURT_L2CFG_H +/** + @file qurt_l2cfg.h + @brief QuRT APIs for L2 configuration and system configuration + +EXTERNAL FUNCTIONS + qurt_l2cfg_set + qurt_l2cfg_get + qurt_system_config_get + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + +/* Definition for system configuration */ +/** @addtogroup l2cfg_macros +@{ */ +#define QURT_CORE_CFG_HMX_INT8_SPATIAL 0x78 /**< HMX fixed-point spatial size */ +#define QURT_CORE_CFG_HMX_INT8_DEPTH 0x7C /**< HMX fixed-point output depth */ +/** @} */ /* end_addtogroup l2cfg_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_l2cfg_set + Sets the value of a L2 configuration register. A register can be set *IFF* its + initial value is configured. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[in] value Value to set the register to. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; likely + a configuration problem. \n + #QURT_EINVALID -- Argument error. \n + #QURT_ENOTALLOWED -- Setting this register is prohibited. + + @dependencies + None. + */ +int qurt_l2cfg_set (unsigned short offset, unsigned int value); + +/**@ingroup func_qurt_l2cfg_get + Gets the value of a L2 configuration register. + + @param[in] offset Offset of L2 configuration register; must be multiple of 4. + @param[out] value Pointer to value of the register. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Internal mapping that covers L2CFG register file absent; + likely a configuration problem. \n + #QURT_EINVALID -- Argument error. + + @dependencies + None. + + */ +int qurt_l2cfg_get (unsigned short offset, unsigned int * value); + + +/**@ingroup func_qurt_system_config_get + Gets the system configuration information. + + @param[in] index Index to system configuration. Values:\n + - #QURT_CORE_CFG_HMX_INT8_SPATIAL \n + - #QURT_CORE_CFG_HMX_INT8_DEPTH @tablebulletend + + @param[out] data Pointer to a word for returned data. + + @return + #QURT_EOK -- Get the configuration data successful. \n + Other values -- Failure (no such configuration available). + + @dependencies + None. + + */ +int qurt_system_config_get(int index, unsigned int *data); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_L2CFG_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_lifo.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_lifo.h new file mode 100755 index 0000000000000..dc399fccc5f0f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_lifo.h @@ -0,0 +1,71 @@ +#ifndef QURT_LIFO_H +#define QURT_LIFO_H +/** + @file qurt_lifo.h + + @brief + Provide lock free LastInFirstOut algorithm, which can be used in a + variety of situations for allocation/free fixed size buffer + This implementation touches the first word of your FREED buffer. Even + though it does not matter how you use it when it is allocated, you might want + to be a bit careful not to put your MAGIC number as the first field. + Because it will not hold the magic value for "freed" + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /*===================================================================== + Functions + ======================================================================*/ + +/*======================================================================*/ +/** + Pops an element out of the LIFO. + + @param[in] freelist Pointer to the head of your list. + + @return + Top object from the list + + @dependencies + None. +*/ +/* ======================================================================*/ +void * qurt_lifo_pop(void *freelist); + + +/*======================================================================*/ +/** + Pushes an element into the LIFO. + + @param[in] freelist Pointer to the head of your list. + @param[in] buf Pointer to your buffer to push into the list. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_lifo_push(void *freelist, void *buf); + +void qurt_lifo_remove(void *freelist, void *buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_LIFO_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mailbox.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mailbox.h new file mode 100755 index 0000000000000..a6cd91c611782 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mailbox.h @@ -0,0 +1,176 @@ +#ifndef QURT_MAILBOX_H +#define QURT_MAILBOX_H + +/** + @file qurt_mailbox.h + @brief Definitions, macros, and prototypes used for QuRT mailbox + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* Definitions on typedef and return values */ + +#define QURT_MAILBOX_ID_NULL 0 +#define QURT_MAILBOX_ERROR -1 +#define QURT_MAILBOX_ID_ERROR -2 +#define QURT_MAILBOX_NON_VALID_DATA -3 +#define QURT_MAILBOX_FULL -4 +#define QURT_MAILBOX_DELETED -5 +#define QURT_MAILBOX_RECEIVE_HALTED -6 +#define QURT_MAILBOX_BANDWIDTH_LIMIT -7 + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ + +#define QURT_MAILBOX_AT_QURTOS 0U // Receiver is QurtOS +#define QURT_MAILBOX_AT_ROOTPD 1U // Receiver is RootPD (ASID=0) +#define QURT_MAILBOX_AT_USERPD 2U // Receiver is User PD (ASID!=0) +#define QURT_MAILBOX_AT_SECUREPD 3U // Receiver is Secure PD + +typedef unsigned char qurt_mailbox_receiver_cfg_t; + +#define QURT_MAILBOX_SEND_OVERWRITE 0U // When there is already valid content, overwrite it +#define QURT_MAILBOX_SEND_NON_OVERWRITE 1U // When there is already valid content, return failure + +typedef unsigned char qurt_mailbox_send_option_t; + + +#define QURT_MAILBOX_RECV_WAITING 0U // When there is no valid content, wait for it +#define QURT_MAILBOX_RECV_NON_WAITING 1U // When there is no valid content, return failure immediately +#define QURT_MAILBOX_RECV_PEEK_NON_WAITING 2U // Read the content, but doesn't remove it from the mailbox. No waiting. + +typedef unsigned char qurt_mailbox_recv_option_t; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/* Function prototype */ + +/**@ingroup qurt_mailbox_create + Creates a QuRT mailbox. + + @param name Mailbox name up to 8 characters. + @param recv_opt Configuration on the receiver process. + + @return + Mailbox ID -- Mailbox Identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at creating mailbox + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_create(char *name, qurt_mailbox_receiver_cfg_t recv_opt); + + +/**@ingroup qurt_mailbox_get_id + Gets a QuRT mailbox identifier. + + @param name Mailbox name up to 8 characters. + + @return + Mailbox ID -- Mailbox identifier \n + #QURT_MAILBOX_ID_NULL -- NULL, failure at getting mailbox ID + + @dependencies + None. +*/ +unsigned long long qurt_mailbox_get_id(char *name); + + +/**@ingroup qurt_mailbox_send + Sends data to a QuRT mailbox. + + @param mailbox_id Mailbox identifier. + @param send_opt Option for mailbox send. + @param data Data to send. + + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors.\n + #QURT_MAILBOX_FULL Valid data already exists, non-overwriting.\n + #QURT_MAILBOX_BANDWIDTH_LIMIT Reached the bandwidth limitation. + + @dependencies + None. +*/ +int qurt_mailbox_send(unsigned long long mailbox_id, qurt_mailbox_send_option_t send_opt, unsigned long long data); + + +/**@ingroup qurt_mailbox_receive + Receive data from QuRT mailbox + + @param mailbox_id Mailbox Identifier + @param send_opt Option for mailbox receiving + @param data Pointer to data buffer for receiving + + @return + #QURT_EOK Success \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. \n + #QURT_MAILBOX_NON_VALID_DATA No current valid data, put the previous content in the buffer. \n + #QURT_MAILBOX_RECEIVE_HALTED Receive halted, the waiting thread is woken up. \n + #QURT_MAILBOX_DELETED Mailbox is deleted, and the waiting thread is woken up. + + @dependencies + None. +*/ +int qurt_mailbox_receive(unsigned long long mailbox_id, qurt_mailbox_recv_option_t recv_opt, unsigned long long *data); + + +/**@ingroup qurt_mailbox_delete + Deletes a QuRT mailbox. + + A mailbox can only be deleted from the process that created the mailbox. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error. \n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_delete(unsigned long long mailbox_id); + + +/**@ingroup qurt_mailbox_receive_halt + Halts a QuRT mailbox receiving and wakes up waiting threads. + + @param mailbox_id Mailbox identifier. + + @return + #QURT_EOK Success. \n + #QURT_MAILBOX_ID_ERROR Mailbox ID error.\n + #QURT_MAILBOX_ERROR Other errors. + + @dependencies + None. +*/ +int qurt_mailbox_receive_halt(unsigned long long mailbox_id); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_MAILBOX_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_memory.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_memory.h new file mode 100755 index 0000000000000..90ce2586fec50 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_memory.h @@ -0,0 +1,1487 @@ +#ifndef QURT_MEMORY_H +#define QURT_MEMORY_H +/** + @file qurt_memory.h + @brief Prototypes of kernel memory API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include +#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup memory_management_macros +@{ */ +#define QURT_SYSTEM_ALLOC_VIRTUAL 1 /**< Allocates available virtual memory in the address space of all + processes.*/ +/** @} */ /* end_addtogroup memory_management_macros */ +/**@cond rest_reg_dist */ +/** @addtogroup memory_management_types +@{ */ +/** @xreflabel{hdr:qurt_mem_default_pool} */ +extern qurt_mem_pool_t qurt_mem_default_pool __attribute__((section(".data"))); /**< Memory pool object.*/ +/** @} */ /* end_addtogroup memory_management_types */ + +/** @cond rest_reg_dist */ +/** Mapping attribute information*/ +typedef struct{ + qurt_paddr_64_t paddr; + qurt_size_t size ; + qurt_mem_cache_mode_t cache_mode; + qurt_perm_t perms ; +}qurt_mapping_attr_t; +/** @endcond */ +/** @} */ /* end_addtogroup mapping_attribute_types*/ + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_mem_cache_clean + Performs a cache clean operation on the data stored in the specified memory area. + Peforms a syncht on all the data cache operations when the Hexagon processor version is V60 or greater. + + @note1hang Perform the flush all operation only on the data cache. + + @note1cont This operation flushes and invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed and invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_INVALIDATE + - #QURT_MEM_CACHE_FLUSH_ALL\n + @note1 #QURT_MEM_CACHE_FLUSH_ALL is valid only when the type is #QURT_MEM_DCACHE @tablebulletend + @param[in] type Cache type. Values: + - #QURT_MEM_ICACHE + - #QURT_MEM_DCACHE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type.\n + + @dependencies + None. +*/ +int qurt_mem_cache_clean(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_clean2 + Performs a data cache clean operation on the data stored in the specified memory area. + + This API only performs the following data cache operations:\n + - #QURT_MEM_CACHE_FLUSH\n + - #QURT_MEM_CACHE_INVALIDATE\n + - #QURT_MEM_CACHE_FLUSH_INVALIDATE -- flushes/invalidates the contents of all cache lines from start address + to end address (start address + size). The contents of the adjoining buffer can be + flushed/invalidated if it falls in any of the cache line. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_op_t \n + #qurt_mem_cache_type_t + + @param[in] addr Address of data to flush. + @param[in] size Size (in bytes) of data to flush. + @param[in] opcode Type of cache clean operation. Values:\n #QURT_MEM_CACHE_FLUSH\n #QURT_MEM_CACHE_INVALIDATE\n + #QURT_MEM_CACHE_FLUSH_INVALIDATE + @param[in] type Cache type. Values: \n #QURT_MEM_DCACHE + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid cache type. + + @dependencies + None. +*/ +int qurt_mem_cache_clean2(qurt_addr_t addr, qurt_size_t size, qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type); + +/**@ingroup func_qurt_mem_cache_phys_clean + Performs a cache clean operation on the data stored in the specified memory area based on address match and mask. + Operate on a cache line when (LINE.PhysicalPageNumber & mask) == addrmatch. + + @note1hang The addrmatch value should be the upper 24-bit physical address to match against. + + @datatypes + #qurt_mem_cache_op_t \n + + @param[in] mask 24-bit address mask. + @param[in] addrmatch Physical page number (24 bits) of memory to use as an address match. + @param[in] opcode Type of cache clean operation. Values: + - #QURT_MEM_CACHE_FLUSH + - #QURT_MEM_CACHE_INVALIDATE @tablebulletend + + @return + #QURT_EOK -- Cache operation performed successfully.\n + #QURT_EVAL -- Invalid operation + + @dependencies + None. +*/ + +int qurt_mem_cache_phys_clean(unsigned int mask, unsigned int addrmatch, qurt_mem_cache_op_t opcode); + +/**@ingroup func_qurt_mem_l2cache_line_lock + Performs an L2 cache line locking operation. This function locks selective lines in the L2 cache memory. + + @note1hang Perform the line lock operation only on the 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to lock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of L2 cache memory to line lock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success.\n + #QURT_EALIGN -- Data alignment or address failure. + #QURT_EINVALID -- Improper addr and size passed (e.g. integer overflow due to addr + size) + #QURT_EFAILED -- Failed to lock cache line as all the ways were locked for the corresponding set of an address + in the range of addr and addr+size or the address range is not L2 cacheable + @dependencies + None. +*/ +int qurt_mem_l2cache_line_lock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_l2cache_line_unlock + Performs an L2 cache line unlocking operation. This function unlocks selective lines in the L2 cache memory. + + @note1hang Perform the line unlock operation only on a 32-byte aligned size and address. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] addr Address of the L2 cache memory line to unlock; the address must be 32-byte aligned. + @param[in] size Size (in bytes) of the L2 cache memory line to unlock; size must be a multiple of 32 bytes. + + @return + #QURT_EOK -- Success. \n + #QURT_EALIGN -- Aligning data or address failure. \n + #QURT_EFAILED -- Operation failed, cannot find the matching tag. + + @dependencies + None. +*/ +int qurt_mem_l2cache_line_unlock(qurt_addr_t addr, qurt_size_t size); + +/**@ingroup func_qurt_mem_region_attr_init + @xreflabel{sec:qurt_mem_region_attr_init} + Initializes the specified memory region attribute structure with default attribute values: \n + - Mapping -- #QURT_MEM_MAPPING_VIRTUAL \n + - Cache mode -- #QURT_MEM_CACHE_WRITEBACK \n + - Physical address -- -1 \n + - Virtual address -- -1 \n + - Memory type -- #QURT_MEM_REGION_LOCAL \n + - Size -- -1 + + @note1hang The memory physical address attribute must be explicitly set by calling the + qurt_mem_region_attr_set_physaddr() function. The size and pool attributes are set directly + as parameters in the memory region create operation. + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the destination structure for the memory region attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_mem_region_attr_init(qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attach + Initializes a memory pool object to attach to a pool predefined in the system + configuration file. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. They are specified in memory region create operations + (Section @xref{sec:mem_region_create}). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool attach + operation is necessary only when allocating memory regions in nonstandard + memory units such as TCM. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach(char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_attach2 + Gets the identifier that corresponds to a pool object created specifically for a client, for example, HLOS_PHYSPOOL. + The client_handle is used to look up the client specific pool. + + Memory pool objects assign memory regions to physical memory in different + Hexagon memory units. Memory pool objects are specified during mapping creation operations + (qurt_mem_mmap() and qurt_mem_region_create()). + + @note1hang QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}) for allocation memory regions in SMI memory. The pool_attach2 + operation is necessary only when allocating memory regions in memory units specific to the client. + + @datatypes + #qurt_mem_pool_t + + @param[in] client_handle Client identifier used by the OS to lookup the identifier + for client specific pool + @param[in] name Pointer to the memory pool name. + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Attach operation successful. + + @dependencies + None. +*/ +int qurt_mem_pool_attach2(int client_handle, char *name, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_create + @xreflabel{hdr:qurt_mem_pool_create} + Dynamically creates a memory pool object from a physical address range. + + The pool is assigned a single memory region with the specified base address and size. + + The base address and size values passed to this function must be aligned to 4K byte + boundaries, and must be expressed as the actual base address and size values divided by 4K. + + For example, the function call: + @code + qurt_mem_pool_create ("TCM_PHYSPOOL", 0xd8020, 0x20, &pool) + @endcode + ... is equivalent to the following static pool definition in the QuRT system configuration file: + @code + + + + @endcode + + @cond rest_dist For more information on the system configuration file, see @xhyperref{80VB41979,80-VB419-79}. @endcond + + @note1hang Dynamically created pools are not identical to static pools. In particular, + qurt_mem_pool_attr_get() is not valid with dynamically created pools. + + @note1cont Dynamic pool creation permanently consumes system resources, and cannot be undone. + + @datatypes + #qurt_mem_pool_t + + @param[in] name Pointer to the memory pool name. + @param[in] base Base address of the memory region (divided by 4K). + @param[in] size Size (in bytes) of the memory region (divided by 4K). + @param[out] pool Pointer to the memory pool object. + + @return + #QURT_EOK -- Success. + + @dependencies + None. +*/ +int qurt_mem_pool_create(char *name, unsigned base, unsigned size, qurt_mem_pool_t *pool); + +/**@ingroup func_qurt_mem_pool_add_pages + Adds a physical address range to the specified memory pool object.\n + + @note1hang Call this operation only with root privileges (guest OS mode). + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_mem_pool_add_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages); + +/**@ingroup func_qurt_mem_pool_remove_pages + Removes a physical address range from the specified memory pool object. + + If any part of the address range is in use, this operation returns an + error without changing the state. + + @note1hang Call this operation only with root privileges (guest-OS mode). + + @note1cont In the future, this operation will support (via the flags parameter) the + removal of a physical address range when part of the range is in use. + + @datatypes + #qurt_mem_pool_t + + @param[in] pool Memory pool object. + @param[in] first_pageno First page number of the physical address range (equivalent to address >> 12) + @param[in] size_in_pages Number of pages in the physical address range (equivalent to size >> 12) + @param[in] flags Remove options. Values: \n + - 0 -- Skip holes in the range that are not part of the pool (default) \n + - #QURT_POOL_REMOVE_ALL_OR_NONE -- Pages are removed only if the specified + physical address range is entirely contained (with no holes) in the + pool free space. @tablebulletend + @param[in] callback Callback procedure called when pages were successfully removed. + Not called if the operation failed. Passing 0 as the parameter + value causes the callback to not be called. + @param[in] arg Value passed as an argument to the callback procedure. + + @return + #QURT_EOK -- Pages successfully removed. + + @dependencies + None. +*/ +int qurt_mem_pool_remove_pages(qurt_mem_pool_t pool, + unsigned first_pageno, + unsigned size_in_pages, + unsigned flags, + void (*callback)(void *), + void *arg); +/**@ingroup memory_management_types*/ +#define QURT_POOL_REMOVE_ALL_OR_NONE 1 /**< */ + +/**@ingroup func_qurt_mem_pool_attr_get + Gets the memory pool attributes. \n + Retrieves pool configurations based on the pool handle, and fills in + the attribute structure with configuration values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_attr_t + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[out] attr Pointer to the memory region attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_attr_get (qurt_mem_pool_t pool, qurt_mem_pool_attr_t *attr); + +/**@ingroup func_qurt_mem_pool_attr_get_size + Gets the size of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] size Pointer to the destination variable for the range size. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_size (qurt_mem_pool_attr_t *attr, int range_id, qurt_size_t *size){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*size) = 0; + return QURT_EINVALID; + } + else { + (*size) = attr->ranges[range_id].size; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr + Gets the start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_t *addr){ + if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; + } + else { + (*addr) = (attr->ranges[range_id].start)<<12; + } + return QURT_EOK; +} + +/**@ingroup func_qurt_mem_pool_attr_get_addr_64 + Gets the 64 bit start address of the specified memory pool range. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_addr_64_t + + @param[in] attr Pointer to the memory pool attribute structure. + @param[in] range_id Memory pool range key. + @param[out] addr Pointer to the destination variable for range start address. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Range is invalid. + + @dependencies + None. +*/ +static inline int qurt_mem_pool_attr_get_addr_64 (qurt_mem_pool_attr_t *attr, int range_id, qurt_addr_64_t *addr){ +if ((range_id >= MAX_POOL_RANGES) || (range_id < 0)){ + (*addr) = 0; + return QURT_EINVALID; +} +else { + (*addr) = ((qurt_addr_64_t)attr->ranges[range_id].start)<<12; + } + return QURT_EOK; + } + + +/**@ingroup func_qurt_mem_pool_status_get + Gets the memory pool status. \n + Based on the pool handle, retrieves largest contiguous free memory, + total free memory, and total memory declared for the pool in bytes. Fills in + the memory status structure with the values. + + @datatypes + #qurt_mem_pool_t \n + #qurt_mem_pool_status_t + + @param[in] pool Pool handle. + @param[out] status Pointer to the memory pool status structure. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Corrupt handle; pool handle is invalid. +*/ +int qurt_mem_pool_status_get (qurt_mem_pool_t pool, qurt_mem_pool_status_t *status); + + +/**@ingroup func_qurt_mem_pool_is_available + Checks whether the number of pages that the page_count argument indicates + can be allocated from the specified pool. + + @datatypes + #qurt_mem_pool_attr_t \n + #qurt_mem_mapping_t \n + + @param[in] pool Pool handle obtained from qurt_mem_pool_attach(). + @param[in] page_count Number of 4K pages. + @param[in] mapping_type Variable of type qurt_mem_mapping_t. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Mapping_type is invalid. \n + #QURT_EMEM -- Specified pages cannot be allocated from the pool. + + @dependencies + None. +*/ +int qurt_mem_pool_is_available(qurt_mem_pool_t pool, int page_count, qurt_mem_mapping_t mapping_type); + + +/**@ingroup func_qurt_mem_region_create + @xreflabel{sec:mem_region_create} + Creates a memory region with the specified attributes. + + The application initializes the memory region attribute structure with + qurt_mem_region_attr_init() and qurt_mem_region_attr_set_bus_attr(). + + If the virtual address attribute is set to its default value + (Section @xref{sec:qurt_mem_region_attr_init}), the virtual address of the memory region is + automatically assigned any available virtual address value. + + If the memory mapping attribute is set to virtual mapping, the physical address of the memory region + is also automatically assigned.\n + + @note1hang The physical address attribute is explicitly set in the attribute structure only + for memory regions with physical-contiguous-mapped mapping. + + Memory regions are always assigned to memory pools. The pool value specifies the memory pool + that the memory region is assigned to. + + @note1hang If attr is specified as NULL, the memory region is created with default + attribute values (Section @xref{sec:qurt_mem_region_attr_init}). + QuRT predefines the memory pool object #qurt_mem_default_pool + (Section @xref{dox:mem_management}), which allocates memory regions in SMI memory. + + @datatypes + #qurt_mem_region_t \n + #qurt_size_t \n + #qurt_mem_pool_t \n + #qurt_mem_region_attr_t + + @param[out] region Pointer to the memory region object. + @param[in] size Memory region size (in bytes). If size is not an integral multiple of 4K, + it is rounded up to a 4K boundary. + @param[in] pool Memory pool of the region. + @param[in] attr Pointer to the memory region attribute structure. + + @return + #QURT_EOK -- Memory region successfully created.\n + #QURT_EMEM -- Not enough memory to create region. + #QURT_EINVALID -- Invalid cache attributes / permissions provided in attribute. + + @dependencies + None. +*/ +int qurt_mem_region_create(qurt_mem_region_t *region, qurt_size_t size, qurt_mem_pool_t pool, qurt_mem_region_attr_t *attr); + +/**@ingroup func_qurt_mem_region_delete + Deletes the specified memory region. + + If the caller application creates the memory region, it is removed and the system reclaims its + assigned memory. + + If a different application creates the memory region (and is shared with the caller + application), only the local memory mapping to the region is removed; the system does + not reclaim the memory. + + @datatypes + #qurt_mem_region_t + + @param[in] region Memory region object. + + @returns + #QURT_EOK -- Region successfully deleted. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. +*/ +int qurt_mem_region_delete(qurt_mem_region_t region); + + +/**@ingroup func_qurt_mem_region_attr_get + @xreflabel{sec:mem_region_attr_get} + Gets the memory attributes of the specified message region. + After a memory region is created, its attributes cannot be changed. + + @datatypes + #qurt_mem_region_t \n + #qurt_mem_region_attr_t + + @param[in] region Memory region object. + @param[out] attr Pointer to the destination structure for memory region attributes. + + @return + #QURT_EOK -- Operation successfully performed. \n + Error code -- Failure. + + @dependencies + None. +*/ +int qurt_mem_region_attr_get(qurt_mem_region_t region, qurt_mem_region_attr_t *attr); + + +/**@ingroup func_qurt_mem_region_attr_set_type + Sets the memory type in the specified memory region attribute structure. + + The type indicates whether the memory region is local to an application or shared between + applications. + @cond rest_dist For more information, see @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in,out] attr Pointer to memory region attribute structure. + @param[in] type Memory type. Values: \n + - #QURT_MEM_REGION_LOCAL \n + - #QURT_MEM_REGION_SHARED @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t type){ + attr->type = type; +} + +/**@ingroup func_qurt_mem_region_attr_get_size + Gets the memory region size from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_size_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] size Pointer to the destination variable for memory region size. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_size(qurt_mem_region_attr_t *attr, qurt_size_t *size){ + (*size) = attr->size; +} + +/**@ingroup func_qurt_mem_region_attr_get_type + Gets the memory type from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_region_type_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] type Pointer to the destination variable for the memory type. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_type(qurt_mem_region_attr_t *attr, qurt_mem_region_type_t *type){ + (*type) = attr->type; +} + +/**@ingroup func_qurt_mem_region_attr_set_physaddr + Sets the memory region 32-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise QuRT automatically sets it + when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr(qurt_mem_region_attr_t *attr, qurt_paddr_t addr){ + attr->ppn = (unsigned)(((unsigned)(addr))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr + Gets the memory region physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for memory region physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned)(((unsigned) (attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_region_attr_set_virtaddr + Sets the memory region virtual address in the specified memory attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_addr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr Memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_virtaddr(qurt_mem_region_attr_t *attr, qurt_addr_t addr){ + attr->virtaddr = addr; +} + +/**@ingroup func_qurt_mem_region_attr_get_virtaddr + Gets the memory region virtual address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr Pointer to the destination variable for the memory region virtual address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_virtaddr(qurt_mem_region_attr_t *attr, unsigned int *addr){ + (*addr) = (unsigned int)(attr->virtaddr); +} + +/**@ingroup func_qurt_mem_region_attr_set_mapping + Sets the memory mapping in the specified memory region attribute structure. + + The mapping value indicates how the memory region is mapped in virtual memory. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mapping Mapping. Values: + - #QURT_MEM_MAPPING_VIRTUAL + - #QURT_MEM_MAPPING_PHYS_CONTIGUOUS + - #QURT_MEM_MAPPING_IDEMPOTENT + - #QURT_MEM_MAPPING_VIRTUAL_FIXED + - #QURT_MEM_MAPPING_NONE + - #QURT_MEM_MAPPING_VIRTUAL_RANDOM + - #QURT_MEM_MAPPING_INVALID @tablebulletend + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t mapping){ + attr->mapping_type = mapping; +} + +/**@ingroup func_qurt_mem_region_attr_get_mapping + Gets the memory mapping from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_mapping_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mapping Pointer to the destination variable for memory mapping. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_mapping(qurt_mem_region_attr_t *attr, qurt_mem_mapping_t *mapping){ + (*mapping) = attr->mapping_type; +} + +/**@ingroup func_qurt_mem_region_attr_set_cache_mode + Sets the cache operation mode in the specified memory region attribute structure. + + @cond rest_dist For more information on the cache, see @xhyperref{80VB41992,80-VB419-92}.@endcond + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] mode Cache mode. Values: \n + - #QURT_MEM_CACHE_WRITEBACK \n + - #QURT_MEM_CACHE_WRITETHROUGH\n + - #QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE\n + - #QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE\n + - #QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE\n + - #QURT_MEM_CACHE_NONE @tablebulletend + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t mode){ + QURT_PGATTR_C_SET(attr->pga, (unsigned)mode); +} + +/**@ingroup func_qurt_mem_region_attr_get_cache_mode + Gets the cache operation mode from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_cache_mode(qurt_mem_region_attr_t *attr, qurt_mem_cache_mode_t *mode){ + unsigned int mode_temp = QURT_PGATTR_C_GET(attr->pga); + (*mode) = (qurt_mem_cache_mode_t)mode_temp; +} + +/**@ingroup func_qurt_mem_region_attr_set_bus_attr + Sets the (A1, A0) bus attribute bits in the specified memory region attribute structure. + + @cond rest_dist For more information on the bus attribute bits, see the @xhyperref{80VB41992,80-VB419-92}. @endcond + + @datatypes + #qurt_mem_region_attr_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] abits The (A1, A0) bits to use with the memory region, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_set_bus_attr(qurt_mem_region_attr_t *attr, unsigned abits){ + QURT_PGATTR_A_SET(attr->pga, abits); +} + +/**@ingroup func_qurt_mem_region_attr_get_bus_attr + Gets the (A1, A0) bus attribute bits from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] pbits Pointer to an unsigned integer that is filled in with + the (A1, A0) bits from the memory region attribute structure, expressed as a 2-bit binary number. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_bus_attr(qurt_mem_region_attr_t *attr, unsigned *pbits){ + (*pbits) = QURT_PGATTR_A_GET(attr->pga); +} + +void qurt_mem_region_attr_set_owner(qurt_mem_region_attr_t *attr, int handle); +void qurt_mem_region_attr_get_owner(qurt_mem_region_attr_t *attr, int *p_handle); +void qurt_mem_region_attr_set_perms(qurt_mem_region_attr_t *attr, unsigned perms); +void qurt_mem_region_attr_get_perms(qurt_mem_region_attr_t *attr, unsigned *p_perms); + +/**@ingroup func_qurt_mem_map_static_query + Determines whether a memory page is statically mapped. + Pages are specified by the following attributes: physical address, page size, cache mode, + and memory permissions. \n + - If the specified page is statically mapped, vaddr returns the virtual + address of the page. \n + - If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + The system configuration file defines QuRT memory maps. + + @datatypes + #qurt_addr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr Physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped, vaddr returns the virtual address. \n + #QURT_EMEM -- Specified page is not statically mapped, vaddr returns -1. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query(qurt_addr_t *vaddr, qurt_addr_t paddr, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + + +/**@ingroup func_qurt_mem_region_query + Queries a memory region. \n + This function determines whether a dynamically-created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. + When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns #QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_paddr_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr Physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Query successfully performed. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_t paddr); + + +/**@ingroup func_qurt_mapping_create + @xreflabel{hdr:qurt_mapping_create} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Mapping created. \n + #QURT_EMEM -- Failed to create mapping. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove + @xreflabel{hdr:qurt_mapping_remove} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr Physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Mapping created. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove(qurt_addr_t vaddr, qurt_addr_t paddr, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr + Translates a virtual memory address to the physical memory address to which it maps. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the + physical address of another process. + + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- Physical address to which the virtual address is mapped.\n + 0 -- Virtual address not mapped. + + @dependencies + None. +*/ +qurt_paddr_t qurt_lookup_physaddr (qurt_addr_t vaddr); + +/**@ingroup func_qurt_mem_region_attr_set_physaddr_64 + Sets the memory region 64-bit physical address in the specified memory attribute structure. + + @note1hang The physical address attribute is explicitly set only for memory regions with + physical contiguous mapping. Otherwise it is automatically set by + QuRT when the memory region is created. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in,out] attr Pointer to the memory region attribute structure. + @param[in] addr_64 Memory region 64-bit physical address. + + @return + None. + */ +static inline void qurt_mem_region_attr_set_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t addr_64){ + attr->ppn = (unsigned)(((unsigned long long)(addr_64))>>12); +} + +/**@ingroup func_qurt_mem_region_attr_get_physaddr_64 + Gets the memory region 64-bit physical address from the specified memory region attribute structure. + + @datatypes + #qurt_mem_region_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory region attribute structure. + @param[out] addr_64 Pointer to the destination variable for the memory region 64-bit physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_region_attr_get_physaddr_64(qurt_mem_region_attr_t *attr, qurt_paddr_64_t *addr_64){ + (*addr_64) = (unsigned long long)(((unsigned long long)(attr->ppn))<<12); +} + +/**@ingroup func_qurt_mem_map_static_query_64 + Determines if a memory page is statically mapped. + The following attributes specify pages: 64-bit physical address, page size, cache mode, + and memory permissions. \n + If the specified page is statically mapped, vaddr returns the virtual + address of the page. + If the page is not statically mapped (or if it does not exist as specified), vaddr + returns -1 as the virtual address value.\n + QuRT memory maps are defined in the system configuration file. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] vaddr Virtual address corresponding to paddr. + @param[in] paddr_64 64-bit physical address. + @param[in] page_size Size of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Specified page is statically mapped; a virtual address is returned in vaddr. \n + #QURT_EMEM -- Specified page is not statically mapped; -1 is returned in vaddr. \n + #QURT_EVAL -- Specified page does not exist. + + @dependencies + None. + */ +int qurt_mem_map_static_query_64(qurt_addr_t *vaddr, qurt_paddr_64_t paddr_64, unsigned int page_size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mem_region_query_64 + Determines whether a dynamically created memory region (Section @xref{sec:mem_region_create}) exists for the + specified virtual or physical address. When a memory region has been determined to exist, its attributes are + accessible (Section @xref{sec:mem_region_attr_get}). + + @note1hang This function returns QURT_EFATAL if #QURT_EINVALID is passed to both + vaddr and paddr (or to neither). + + @datatypes + #qurt_mem_region_t \n + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[out] region_handle Pointer to the memory region object (if it exists). + @param[in] vaddr Virtual address to query; if vaddr is specified, paddr must be set to + the value #QURT_EINVALID. + @param[in] paddr_64 64-bit physical address to query; if paddr is specified, vaddr must be set to + the value #QURT_EINVALID. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Region not found for the specified address. \n + #QURT_EFATAL -- Invalid input parameters. + + @dependencies + None. + */ +int qurt_mem_region_query_64(qurt_mem_region_t *region_handle, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64); + +/**@ingroup func_qurt_mapping_create_64 + @xreflabel{hdr:qurt_mapping_create_64} + Creates a memory mapping in the page table. + Not supported if called from a user process, always returns QURT_EMEM. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size (4K-aligned) of the mapped memory page. + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perm Access permissions. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Failure. + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + @dependencies + None. +*/ +int qurt_mapping_create_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, + qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perm); + +/**@ingroup func_qurt_mapping_remove_64 + @xreflabel{hdr:qurt_mapping_remove_64} + Deletes the specified memory mapping from the page table. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t \n + #qurt_size_t + + @param[in] vaddr Virtual address. + @param[in] paddr_64 64-bit physical address. + @param[in] size Size of the mapped memory page (4K-aligned). + + @return + #QURT_EOK -- Success. + #QURT_ELOCKED -- Buffer is locked. Mapping delete failed. + + @dependencies + None. + + */ +int qurt_mapping_remove_64(qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size); + +/**@ingroup func_qurt_lookup_physaddr_64 + Translates a virtual memory address to the 64-bit physical memory address it is mapped to. \n + The lookup occurs in the process of the caller. Use qurt_lookup_physaddr2() to lookup the physical + address of another process. + + @datatypes + #qurt_paddr_64_t \n + #qurt_addr_t + + @param[in] vaddr Virtual address. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address has not been mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr_64 (qurt_addr_t vaddr); +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_mapping_reclaim + Deallocates all QuRT resources associated with the specified virtual + memory area, making it available for user memory management:\n + - The associated physical memory areas are freed and added to the + specified physical pool.\n + - The associated TLB entries are deleted and made available for TLB + management.\n + - The virtual memory area is not freed -- it is left in + place as allocated, but unmapped virtual memory. Access to this + memory area generates an exception.\n + + The virtual memory area must be statically allocated. + If no pool is specified, the freed physical memory is not added to any pool. + + @note1hang The virtual memory area is restricted to being filled with locked + TLB entries that are contiguous within the memory area, and contained by it. + + @datatypes + #qurt_addr_t \n + #qurt_size_t \n + #qurt_mem_pool_t + + @param[in] vaddr Virtual address of the memory area to free. + @param[in] vsize Size (in bytes) of the memory area to free. + @param[in] pool Handle to the physical pool where freed physical memory is added. + If set to 0, freed physical memory is not added to any pool. + + @return + 0 -- Success. \n + Nonzero -- Failure that indicates a partial success, or that the request was malformed. \n @note1hang The expected behavior is that + QuRT logs messages related to the failure, and callers are free to ignore the return value. + + @dependencies + None. +*/ +int qurt_mapping_reclaim(qurt_addr_t vaddr, qurt_size_t vsize, qurt_mem_pool_t pool); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_mem_configure_cache_partition + Configures the Hexagon cache partition at the system level. + + A partition size value of #SEVEN_EIGHTHS_SIZE is applicable only to the L2 cache. + + The L1 cache partition is not supported in Hexagon processor version V60 or greater. + + @note1hang Call this operation only with QuRT OS privilege. + + @datatypes + #qurt_cache_type_t \n + #qurt_cache_partition_size_t + + @param[in] cache_type Cache type for partition configuration. Values: \n + - #HEXAGON_L1_I_CACHE \n + - #HEXAGON_L1_D_CACHE \n + - #HEXAGON_L2_CACHE @tablebulletend + + @param[in] partition_size Cache partition size. Values: \n + - #FULL_SIZE \n + - #HALF_SIZE \n + - #THREE_QUARTER_SIZE \n + - #SEVEN_EIGHTHS_SIZE @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Error. + + @dependencies + None. + */ +int qurt_mem_configure_cache_partition(qurt_cache_type_t cache_type, qurt_cache_partition_size_t partition_size); + + +/**@ingroup func_qurt_mem_syncht + @xreflabel{hdr:qurt_mem_syncht} + Performs heavy-weight synchronization of memory transactions. + + This operation does not return until all previous memory transactions (cached and uncached load/store, + mem_locked, and so on) that originated from the current thread are complete and globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon syncht instruction. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mem_syncht(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" SYNCHT \n"); + #endif +} + +/**@ingroup func_qurt_mem_barrier + @xreflabel{hdr:qurt_mem_barrier} + Creates a barrier for memory transactions. + + This operation ensures that all previous memory transactions are globally observable before any + future memory transactions are globally observable. + + @note1hang This operation is implemented as a wrapper for the Hexagon barrier instruction. + @return + None + + @dependencies + None. + */ +static inline void qurt_mem_barrier(void){ + #ifdef __HEXAGON_ARCH__ + __asm__ __volatile__ (" BARRIER \n"); + #endif +} +/** @endcond */ + +/** @cond internal_only */ +/**@ingroup func_qurt_system_mem_alloc + Requests that the kernel allocates memory from the kernel-owned pool. + + @param[in] size Size in bytes (aligned to 4K) to allocate. + @param[in] align Any alignment that must be considered for the allocation. + @param[in] flags Supports the #QURT_SYSTEM_ALLOC_VIRTUAL flag; allocates + available virtual memory in the address space of all processes. + + @return + #QURT_EFATAL -- Allocation failed \n + Start address of the successful allocation. + + @dependencies + None. +*/ +unsigned qurt_system_mem_alloc(unsigned size, unsigned align, unsigned flags); +/** @endcond */ +/** @cond rest_reg_dist*/ +/**@ingroup func_qurt_lookup_physaddr2 + Translates the virtual memory address of the specified process to the 64-bit + physical memory address to which it is mapped. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_64_t + + @param[in] vaddr Virtual address. + @param[in] pid PID. + + @return + Nonzero -- 64-bit physical address to which the virtual address is mapped. \n + 0 -- Virtual address is not mapped. + + @dependencies + None. +*/ +qurt_paddr_64_t qurt_lookup_physaddr2(qurt_addr_t vaddr, unsigned int pid); +/** @endcond */ + +/**@ingroup func_qurt_mapping_attr_get + Gets the mapping attributes for a given virtual address and PID + + @datatypes + #qurt_addr_t \n + #qurt_mapping_attr_t + + @param[in] vaddr virtual address for which the attributes are required. + @param[in] pid process id for the target process + @param[out] attr Pointer to the mapping attribute structure. + + @return + 0 -- Success. \n + #QURT_EINVALID -- Incorrect virtual address or pid +*/ +int qurt_mapping_attr_get(qurt_addr_t vaddr, unsigned int pid, qurt_mapping_attr_t *attr); + + +/**@ingroup func_qurt_mapping_attr_get_cache_mode + Gets the cache operation mode in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_mem_cache_mode_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] cache_mode Pointer to the destination variable for cache mode. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_cache_mode(qurt_mapping_attr_t *attr, qurt_mem_cache_mode_t *cache_mode) +{ + (*cache_mode) = attr->cache_mode; +} + +/**@ingroup func_qurt_mapping_attr_get_physaddr + Gets the physical memory address in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_paddr_64_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] physaddr Pointer to the destination variable for physical address. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_physaddr(qurt_mapping_attr_t *attr, qurt_paddr_64_t *physaddr) +{ + (*physaddr) = attr->paddr; +} + +/**@ingroup func_qurt_mapping_attr_get_perms + Gets the permissions in the specified memory mapping attribute structure. + + + @datatypes + #qurt_mapping_attr_t \n + #qurt_perm_t + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] perms Pointer to the destination variable for permissions. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_mapping_attr_get_perms(qurt_mapping_attr_t *attr, qurt_perm_t *perms) +{ + (*perms) = attr->perms; +} + +/**@ingroup func_qurt_mapping_attr_get_size + Gets the size in the specified memory mapping attribute structure.This represents size of the + TLB entry which covers the virtual address. + + + @datatypes + #qurt_mapping_attr_t \n + #unsigned int + + @param[in] attr Pointer to the memory mapping attribute structure. + @param[out] size Pointer to the destination variable for size. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_mapping_attr_get_size(qurt_mapping_attr_t *attr, unsigned int *size) +{ + (*size) = attr->size; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MEMORY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mmap.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mmap.h new file mode 100755 index 0000000000000..c3bd875910af7 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mmap.h @@ -0,0 +1,359 @@ +#ifndef QURT_MMAP_H +#define QURT_MMAP_H +/** + @file qurt_mmap.h + @brief Prototypes of memory mapping/unmapping APIs. + The APIs allow the user to map, un-map, and change permissions + on memory regions. + + EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2022, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_mem_mmap + Creates a memory mapping with the specified attributes. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that specifies a pool handle + if the user wants to allocate memory from a specific pool. + The default value for this argument is NULL. + @param[in] pRegion Map region. This argument is unused, and the default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + @param[in] flags Mapping modes.\n + - #QURT_MAP_NAMED_MEMSECTION + - #QURT_MAP_FIXED \n + - #QURT_MAP_NONPROCESS_VPOOL \n + - #QURT_MAP_TRYFIXED \n + - #QURT_MAP_ANON \n + - #QURT_MAP_PHYSADDR \n + - #QURT_MAP_VA_ONLY @tablebulletend + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap2 + Creates a memory mapping with the specified attributes. Returns a more descriptive + error code in case of failure. + This API allows the root process caller to create mapping on behalf of a user + process. If the client_handle belongs to a valid user process, the resulting + mapping is created for the process. + If -1 is passed in place of client_handle, the API creates mapping + for the underlying process of the caller. + + @note1hang If the specified attributes are not valid, an error result is returned. + + @param[out] client_handle Client handle to use for this mapping (optional). + @param[in] pool Optional argument that allows the user to specify a pool handle + when the user wants to allocate memory from a specific pool. + Default value for this argument is NULL. + @param[in] pRegion Map region (unused argument); default value is NULL. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode. + @param[in] flags Mapping modes; + Shared, Private, or Anonymous. + @param[in] fd File designator. + @param[in] offset Offset in file. + + @return + Valid virtual address -- Success.\n + #QURT_EMEM -- Physical address is not available. \n + #QURT_EFAILED -- VA is not available or mapping failed.\n + #QURT_EINVALID -- Invalid argument was passed (for example, an unaligned VA/PA). + */ +void *qurt_mem_mmap2(int client_handle, + qurt_mem_pool_t pool, + qurt_mem_region_t *pRegion, + void *addr, + size_t length, + int prot, + int flags, + int fd, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mmap_by_name + Creates a memory mapping for a named-memsection using the specified attributes. + The named memsection should be specified in cust_config.xml. + + @note1hang If the specified attributes are not valid or the named memsection is not found, + an error result is returned. + + @param[in] name Name of the memsection in cust_config.xml that specifies + this mapping. Should be less than 25 characters. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, bus attributes, User mode + @param[in] flags Mapping modes, such as + Shared, Private, or Anonymous. + @param[in] offset Offset relative to the physical address range specified in memsection. + If offset + length exceeds size of memsection, failure is + returned. + @return + Valid virtual address -- Success.\n + #QURT_MAP_FAILED -- Mapping creation failed. + */ +void *qurt_mem_mmap_by_name(const char* name, + void *addr, + size_t length, + int prot, + int flags, + unsigned long long offset); + +/**@ingroup func_qurt_mem_mprotect2 + Changes access permissions and attributes on an existing mapping based on the client_handle argument. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned. + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping.\n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect2(int client_handle, const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_mprotect + Changes access permissions and attributes on an existing mapping. + + @note1hang If the specified virtual address is not found or invalid attributes are passed, + an error code is returned.\n + + @note2 When error is returned, it is possible that attributes/permissions are changed for some part of the + mapping, while for the remaining it is unchanged. Clients should not use these mappings further. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] prot Mapping access permissions (R/W/X). + Cache attributes, Bus attributes, User mode. + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. \n + #QURT_EINVALID -- Attributes / permissions requested are invalid. + */ +int qurt_mem_mprotect(const void *addr, + size_t length, + int prot); + +/**@ingroup func_qurt_mem_munmap + Removes an existing mapping. + + @note1hang If the specified mapping is not found in the context of the caller process + or invalid attributes are passed, an error code is returned. + + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap(void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap2 + Removes an existing mapping for a specified process. + + @note1hang This API allows a root process entity, such as a driver, to remove mapping + that was created for a user process. If the specified mapping is not found in the context + of client handle or invalid attributes are passed, an error code is returned. + + @param[out] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Virtual memory address. + @param[in] length Size of mapping in bytes. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap2(int client_handle, + void *addr, + size_t length); + +/**@ingroup func_qurt_mem_munmap3 + Removes an existing mapping or reservation for a specified process. + + @param[in] client_handle Client handle of the user process that owns this mapping. + @param[in] addr Pointer to a virtual memory address. + @param[in] length Size of mapping in bytes. + @param[in] flags Specifies the flag. + + @return + #QURT_EOK -- Successfully changes permissions on the mapping. \n + #QURT_EFATAL -- Failed to change permissions on the mapping. + #QURT_ELOCKED - Buffer is locked. Mapping delete failed. + */ +int qurt_mem_munmap3(int client_handle, + void *addr, + size_t length, + int flags); + +/* +|| The macros here follow the style of the standard mmap() macros, but with +|| QURT_ prepended to avoid name conflicts, and to avoid having a dependency +|| on sys/mman.h. +|| +|| Wherever possible, any values here that are also present in sys/mman.h +|| should have the same value in both places so that we can accept "mmap" +|| calls without having to remap parameters to new values. +|| +|| In the future, it would be desirable to have a regression test that +|| checks, for instance, that these macros match. Example: +|| +|| assert(QURT_MAP_FAILED == MAP_FAILED); +|| ... repeat as needed ... +*/ + +/** @addtogroup memory_mapping_macros +@{ */ +/** @cond */ +#define QURT_PROT_NONE 0x00U /**< */ +#define QURT_PROT_READ 0x01U /**< */ +#define QURT_PROT_WRITE 0x02U /**< */ +#define QURT_PROT_EXEC 0x04U /**< */ +#define QURT_PROT_NODUMP 0x08U /**< Skip dumping the mapping. During PD dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and the DSP process + crashes before the mapping is removed.*/ +#define QURT_PROT_ISLAND 0x10U /**< Island mapping. */ + +#define QURT_MAP_SHARED 0x0001U /**< Shared. */ +#define QURT_MAP_PRIVATE 0x0002U /**< Private. */ +/** @endcond */ +#define QURT_MAP_NAMED_MEMSECTION 0x0004U /**< Named memsection. */ +#define QURT_MAP_FIXED 0x0010U /**< Fixed virtual address. */ +#define QURT_MAP_RENAME 0x0020U /**< Rename. */ +#define QURT_MAP_NORESERVE 0x0040U /**< No reserve. */ +#define QURT_MAP_INHERIT 0x0080U /**< Inherit. */ +#define QURT_MAP_NONPROCESS_VPOOL 0x0100U /**< Use a virtual address outside of the default range of the + processes. This option is only supported in the root process + and only when virtual memory split is enabled in the XML. + The root process can use this flag to create mapping for a + user process, for example, if the virtual address is configured + for a 3G/1G split, the root process can use this flag to create + mapping in the top 1 GB area for the user process or the + lower 3 GB area for the root process. This is useful for + shared buffer use cases. */ +#define QURT_MAP_HASSEMAPHORE 0x0200U /**< Has semaphore. */ +#define QURT_MAP_TRYFIXED 0x0400U /**< Try to create a mapping for a virtual address that was passed. + If the passed virtual address fails, use a random virtual address. */ +#define QURT_MAP_WIRED 0x0800U /**< Wired. */ +#define QURT_MAP_FILE 0x0000U /**< File. */ +#define QURT_MAP_ANON 0x1000U /**< Allocate physical memory from the pool that was passed. + By default, memory is allocated from the default physpool. */ +#define QURT_MAP_VA_ONLY 0X2000U /**< Reserve a virtual address without + mapping it. */ + +/** @cond */ +#define QURT_MAP_ALIGNED(n) ((n) << QURT_MAP_ALIGNMENT_SHIFT) +#define QURT_MAP_ALIGNMENT_SHIFT 24 + + +#define QURT_MAP_ALIGNMENT_MASK QURT_MAP_ALIGNED(0xff) /**< */ +#define QURT_MAP_ALIGNMENT_64KB QURT_MAP_ALIGNED(16) /**< */ +#define QURT_MAP_ALIGNMENT_16MB QURT_MAP_ALIGNED(24) /**< */ +#define QURT_MAP_ALIGNMENT_4GB QURT_MAP_ALIGNED(32) /**< */ +#define QURT_MAP_ALIGNMENT_1TB QURT_MAP_ALIGNED(40) /**< */ +#define QURT_MAP_ALIGNMENT_256TB QURT_MAP_ALIGNED(48) /**< */ +#define QURT_MAP_ALIGNMENT_64PB QURT_MAP_ALIGNED(56) /**< */ +/** @endcond */ +#define QURT_MAP_FAILED ((void *) -1) /**< Mapping creation failed. */ + +/* +|| The macros below are extensions beyond the standard mmap flags, but follow +|| the style of the mmap flags. +*/ +/** @cond */ +// Describe bitfields in (prot) +#define QURT_PROT_CACHE_BOUNDS 16U,19U,7U /**< Bits 16 through 19 are cache attribute, default is 0. */ +#define QURT_PROT_BUS_BOUNDS 20U,21U,0U /**< Bits 20 through 21 are bus attributes, default is 0. */ +#define QURT_PROT_USER_BOUNDS 22U,23U,3U /**< Bits 22 through 23 are user mode, default is 3; + default of 3 means to derive user mode setting from the + default mode of the client. */ + +// Describe bitfields in (flags) +#define QURT_MAP_PHYSADDR_BOUNDS 15U,15U,0U /**< Bits 15 through 15 are physaddr, default is 0. */ +#define QURT_MAP_TYPE_BOUNDS 16U,19U,0U /**< Bits 16 through 19 are mapping type, default is 0. */ +#define QURT_MAP_REGION_BOUNDS 20U,23U,0U /**< Bits 20 through 23 are region type, default is 0. */ +/** @endcond */ + +// These macros get OR'ed into (prot) +#define QURT_PROT_CACHE_MODE(n) QURT_MMAP_BUILD(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_BUS_ATTR(n) QURT_MMAP_BUILD(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_USER_MODE(n) QURT_MMAP_BUILD(QURT_PROT_USER_BOUNDS,(n)) /**< */ +// These macros get OR'ed into (flags) + +#define QURT_MAP_PHYSADDR QURT_MMAP_BUILD(QURT_MAP_PHYSADDR_BOUNDS,1U) /**< Use the physical address that was passed in offset field. + This is allowed only for root process. */ +#define QURT_MAP_TYPE(n) QURT_MMAP_BUILD(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_REGION(n) QURT_MMAP_BUILD(QURT_MAP_REGION_BOUNDS,(n)) /**< */ +/** @} */ /* end_addtogroup memory_mapping_macros */ +/** @cond */ +// These macros extract fields from (prot) +#define QURT_PROT_GET_CACHE_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_CACHE_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_BUS_ATTR(n) QURT_MMAP_EXTRACT(QURT_PROT_BUS_BOUNDS,(n)) /**< */ +#define QURT_PROT_GET_USER_MODE(n) QURT_MMAP_EXTRACT(QURT_PROT_USER_BOUNDS,(n)) /**< */ + +// These macros extract fields from (flags) +#define QURT_MAP_GET_TYPE(n) QURT_MMAP_EXTRACT(QURT_MAP_TYPE_BOUNDS,(n)) /**< */ +#define QURT_MAP_GET_REGION(n) QURT_MMAP_EXTRACT(QURT_MAP_REGION_BOUNDS,(n)) /**< */ + +// Macros for bitfield insertion and extraction +#define QURT_MMAP_MASK(lo,hi) (~((~0u) << ((hi)-(lo)+1U))) /**< Mask of same size as [lo..hi]. */ +#define QURT_MMAP_BUILD_(lo,hi,def,n) ((((n)^(def))&QURT_MMAP_MASK((lo),(hi)))<<(lo)) /**< */ +#define QURT_MMAP_EXTRACT_(lo,hi,def,n) ((((n)>>(lo))&QURT_MMAP_MASK((lo),(hi)))^(def)) /**< */ +#define QURT_MMAP_BUILD(a,b) QURT_MMAP_BUILD_(a,b) /**< */ +#define QURT_MMAP_EXTRACT(a,b) QURT_MMAP_EXTRACT_(a,b) /**< */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mq.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mq.h new file mode 100755 index 0000000000000..580c83d3de41a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mq.h @@ -0,0 +1,458 @@ +#ifndef QURT_MQ_H +#define QURT_MQ_H +/** + @file qurt_mq.h + + @brief Prototypes of secure message queues API functions. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2019-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. +======================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_MQ_NAME_MAXLEN 16U /**< Maximum name length. */ + + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/* This enum must be generated in accordance to process class class numbers. + For now it is made to match generated version, do not change this unless + there is a corresponding change in the process_class.py, indicies start from 0 + basically: QURT_MQ_SECURITY_SCOPE_ = (1 << QURTK_process_class_index_) +*/ +typedef enum { + QURT_MQ_SECURITY_SCOPE_KERNEL = ( 1U << 0 ), + QURT_MQ_SECURITY_SCOPE_SRM = ( 1U << 1 ), + QURT_MQ_SECURITY_SCOPE_SECURE = ( 1U << 2 ), + QURT_MQ_SECURITY_SCOPE_CPZ = ( 1U << 3 ), + QURT_MQ_SECURITY_SCOPE_ROOT = ( 1U << 4 ), + QURT_MQ_SECURITY_SCOPE_SIGNED = ( 1U << 5 ), + QURT_MQ_SECURITY_SCOPE_UNSIGNED = ( 1U << 6 ), + QURT_MQ_SECURITY_SCOPE_SECURE_ROOT = ( 1U << 7 ) +} qurt_mq_security_scope_t; + +typedef enum { + QURT_MQ_CARDINALITY_PTP = (1U << 0), + QURT_MQ_CARDINALITY_MTO = (1U << 1) +}qurt_mq_cardinality_t; + +typedef unsigned int qurt_mqd_t; + +typedef union{ + struct { + unsigned int perms:2; + unsigned int cardinality:1; + unsigned int blocking:1; + + qurt_mq_security_scope_t creator_scope: 8; + qurt_mq_security_scope_t allowed_scope: 8; //can be a bitmask in case of MTO + unsigned int queue_closed: 1; + unsigned int reserved: 11; + }; //try to do anonymous struct + unsigned int raw; +} qurt_mq_flags_t; + + +/* permissions are from qurt_types.h , block X though */ +#if 0 +/** Memory access permission. */ +typedef enum { + QURT_PERM_READ=0x1U, /**< */ + QURT_PERM_WRITE=0x2U, /**< */ + QURT_PERM_EXECUTE=0x4U, /**< */ + QURT_PERM_FULL=QURT_PERM_READ|QURT_PERM_WRITE|QURT_PERM_EXECUTE, /**< */ +} qurt_perm_t; +#endif + +struct qurt_mq_attr { + unsigned flags; /**< Configured flags. Only meaningful with get_attr(), only used for qurt_mq_flags_t.perms. */ + unsigned mq_maxmsg; /**< Maximum number of messages. Used with create() and get_attr. */ + unsigned short mq_send_msgsize; /**< Maximum size (bytes) of message in receiver facing queue, + from sender to receiver. */ + unsigned short mq_recv_msgsize; /**< Maximum size (bytes) of message in sender facing queue, + from receiver to sender. */ + unsigned client_pid; /**< Process ID of client that is allowed to open the message queue + that was created using qurt_mq_create(). */ + qurt_mq_cardinality_t cardinality; /**< Cardinality of message queue connection, see below. */ + qurt_mq_security_scope_t scope; /**< Security scope of the senders to the queue. */ +}; + + +/*============================================================================= + EXTERNS & FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mq_attr_init + Initializes attributes to default values used for creating the queue. + + The initialize operation sets the following default attribute values: \n + - flag - QURT_PERM_READ | QURT_PERM_WRITE \n + - maxmsg - 1 \n + - mq_send_msgsize - 8 \n + - mq_recv_msgsize - 8 \n + - sender_pid - -1 \n + - cardinality - QURT_MQ_CARDINALITY_PTP \n + - scope - QURT_MQ_SECURITY_SCOPE_SIGNED \n + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the initialized message queue object. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_init(struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_attr_set_send_msgsize + Sets the message size in bytes the sender can send. + Maximum message length is configurable using the XML configuration, however, limited to a maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_send_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_recv_msgsize + Sets the message size in bytes that the receiver can read. + Maximum message length is configurable using the XML configuration, however, limited to maximum value of 62 bytes. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] len Length of message in bytes. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_recv_msgsize (struct qurt_mq_attr *attr, size_t len); + +/**@ingroup qurt_mq_attr_set_maxmsg + Sets the maximum message that can queue in the message queue. + Message depth is configurable using the XML configuration. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] depth Maximum message that can be queued. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_maxmsg (struct qurt_mq_attr *attr, unsigned int depth); + +/**@ingroup qurt_mq_attr_set_scope + Sets the scope of the message queue. A message queue created with a security + scope allows only a process class of that scope to open a message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mq_security_scope_t + + @param[in,out] attr Pointer to the message queue object. + @param[in] scope Scope of the message queue: \n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_scope (struct qurt_mq_attr *attr, qurt_mq_security_scope_t scope); + + +/**@ingroup qurt_mq_attr_set_client_pid + Sets the client_pid that can open this message queue. + If client_pid is set, allowed_scope to open MQ shall not be considered. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] client_pid Valid PID for client process. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_client_pid (struct qurt_mq_attr *attr, unsigned client_pid); + +/**@ingroup qurt_mq_attr_set_flags + Sets the properties of the message queues. + The current implementation is only used to set the permission for the message queue using the flag attribute. + Default is #QURT_PERM_READ | #QURT_PERM_WRITE, explicit permission is not implemented. + + @datatypes + #qurt_mq_attr + + @param[in,out] attr Pointer to the message queue object. + @param[in] flags Permission for message queue. + + @return + None. + + @dependencies + None. +*/ +void qurt_mq_attr_set_flags (struct qurt_mq_attr *attr, unsigned int flags); + +/**@ingroup qurt_mq_create + Create a message queue with the provided name and attributes. + The calling process becomes the owner of the queue. + Name of the message queue is limited to 16 characters including the NULL terminator. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue identifier if + the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] attr Pointer to the initialized message queue attribute + structure that specifies the attributes of the created message queue. + + @return + #QURT_EOK Message queue created. \n + #QURT_EINVALID Invalid arguments. \n + #QURT_ENOSPC Maximum number of queues in the system is exceeded. + + @dependencies + None. +*/ +int qurt_mq_create(qurt_mqd_t *mqd, const char *name, struct qurt_mq_attr * attr); + +/**@ingroup qurt_mq_open + Opens a message queue connection between a process and a created message queue. + + @datatypes + #qurt_mq_attr \n + #qurt_mqd_t + + @param[out] mqd Returns a pointer to the message queue + identifier if the message queue was successfully created. + @param[in] name String identifier of the message queue. + @param[in] flags Flag that contains the properties that define the behavior of message queue connection. + Permissions:\n + #QURT_PERM_READ \n + #QURT_PERM_WRITE \n + #QURT_PERM_READ | QURT_PERM_WRITE @tablebulletend + Default is QURT_PERM_READ | QURT_PERM_WRITE, explicit permission is not implemented \n + Cardinality: \n + #QURT_MQ_CARDINALITY_PTP (default) \n + #QURT_MQ_CARDINALITY_MTO (not implemented) \n + Block suspend thread until the message queue with the apecified name is created. \n + Scope: security boundary to which the message queue and its users are constrained. + Block suspend thread until the message queue with the apecified name is created. \n + It is coupled with process privilege level/scope.\n + #QURT_MQ_SECURITY_SCOPE_KERNEL \n + #QURT_MQ_SECURITY_SCOPE_SRM \n + #QURT_MQ_SECURITY_SCOPE_SECURE \n + #QURT_MQ_SECURITY_SCOPE_CPZ \n + #QURT_MQ_SECURITY_SCOPE_ROOT \n + #QURT_MQ_SECURITY_SCOPE_SIGNED \n + #QURT_MQ_SECURITY_SCOPE_UNSIGNED @tablebulletend + + @return + QURT_EOK -- Message queue connection successfully opened \n + QURT_EFAILED -- Message queue connection failed , if non-blocking message queue \n + QURT_ENOTALLOWED -- Open failed due to security scope mismatch + + @dependencies + None. +*/ +int qurt_mq_open (qurt_mqd_t *mqd, const char *name, qurt_mq_flags_t flags); + +/**@ingroup qurt_mq_send + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send shall resume that thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] msg_len Length of the message buffer in bytes. + + @return + #QURT_EOK Message queue send was successful.\n + #QURT_EMSGSIZE Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED Send failed due to security scope mismatch. + + @dependencies + None. +*/ +int qurt_mq_send(qurt_mqd_t mqd, const char *msg_ptr, size_t msg_len); + +/**@ingroup qurt_mq_send_timed + Sends a message over message queue.\n + - If the message queue is full, the calling thread shall be + suspended until space becomes available to enqueue the message or until timeout is reached. \n + - If there exists a thread suspended on an empty queue + to receive a message, qurt_mq_send_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_send_timed shall return #QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer. + @param[in] duration Interval (in microseconds) that the duration value must be + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in] msg_len Length of message buffer in bytes. + + @return + #QURT_EOK -- Message queue send was successful. \n + #QURT_EMSGSIZE -- Message size in msg_len field is greater than max_message_len specified during queue creation.\n + #QURT_ENOTALLOWED -- Send failed due to security scope mismatch \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. +*/ +int qurt_mq_send_timed(qurt_mqd_t mqd, const char *msg_ptr, unsigned long long int duration, size_t msg_len); + + /**@ingroup qurt_mq_recv + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue. \n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv shall resume the thread. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in,out] msg_len Pointer to the length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID Message pointer or msg_len ptr are NULL. \n + #QURT_EBADR Message queue descriptior (mqd) is invalid. \n + #QURT_EBADF Sender closed the message queue. + + @dependencies + None. +*/ +int qurt_mq_recv(qurt_mqd_t mqd, unsigned char *msg_ptr, size_t *msg_len); + + /**@ingroup qurt_mq_recv_timed + Receives a message from the message queue. \n + -If the message queue is empty, the calling thread shall be + suspended until a message is enqueued in the message queue or until timeout is reached.\n + -If there exists a thread suspended on a full queue to + send a message, qurt_mq_recv_timed shall return with possible return codes.\n + - If timeout is reached, qurt_mq_recv_timed shall return QURT_ETIMEOUT. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + @param[in] msg_ptr Pointer to the message buffer + @param[in] duration Interval (in microseconds) that the duration value must be; + between #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION + @param[in,out] msg_len Pointer to length of message buffer. + + @return + #QURT_EOK -- Message queue created.\n + #QURT_EINVALID -- Message ptr or msg_len ptr are NULL. \n + #QURT_EBADR -- Message queue descriptior (mqd) is invalid.\n + #QURT_EBADF -- Sender closed the message queue. \n + #QURT_ETIMEDOUT -- Timeout. + + @dependencies + None. +*/ +int qurt_mq_recv_timed(qurt_mqd_t mqd, unsigned char *msg_ptr, unsigned long long int duration, size_t *msg_len); + + /**@ingroup qurt_mq_close + Closes the message queue and disassociates the calling process (client) from the message queue + under this descriptor. Marks the queue as closed for the receiver. + This function is expected to be called from the client side. If called + from the server side, the function reduces to no-op and returns success. + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue close was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_close(qurt_mqd_t mqd); + + /**@ingroup qurt_mq_destroy + Destroys the message queue. This function ought to be + called from the process that called qurt_mq_create(). + + @datatypes + #qurt_mqd_t + + @param[in] mqd Pointer to the message queue identifier. + + @return + #QURT_EOK -- Message queue destroy was successfully.\n + #QURT_EBADR -- Invalid descriptor.\n + #QURT_ENOTALLOWED -- Message queue close is not called from client side. + + @dependencies + None. +*/ +int qurt_mq_destroy(qurt_mqd_t mqd); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif //QURT_MQ_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mutex.h new file mode 100755 index 0000000000000..4ad6b270cdde6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_mutex.h @@ -0,0 +1,211 @@ +#ifndef QURT_MUTEX_H +#define QURT_MUTEX_H +/** + @file qurt_mutex.h + @brief Prototypes of mutex API. + This is mostly a user space mutex, but calls the + kernel to block if the mutex is taken. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT mutex type. + + Both non-recursive mutex lock and unlock, and recursive + mutex lock and unlock can be applied to this type. + */ +typedef union qurt_mutex_aligned8{ + /** @cond */ + struct { + unsigned int holder; + unsigned int count; + unsigned int queue; + unsigned int wait_count; + }; + unsigned long long int raw; + /** @endcond */ +} qurt_mutex_t; +/** @} */ /* end_addtogroup mutex_types */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/* @addtogroup mutex_const_macros +@{ */ +#define MUTEX_MAGIC 0xfe /**< */ +#define QURTK_FUTEX_FREE_MAGIC 0x1F // 11111 /**< */ +#define QURT_MUTEX_INIT {{MUTEX_MAGIC, 0, QURTK_FUTEX_FREE_MAGIC,0}} /**< Suitable as an initializer for a + variable of type qurt_mutex_t. */ +/* @} */ /* end_addtogroup mutex_const_macros */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_mutex_init + Initializes a mutex object. + The mutex is initially unlocked. + + @note1hang Each mutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_mutex_destroy() + when this object is not used anymore + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the mutex object. Returns the initialized object. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_destroy + Destroys the specified mutex. + + @note1hang Mutexes must be destroyed when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Mutexes must not be destroyed while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_mutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_mutex_lock + Locks the specified mutex. + If a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. + + @note1hang A thread is suspended indefinitely if it locks a mutex that it has already + locked. Avoid this by using recursive mutexes (Section @xref{dox:recursive_mutexes}). + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_lock(qurt_mutex_t *lock); /* blocking */ + +/**@ingroup func_qurt_mutex_lock_timed + Locks the specified mutex. + When a thread performs a lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + When a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared + resource. If the duration of suspension exceeds the timeout duration, wait is + terminated and no access to mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object; specifies the mutex to lock. + @param[in] duration Interval (in microseconds) that the duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_mutex_lock_timed (qurt_mutex_t * lock, unsigned long long int duration); + +/**@ingroup func_qurt_mutex_unlock + Unlocks the specified mutex. \n + More than one thread can be suspended on a mutex. When the mutex is unlocked, only the + highest-priority thread waiting on the mutex is awakened. If the awakened thread has + higher priority than the current thread, a context switch occurs. + + @note1hang The behavior of QuRT is undefined if a thread unlocks a mutex it did not first + lock. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to unlock. + + @return + None. + + @dependencies + None. + */ +void qurt_mutex_unlock(qurt_mutex_t *lock); /* unlock */ + +/**@ingroup func_qurt_mutex_try_lock + @xreflabel{hdr:qurt_mutex_try_lock} + Attempts to lock the specified mutex. + If a thread performs a try_lock operation on a mutex that is not in use, the thread gains + access to the shared resource that is protected by the mutex, and continues executing. + + @note1hang If a thread performs a try_lock operation on a mutex that it has already locked + or is in use by another thread, qurt_mutex_try_lock immediately returns with a + nonzero result value. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object. Specifies the mutex to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_mutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_MUTEX_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_os_services.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_os_services.h new file mode 100755 index 0000000000000..cbc4c239e9620 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_os_services.h @@ -0,0 +1,24 @@ +/*============================================================================= + + qurt_os_services.c + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ + +#define QURT_OS_SERVICE_THREAD "/os/thread" /**< Thread service */ +#define QURT_OS_SERVICE_FS_HUB "/os/fs_hub" /**< file-system hub */ +#define QURT_OS_SERVICE_CALLBACK "/os/callback" /**< QDI callback service */ +#define QURT_OS_SERVICE_INTERRUPTS "/os/interrupt" /**< Interrupt service */ +#define QURT_OS_SERVICE_PROXY "/os/proxy" /**< QDI proxy serice */ +#define QURT_OS_SERVICE_MEMORY "/os/memory" /**< Memory management service */ +#define QURT_OS_SERVICE_MEMPOOL "/os/mempool" /**< Pool management service */ +#define QURT_OS_SERVICE_PROCESS "/os/process" /**< Process management service */ +#define QURT_OS_SERVICE_MMAP "/os/mem_mapper" /**< mmapper service */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex.h new file mode 100755 index 0000000000000..61aee5cba7ce8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_PIMUTEX_H +#define QURT_PIMUTEX_H 1 +/** + @file qurt_pimutex.h + @brief Prototypes of qurt_pimutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pimutex_init + Initializes a priority inheritance mutex object. + The priority inheritance mutex is initially unlocked. + + This function works the same as qurt_mutex_init(). + + @note1hang Each pimutex-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_pimutex_destroy() + when this object is not used anymore + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the priority inheritance mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_destroy + Destroys the specified priority inheritance mutex. + + @note1hang Priority inheritance mutexes must be destroyed when they are no longer in + use. Failure to do this causes resource leaks in the QuRT kernel.\n + @note1cont Priority inheritance mutexes must not be destroyed while they are still in use. + If this occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_lock + Requests access to a shared resources. If a thread performs a lock operation on a mutex + that is not in use, the thread gains access to the shared resource that the mutex protects, + and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + If a thread is suspended on a priority inheritance mutex, and the priority of the suspended + thread is higher than the priority of the thread that has locked the mutex, the thread + with the mutex acquires the higher priority of the suspended thread. The locker thread blocks + until the lock is available. + + @note1hang A thread is not suspended if it locks a priority inheritance mutex that it has + already locked . However, the mutex does not become available to other + threads until the thread performs a balanced number of unlocks on the mutex.\n + @note1cont When multiple threads compete for a mutex, the lock operation for a priority + inheritance mutex is slower than it is for a recursive mutex. + In particular, it is about 10 times slower when the mutex is available for locking, + and slower (with greatly varying times) when the mutex is already locked. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_lock(qurt_mutex_t *lock); + + +/**@ingroup func_qurt_pimutex_lock_timed + Locks a priority inheritance mutex with timeout. + + A thread can lock a priority inheritance mutex for multiple times. The mutex is not + available to other threads until the thread performs the same number of mutex unlock + operations. + + If a thread performs a lock operation on a mutex that is already locked by another thread, + the thread is moved to waiting state. When the mutex becomes available again (because the + other thread has unlocked the mutex), the thread is awakened and tries to lock the mutex. + + If a thread is waiting on a priority inheritance mutex, and the priority of the waiting thread + is higher than the priority of the thread that has locked the mutex, the priority of the thread + that has locked the mutex is raised to the same priority of the waiting thread. + + If the duration of waiting exceeds the timeout duration, the waiting is terminated, and + the function returns QURT_ETIMEDOUT as a failure of the mutex lock. + + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the mutex object to lock. + @param[in] duration Duration (in microseconds) to wait. The duration value must be between + #QURT_TIMER_MIN_DURATION and #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + #QURT_EINVALID -- Duration is out of range + + @dependencies + None. + + */ +int qurt_pimutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + + +/**@ingroup func_qurt_pimutex_unlock + Releases access to a shared resource; unlocks the specified priority inheritance mutex. \n + More than one thread can be suspended on a priority inheritance mutex. When the mutex + is unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + When a thread unlocks a priority inheritance mutex, its thread priority is restored to its + original value from any higher priority value that it acquired from another thread + suspended on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_pimutex_try_lock + Request access to a shared resource (without suspend). Attempts to lock the specified priority inheritance mutex.\n + If a thread performs a try_lock operation on a priority inheritance mutex that is not in + use, the thread gains access to the shared resource that is protected by the mutex, and + continues executing. + If a thread performs a try_lock operation on a priority inheritance mutex that is already + in use by another thread, qurt_pimutex_try_lock immediately returns with a + nonzero result value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the priority inheritance mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_pimutex_try_lock(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex2.h new file mode 100755 index 0000000000000..b809f163cbfd2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pimutex2.h @@ -0,0 +1,162 @@ +#ifndef QURT_PIMUTEX2_H +#define QURT_PIMUTEX2_H +/** + @file qurt_pimutex2.h + @brief Prototypes of pimutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_pimutex2_init + Initializes a recursive mutex object. + + @deprecated use #qurt_pimutex_init instead. + + The recursive mutex is initially unlocked. + + Objects of type pimutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_destroy + + @deprecated use #qurt_pimutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1cont Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code should destroy an pimutex2 object prior to + deallocating it; calling qurt_pimutex2_destroy() before deallocating it ensures + that all qurt_pimutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_lock + + @deprecated use #qurt_pimutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not being used, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing. + + If a thread performs a lock operation on a recursive mutex that is already being used by + another thread, the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_pimutex2_unlock + + @deprecated use #qurt_pimutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex is awakened. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_pimutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_pimutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_pimutex2_lock(). If a call to qurt_pimutex2_lock() would + succeed immediately, this function behaves similarly, and returns 0 for success. + If a call to qurt_pimutex2_lock() would not succeed immediately, this function has + no effect and returns non-zero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_pimutex2_try_lock(qurt_rmutex2_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pipe.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pipe.h new file mode 100755 index 0000000000000..6bdaa044f8640 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pipe.h @@ -0,0 +1,479 @@ +#ifndef QURT_PIPE_H +#define QURT_PIPE_H +/** + @file qurt_pipe.h + @brief Prototypes of the pipe interface API + This is a pipe or message queue + It blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021,2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup pipe_types +@{ */ +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define QURT_PIPE_MAGIC 0xF1FEF1FE /**< Magic. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_RAM 0 /**< RAM. */ +#define QURT_PIPE_ATTR_MEM_PARTITION_TCM 1 /**< TCM. */ + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** QuRT pipe data values type. */ +typedef unsigned long long int qurt_pipe_data_t; + +/** QuRT pipe type.*/ +typedef struct { + /** @cond */ + qurt_mutex_t pipe_lock; + qurt_sem_t senders; + qurt_sem_t receiver; + unsigned int size; + unsigned int sendidx; + unsigned int recvidx; + void (*lock_func)(qurt_mutex_t *); + void (*unlock_func)(qurt_mutex_t *); + int (*try_lock_func)(qurt_mutex_t *); + void (*destroy_lock_func)(qurt_mutex_t *); + unsigned int magic; + qurt_pipe_data_t *data; + /** @endcond */ +} qurt_pipe_t; + +/** QuRT pipe attributes type. */ +typedef struct { + /** @cond */ + qurt_pipe_data_t *buffer; + unsigned int elements; + unsigned char mem_partition; + /** @endcond */ +} qurt_pipe_attr_t; + +/** @} */ /* end_addtogroup pipe_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_pipe_attr_init + @xreflabel{hdr:qurt_pipe_attr_init} + Initializes the structure that sets the pipe attributes when a pipe is created. + + After an attribute structure is initialized, the individual attributes in the structure are + explicitly set using the pipe attribute operations. + + The attribute structure is assigned the following default values: \n + - buffer -- 0 \n + - elements -- 0 \n + - mem_partition -- #QURT_PIPE_ATTR_MEM_PARTITION_RAM + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_init(qurt_pipe_attr_t *attr) +{ + attr->buffer = NULL; + attr->elements = 0; + attr->mem_partition = QURT_PIPE_ATTR_MEM_PARTITION_RAM; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer + @xreflabel{sec:qurt_pipe_attr_set_buffer} + Sets the pipe buffer address attribute.\n + Specifies the base address of the memory area to use for the data buffer of a pipe. + + The base address and size (Section @xref{sec:qurt_pipe_attr_set_elements}) specify the + memory area used as a pipe data buffer. The user is responsible for allocating the + memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t \n + #qurt_pipe_data_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] buffer Pointer to the buffer base address. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer(qurt_pipe_attr_t *attr, qurt_pipe_data_t *buffer) +{ + attr->buffer = buffer; +} + +/**@ingroup func_qurt_pipe_attr_set_elements + @xreflabel{sec:qurt_pipe_attr_set_elements} + Specifies the length of the memory area to use for the data buffer of a pipe. + + The length is expressed in terms of the number of 64-bit data elements that + can be stored in the buffer. + + The base address (Section @xref{sec:qurt_pipe_attr_set_buffer}) and size specify + the memory area used as a pipe data buffer. The user is responsible for + allocating the memory area used for the buffer. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] elements Pipe length (64-bit elements). + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_elements(qurt_pipe_attr_t *attr, unsigned int elements) +{ + attr->elements = elements; +} + +/**@ingroup func_qurt_pipe_attr_set_buffer_partition + @xreflabel{sec:qurt_pipe_attr_set_buffer_partition} + Specifies the memory type where a pipe's buffer is allocated. + Allocate pipes in RAM or TCM/LPM. + + @note1hang If a pipe is specified as allocated in TCM/LPM, it must be created + with the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_attr_t + + @param[in,out] attr Pointer to the pipe attribute structure. + @param[in] mem_partition Pipe memory partition. Values: \n + - #QURT_PIPE_ATTR_MEM_PARTITION_RAM -- Pipe resides in RAM \n + - #QURT_PIPE_ATTR_MEM_PARTITION_TCM -- Pipe resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_pipe_attr_set_buffer_partition(qurt_pipe_attr_t *attr, unsigned char mem_partition) +{ + attr->mem_partition = mem_partition; +} + +/**@ingroup func_qurt_pipe_create + Creates a pipe.\n + Allocates a pipe object and its associated data buffer, and initializes the pipe object. + + @note1hang The buffer address and size stored in the attribute structure specify how the + pipe data buffer is allocated. + + @note1cont If a pipe is specified as allocated in TCM/LPM, it must be created + using the qurt_pipe_init() operation. The qurt_pipe_create() operation results in an error. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the created pipe object. + @param[in] attr Pointer to the attribute structure used to create the pipe. + + @return + #QURT_EOK -- Pipe created. \n + #QURT_EFAILED -- Pipe not created. \n + #QURT_ENOTALLOWED -- Pipe cannot be created in TCM/LPM. + + @dependencies + None. + */ +int qurt_pipe_create(qurt_pipe_t **pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_init + Initializes a pipe object using an existing data buffer. + + @note1hang The buffer address and size stored in the attribute structure must + specify a data buffer that the user has already allocated. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_attr_t + + @param[out] pipe Pointer to the pipe object to initialize. + @param[in] attr Pointer to the pipe attribute structure used to initialize the pipe. + + @return + #QURT_EOK -- Success. \n + #QURT_EFAILED -- Failure. + + @dependencies + None. + */ +int qurt_pipe_init(qurt_pipe_t *pipe, qurt_pipe_attr_t *attr); + +/**@ingroup func_qurt_pipe_destroy + @xreflabel{sec:qurt_pipe_destroy} + Destroys the specified pipe. + + @note1hang Pipes must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel. + Pipes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_destroy(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_delete + Deletes the pipe.\n + Destroys the specified pipe (Section @xref{sec:qurt_pipe_destroy}) and deallocates the pipe object and its + associated data buffer. + + @note1hang Delete pipes only if they were created using qurt_pipe_create + (and not qurt_pipe_init). Otherwise the behavior of QuRT is undefined. \n + @note1cont Pipes must be deleted when they are no longer in use. Failure to do this + causes resource leaks in the QuRT kernel.\n + @note1cont Pipes must not be deleted while they are still in use. If this occurs, the + behavior of QuRT is undefined. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_pipe_delete(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_send + Writes a data item to the specified pipe. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + None. + + @dependencies + None. +*/ +void qurt_pipe_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_receive + Reads a data item from the specified pipe. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + Integer containing the 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_receive(qurt_pipe_t *pipe); + +/**@ingroup func_qurt_pipe_try_send + Writes a data item to the specified pipe (without suspending the thread if the pipe is full).\n + + If a thread writes to a full pipe, the operation returns immediately with success set to -1. + Otherwise, success is always set to 0 to indicate a successful write operation. + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to write to. + @param[in] data Data item to write. + + @return + 0 -- Success. \n + -1 -- Failure (pipe full). + + @dependencies + None. +*/ +int qurt_pipe_try_send(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_try_receive + Reads a data item from the specified pipe (without suspending the thread if the pipe is + empty).\n + If a thread reads from an empty pipe, the operation returns immediately with success set + to -1. Otherwise, success is always set to 0 to indicate a successful read operation.\n + + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[out] success Pointer to the operation status result. + + @return + Integer containing a 64-bit data item from pipe. + + @dependencies + None. +*/ +qurt_pipe_data_t qurt_pipe_try_receive(qurt_pipe_t *pipe, int *success); + +/**@ingroup func_qurt_pipe_receive_cancellable + Reads a data item from the specified pipe (with suspend), cancellable. + + If a thread reads from an empty pipe, it is suspended on the pipe. When another thread + writes to the pipe, the suspended thread is awakened and can then read data from the pipe. + The operation is cancelled if the user process of the calling thread is killed, + or if the calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + Pipe data items are defined as 64-bit values. Pipe reads are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] result Pointer to the integer containing the 64-bit data item from pipe. + + @return + #QURT_EOK -- Receive completed. \n + #QURT_ECANCEL -- Receive canceled. \n + #QURT_EDESTROY -- Receive destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_receive_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t *result); + +/**@ingroup func_qurt_pipe_send_cancellable + @xreflabel{hdr:qurt_pipe_send_cancellable} + Writes a data item to the specified pipe (with suspend), cancellable. \n + If a thread writes to a full pipe, it is suspended on the pipe. When another thread reads + from the pipe, the suspended thread is awakened and can then write data to the pipe. + The operation is canceled if the user process of the calling thread is killed, or if the + calling thread must finish its current QDI invocation and return to user space. + Root pd thread can use this api to wait on pipe for receiving and gets resumed with QURT_EDESTROY + if the pipe gets destroyed . + + Pipe data items are defined as 64-bit values. Pipe writes are limited to transferring a single + 64-bit data item per operation. + + @note1hang Transfer data items larger than 64 bits by reading and writing + pointers to the data, or by transferring the data in consecutive 64-bit chunks. + + @datatypes + #qurt_pipe_t \n + #qurt_pipe_data_t + + @param[in] pipe Pointer to the pipe object to read from. + @param[in] data Data item to write. + + @return + #QURT_EOK -- Send completed. \n + #QURT_ECANCEL -- Send canceled. \n + #QURT_EDESTROY -- Send destroyed. \n + #QURT_ENOTALLOWED -- Pipe is not initialized + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_pipe_send_cancellable(qurt_pipe_t *pipe, qurt_pipe_data_t data); + +/**@ingroup func_qurt_pipe_is_empty + Returns a value indicating whether the specified pipe contains any data. + + @datatypes + #qurt_pipe_t + + @param[in] pipe Pointer to the pipe object to read from. + + @return + 1 -- Pipe contains no data. \n + 0 -- Pipe contains data. + + @dependencies + None. +*/ +int qurt_pipe_is_empty(qurt_pipe_t *pipe); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PIPE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmem_manager.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmem_manager.h new file mode 100755 index 0000000000000..8c8da985228b9 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmem_manager.h @@ -0,0 +1,82 @@ +#ifndef QURT_PMEM_MANAGER_H +#define QURT_PMEM_MANAGER_H +/** + @file qurt_pmem_manager.h + Prototypes of kernel physical memory manager APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===================================================================== + Constants and macros + ======================================================================*/ + +/* physical memory API return error code */ +#define QURT_PMEM_SUCCESS 0 +#define QURT_PMEM_NO_PRIV 1 +#define QURT_PMEM_RETRY 2 +#define QURT_PMEM_OVERLAP 3 +#define QURT_PMEM_NOT_EXIST 4 +#define QURT_PMEM_INIT_FAILURE 5 +#define QURT_PMEM_OUTSTANDING_MAPPING 6 +#define QURT_PMEM_GENERIC_FAILURE 7 +#define QURT_PMEM_ENTRY_FOUND 8 +#define QURT_PMEM_REACH_END 9 +#define QURT_PMEM_UNCLAIMED 10 +#define QURT_PMEM_ALREADY_CLAIMED 11 + +/*===================================================================== + Functions +======================================================================*/ + +/**@ingroup func_qurt_pmem_acquire + Acquire the ownership of a specific physical memory region. + + @note1hang The ownership will be the caller + + @param[in] ppage Starting physical page number + @param[in] pnum Number of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_OVERLAP -- The whole or part of the range has been owned \n + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. +*/ +int qurt_pmem_acquire(unsigned int ppage, unsigned int pnum); + +/**@ingroup func_qurt_pmem_release + Release the ownership of a specific physical memory region. + + @param[in] ppage The start of physical page number + @param[in] pnum The numbers of physical pages + + @return + #QURT_PMEM_NO_PRIV -- Have no privilege to claim the ownership. \n + #QURT_PMEM_NOT_EXIST -- The physical memory range is not usable. \n + #QURT_PMEM_OUTSTANDING_MAPPING -- There is outstanding mapping in this range + #QURT_PMEM_SUCCESS -- Succeed to claim ownership. + + @dependencies + None. + */ +int qurt_pmem_release(unsigned int ppage, unsigned int pnum); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMEM_MANAGER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmu.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmu.h new file mode 100755 index 0000000000000..73ea8eba04abf --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_pmu.h @@ -0,0 +1,121 @@ +#ifndef QURT_PMU_H +#define QURT_PMU_H +/** + @file qurt_pmu.h + Prototypes of pipe interface API. + A pipe or message queue blocks when too full (send) or empty (receive). + Unless using a nonblocking option, all datagrams are 64 bits. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_pmu_set + Sets the value of the specified PMU register. + + @note1hang Setting PMUEVTCFG automatically clears the PMU registers PMUCNT0 + through PMUCNT3. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @param[in] reg_value Register value. + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_set (int reg_id, unsigned int reg_value); + +/**@ingroup func_qurt_pmu_get + Gets the PMU register.\n + Returns the current value of the specified PMU register. + + @param[in] reg_id PMU register. Values: + - #QURT_PMUCNT0 + - #QURT_PMUCNT1 + - #QURT_PMUCNT2 + - #QURT_PMUCNT3 + - #QURT_PMUCFG + - #QURT_PMUEVTCFG + - #QURT_PMUCNT4 + - #QURT_PMUCNT5 + - #QURT_PMUCNT6 + - #QURT_PMUCNT7 + - #QURT_PMUEVTCFG1 @tablebulletend + + @return + Integer -- Current value of the specified PMU register. + + @dependencies + None. + */ +unsigned int qurt_pmu_get (int reg_id); + +/**@ingroup func_qurt_pmu_enable + Enables or disables the Hexagon processor PMU. + Profiling is disabled by default. + + @note1hang Enabling profiling does not automatically reset the count registers -- this must + be done explicitly before starting event counting. + + @param[in] enable Performance monitor. Values: \n + - 0 -- Disable performance monitor \n + - 1 -- Enable performance monitor @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_pmu_enable (int enable); + +/**@ingroup func_qurt_pmu_get_pmucnt + Reads PMU counters in a single trap. + + @param[out] buf Pointer to a buffer to save values read from PMU counters. + buffer size should be at least 32 bytes to read all eight PMU counters. + + @return + #QURT_EOK -- Successful read.\n + #QURT_EFATAL -- Failure. + + @dependencies + None. + */ +int qurt_pmu_get_pmucnt (void * buf); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PMU_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_power.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_power.h new file mode 100755 index 0000000000000..2ee4d29a73976 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_power.h @@ -0,0 +1,140 @@ +#ifndef QURT_POWER_H +#define QURT_POWER_H +/** + @file qurt_power.h + @brief Prototypes of power API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +/*============================================================================= + + EDIT HISTORY FOR MODULE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + +when who what, where, why +-------- --- ------------------------------------------------------------ +03/03/11 op Add header file +12/12/12 cm (Tech Pubs) Edited/added Doxygen comments and markup. +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +/**@ingroup func_qurt_power_shutdown_fail_exit + Returns from Power Collapse mode when power collapse cannot proceed. + + This function unmasks the global interrupt. This operation is used only when the thread is + recovering from a failed power collapse operation (Section @xref{sec:powerShutdownEnter}). + + @return + #QURT_EOK -- Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_fail_exit qurt_power_exit + +/**@ingroup func_qurt_power_shutdown_exit + Undoes state changes made preparing for power collapse.\n + This function unmasks the global interrupts. + + @return + #QURT_EOK --Operation was successfully performed. + + @dependencies + None. + */ +#define qurt_power_shutdown_exit qurt_power_exit +/**@endcond */ + +/**@ingroup func_qurt_system_ipend_get + Gets the IPEND register.\n + + @note1hang Returns the current value of the Hexagon processor IPEND register. The return value + is a mask value that identifies the individual interrupts that are pending. \n + + @note1hang The bit order of the mask value is identical to the order defined for the IPEND register. A + mask bit value of 1 indicates that the corresponding interrupt is pending, and 0 indicates that the + corresponding interrupt is not pending. \n + + @return + Return the IPEND register value. + + @dependencies + None. + */ +unsigned int qurt_system_ipend_get (void); + + +/**@ingroup func_qurt_system_vid_get + Gets the VID register. \n + + @note1hang Returns the current value of the Hexagon processor VID register. The return value is + the vector number of a second-level interrupt that has been accepted by the Hexagon + processor core.\n + + @return + Return the VID register value that is the L2 VIC interrupt number accepted by the processor. + Valid range is 0 to 1023. + + @dependencies + None. + */ +unsigned int qurt_system_vid_get(void); + +/**@ingroup func_qurt_power_shutdown_get_pcycles + Gets the number of power collapses and processor cycles for entering and exiting most recent + power collapse. + + @note1hang If no power collapse has occured yet, processor cycle numbers are zero. + + @param[out] enter_pcycles Number of processor cycles for entering most + recent power collapse. + @param[out] exit_pcycles Number of processor cycles for exiting most + recent power collapse. + @return + Zero -- No power collapses have occurred. \n + Nonzero -- Number of power collapses that have occurred since + the processor was reset. + + @dependencies + None. + */ +int qurt_power_shutdown_get_pcycles( unsigned long long *enter_pcycles, unsigned long long *exit_pcycles ); + +/**@ingroup func_qurt_system_tcm_set_size + Set size of TCM to save during full power collapse. + + @note1hang The size aligns to 32 bytes. If size passed is greater than the maximum size defined in + XML, the size is truncated to the size defined in XML. + + @param[in] new_size Size of TCM to save. + + @return + Zero -- Size successfully set \n + -1 -- Size of 0 passed + + @dependencies + None. + */ +int qurt_system_tcm_set_size(unsigned int new_size); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_POWER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_printf.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_printf.h new file mode 100755 index 0000000000000..a775d8a815918 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_printf.h @@ -0,0 +1,44 @@ +#ifndef QURT_PRINTF_H +#define QURT_PRINTF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file qurt_printf.h + Prototypes of printf API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup chapter_function_tracing +@{ */ + +int qurt_printf(const char* format, ...); + +int qurt_vprintf(const char* format, va_list args); + +/** @} */ /* end_addtogroup chapter_function_tracing */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_PRINTF_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_process.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_process.h new file mode 100755 index 0000000000000..0df9ddc2d4a70 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_process.h @@ -0,0 +1,995 @@ +#ifndef QURT_PROCESS_H +#define QURT_PROCESS_H +/** + @file qurt_process.h + @brief Prototypes of QuRT process control APIs. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2009-2013, 2021-2023 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_callback.h" +#include "qurt_consts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup process_types +@{ */ +#define QURT_PROCESS_ATTR_NAME_MAXLEN QURT_MAX_NAME_LEN /**< Maximum length of the process name. */ +#define QURT_PROCESS_ATTR_BIN_PATH_MAXLEN 128 /**< Maximum length of the path of binary/ELF for this process. */ +#define QURT_PROCESS_ATTR_CAP_MAXLEN 128 /**< Maximum length for a resource name. */ + +/** QuRT process capability wildcard strings */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_ALL "ALLOW_ALL" /**< Capability wild-card for full access */ +#define QURT_PROCESS_ATTR_CAP_ALLOW_NONE "ALLOW_NONE" /**< Capability wild-card for no access */ + +/** QuRT process capability states */ +#define QURT_PROCESS_ATTR_CAP_ENABLED 0x1 /**< Capability enabled*/ +#define QURT_PROCESS_ATTR_CAP_DISABLED 0x0 /**< Capability disabled*/ + +/* QuRT process thread attributes. */ +#define QURT_PROCESS_DEFAULT_CEILING_PRIO 0 /**< Default ceiling priority of the threads in the new process. */ +#define QURT_PROCESS_DEFAULT_MAX_THREADS -1 /**< Default number of threads in the new process. + -1 indicates that the limit is set to the maximum supported by the system. */ + +/* QuRT process flags. */ +#define QURT_PROCESS_SUSPEND_ON_STARTUP (1U) /**< Suspend the new processes just before calling main(). */ +#define QURT_PROCESS_NON_SYSTEM_CRITICAL (1u << 1) /**< Starts the new process as non system-critical. */ +#define QURT_PROCESS_ISLAND_RESIDENT (1u << 2) /**< Process is island resident. */ +#define QURT_PROCESS_RESTARTABLE (1u << 3) /**< Indicates that the process is restartable */ +#define QURT_PROCESS_UNTRUSTED (1u << 7) /**< Starts the new process as unsigned process. */ + +/* QuRT process debugging session status.*/ +#define QURT_DEBUG_NOT_START 0 /**< Debug is not started. */ +#define QURT_DEBUG_START 1 /**< Debug has started. */ + +/** Process Suspend Options */ +#define QURT_PROCESS_SUSPEND_DEFAULT 0 + +/** Process Resume Options */ +#define QURT_PROCESS_RESUME_DEFAULT 0 + + +/* QuRT process types. */ +typedef enum { + QURT_PROCESS_TYPE_RESERVED, /**< Process type is reserved. \n */ + QURT_PROCESS_TYPE_KERNEL, /**< Kernel process. \n*/ + QURT_PROCESS_TYPE_SRM, /**< SRM process. \n*/ + QURT_PROCESS_TYPE_SECURE, /**< Secure process. \n*/ + QURT_PROCESS_TYPE_ROOT, /**< Root process. \n*/ + QURT_PROCESS_TYPE_USER, /**< User process. */ +}qurt_process_type_t; + +/** QuRT process callback types. */ +typedef enum { + QURT_PROCESS_DUMP_CB_ROOT, /**< Register the callback that executes in the + root process context. \n */ + QURT_PROCESS_DUMP_CB_ERROR, /**< Register the user process callback that is + called after threads in the process are frozen. \n */ + QURT_PROCESS_DUMP_CB_PRESTM, /**< Register the user process callback that is + called before threads in the process are frozen. \n*/ + QURT_PROCESS_DUMP_CB_MAX /**< Reserved for error checking. */ +}qurt_process_dump_cb_type_t; + +/** QuRT process dump attributes. */ +typedef struct _qurt_pd_dump_attr{ + /** @cond */ + unsigned int enabled; /**< Process dump is enabled. */ + const char *path; /**< Process dump path. */ + unsigned int path_len; /**< Length of process dump path. */ + /** @endcond */ +}qurt_pd_dump_attr_t; + +/** QuRT process capability resource type */ +enum qurt_process_cap_type_t { + QURT_PROCESS_CAP_TYPE_NUM_ENTRIES=0, /**< Number of entries in the capability structure*/ + QURT_PROCESS_CAP_TYPE_DRIVER=1, /**< Driver resource */ + QURT_PROCESS_CAP_TYPE_MAX /**< Maximum identifier */ +}; + +/** QuRT process capability structure */ +typedef struct _qurt_capability { + enum qurt_process_cap_type_t type; /**< Resource type */ + char name[QURT_PROCESS_ATTR_CAP_MAXLEN]; /**< Resource name*/ + unsigned long long cap; /**< Capabilities allowed for this resource */ +}qurt_capability_t; + +/** QuRT process attributes. */ +typedef struct _qurt_process_attr { + /** @cond */ + char name[QURT_PROCESS_ATTR_NAME_MAXLEN]; /**< Name of the new process. */ + char path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the binary for the new process. */ + char dtb_path[QURT_PROCESS_ATTR_BIN_PATH_MAXLEN]; /**< Path of the DTB ELF for the new process. */ + int flags; /**< Flags as indicated by QuRT process flags. */ + unsigned int sw_id; /**< Software ID of the process be load. */ + unsigned sid; /**< Stream ID of the process being spawned. */ + unsigned max_threads; /**< Maximum number of threads that the new process can create. */ + unsigned short ceiling_prio; /**< Maximum priority at which threads can be + created by new process. */ + qurt_process_type_t type; /**< Process type as indicated by + #qurt_process_type_t. */ + qurt_pd_dump_attr_t dump_attr; /**< Process dump attributes for the new process + as indicated by #qurt_pd_dump_attr_t. */ + qurt_capability_t *capabilities; /**< Pointer to array of structure of type + qurt_capability_t */ + /** @endcond */ +} qurt_process_attr_t; + +/** @} */ /* end_addtogroup process_types */ + +/*============================================================================= +FUNCTIONS +=============================================================================*/ + /** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_create + Creates a process with the specified attributes, and starts the process. + + The process executes the code in the specified executable ELF file. + + @datatypes + #qurt_process_attr_t + + @param[out] attr Accepts an initialized process attribute structure, which specifies + the attributes of the created process. + + @return + Postive return value Indicates Process ID. + Negative return value Indicates any of follwoing error, + #-QURT_EPRIVILEGE -- Caller does not have privilege for this operation \n + #-QURT_EMEM -- Not enough memory to perform the operation \n + #-QURT_EFAILED -- Operation failed \n + #-QURT_ENOTALLOWED -- Operation not allowed \n + #-QURT_ENOREGISTERED -- Not registered \n + #-QURT_ENORESOURCE -- Resource exhaustion \n + #-QURT_EINVALID -- Invalid argument value + #QURT_EFATAL -- attr is NULL + + @dependencies + None. +*/ +int qurt_process_create (qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_get_id + Returns the process identifier for the current thread. + + @return + None. + + @dependencies + Process identifier for the current thread. +*/ +int qurt_process_get_id (void); +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_get_uid + Returns the user identifier for the current thread. + + @return + None. + + @dependencies + User identifier for the current thread. +*/ +int qurt_process_get_uid (void); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_init + Initializes the structure that sets the process attributes when a thread is created. + + After an attribute structure is initialized, the individual attributes in the structure can + be explicitly set using the process attribute operations. + + Table @xref{tbl:processAttrDefaults} lists the default attribute values set by the initialize + operation. + + @inputov{table_process_attribute_defaults} + + @datatypes + #qurt_process_attr_t + + @param[out] attr Pointer to the structure to initialize. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_process_attr_init (qurt_process_attr_t *attr) +{ + attr->name[0] = '\0'; + attr->path[0] = '\0'; + attr->dtb_path[0] = '\0'; + attr->flags = 0; + attr->sw_id = 0; + attr->sid = 0; + attr->max_threads = (unsigned)QURT_PROCESS_DEFAULT_MAX_THREADS; + attr->ceiling_prio = QURT_PROCESS_DEFAULT_CEILING_PRIO; + attr->type = QURT_PROCESS_TYPE_RESERVED; + attr->dump_attr.enabled = 0; + attr->dump_attr.path = NULL; + attr->dump_attr.path_len = 0; + attr->capabilities = NULL; +} + +/**@ingroup func_qurt_process_attr_set_executable + Sets the process name in the specified process attribute structure. + + Process names identify process objects that are already + loaded in memory as part of the QuRT system. + + @note1hang Process objects are incorporated into the QuRT system at build time. + + @note1hang Maximum length of name string is limited to QURT_PROCESS_ATTR_NAME_MAXLEN - 1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] name Pointer to the process name. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_executable (qurt_process_attr_t *attr, const char *name); + +/**@ingroup func_qurt_process_attr_set_binary_path + Sets the binary path for the process loading in the specified process attribute structure. + + Path specifies the binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_binary_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_dtb_path + Sets the DTB binary path for the process loading in the specified process attribute structure. + + Path specifies the DTB binary to load for this process. + + @note1hang Max length of path string is limited to QURT_PROCESS_ATTR_BIN_PATH_MAXLEN-1. + + @datatypes + #qurt_process_attr_t + + @param[in] attr Pointer to the process attribute structure. + @param[in] path Pointer to the binary path. + + @return + None. + + @dependencies + None. +*/ +void qurt_process_attr_set_dtb_path(qurt_process_attr_t *attr, char *path); + +/**@ingroup func_qurt_process_attr_set_flags +Sets the process properties in the specified process attribute structure. +Process properties are represented as defined symbols that map into bits +0 through 31 of the 32-bit flag value. Multiple properties are specified by OR'ing +together the individual property symbols. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] flags QURT_PROCESS_NON_SYSTEM_CRITICAL Process is considered as non system-critical. + This attribute will be used by error services, + to decide whether to kill user pd or whole subsystem. + QURT_PROCESS_ISLAND_RESIDENT Process will be marked as island resident. + QURT_PROCESS_RESTARTABLE Process will be marked as restartable. + QURT_PROCESS_UNTRUSTED Process will be marked as unsigned process. +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_flags (qurt_process_attr_t *attr, int flags) +{ + attr->flags = flags; +} +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_sid +Sets the process streamID in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sid streamID to set for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sid (qurt_process_attr_t *attr, unsigned sid) +{ + attr->sid = sid; +} +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_set_max_threads +Sets the maximum number of threads allowed in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] max_threads Maximum number of threads allowed for this process. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_max_threads (qurt_process_attr_t *attr, unsigned max_threads) +{ + attr->max_threads = max_threads; +} + +/**@ingroup func_qurt_process_attr_set_sw_id +Sets the software ID of the process to load in the specified process attribute structure. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] sw_id Software ID of the process, used in authentication. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_sw_id(qurt_process_attr_t *attr, unsigned int sw_id) +{ + attr->sw_id = sw_id; +} + +/**@ingroup func_qurt_process_attr_set_ceiling_prio +Sets the highest thread priority allowed in the specified process attribute structure. +Refer qurt_thread.h for priority ranges. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] prio Priority. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_ceiling_prio (qurt_process_attr_t *attr, unsigned short prio) +{ + attr->ceiling_prio = prio; +} +/** @endcond */ + +/** @cond internal_only*/ +/**@ingroup func_qurt_process_attr_set_dump_status +Sets the process domain dump-enabled field in the process domain dump attributes. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] enabled 1 -- Process domain dump is collected \n + 0 -- Process domain dump is not collected + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_status(qurt_process_attr_t *attr, unsigned int enabled) +{ + attr->dump_attr.enabled = enabled; +} + +/**@ingroup func_qurt_process_attr_set_dump_path +Sets the process domain dump path and type. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] path Path where the process domain dumps must be saved. +@param[in] path_len Length of the path string. + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_dump_path(qurt_process_attr_t *attr, const char *path, int path_len) +{ + attr->dump_attr.path = path; + attr->dump_attr.path_len = (unsigned int)path_len; +} + +/**@ingroup func_qurt_process_attr_set_capabilities +Sets list of capabilities available to this process. + +@datatypes +#qurt_process_attr_t + +@param[in] attr Pointer to the process attribute structure. +@param[in] capabilities Pointer to array of structures of type qurt_capability_t defining + resources and capabilites + +@return +None. + +@dependencies +None. +*/ +static inline void qurt_process_attr_set_capabilities(qurt_process_attr_t *attr, qurt_capability_t *capabilities) +{ + attr->capabilities = capabilities; +} + +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_cmdline_get +Gets the command line string associated with the current process. +The Hexagon simulator command line arguments are retrieved using +this function as long as the call is made +in the process of the QuRT installation, and with the +requirement that the program runs in a simulation environment. + +If the function modifies the provided buffer, it zero-terminates +the string. It is possible that the function does not modify the +provided buffer, so the caller must set buf[0] to a NULL +byte before making the call. A truncated command line is returned when +the command line is longer than the provided buffer. + +@param[in] buf Pointer to a character buffer that must be filled in. +@param[in] buf_siz Size (in bytes) of the buffer pointed to by the buf argument. + +@return +None. + +@dependencies +None. +*/ +void qurt_process_cmdline_get(char *buf, unsigned buf_siz); + +/**@ingroup func_qurt_process_get_thread_count +Gets the number of threads present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of threads in the process indicated by PID, if positive value is obtained +Negative error code if failed include: + QURT_EFATAL - Invalid PID + -QURT_ENOTALLOWED - Current process doesnt have access to target process indicated by PID + +@dependencies +None. +*/ +int qurt_process_get_thread_count(unsigned int pid); + +/**@ingroup func_qurt_process_get_thread_ids +Gets the thread IDs for a process indicated by PID. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a user passed buffer that must be filled in with thread IDs. +@param[in] thread_num Number of thread IDs requested. + +@return +#QURT_EOK - Success +#QURT_EFATAL - Failed, ptr is NULL + +@dependencies +None. + */ +int qurt_process_get_thread_ids(unsigned int pid, unsigned int *ptr, unsigned thread_num); +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_dump_get_mem_mappings_count +Gets the number of mappings present in the process indicated by the PID. + +@param[in] pid PID of the process for which the information is required. + +@return +Number of mappings for the process indicated by the PID. + +@dependencies +None. +*/ +int qurt_process_dump_get_mem_mappings_count(unsigned int pid); + +/**@ingroup func_qurt_process_dump_get_mappings +Gets the mappings for a specified PID. + +@note1hang This API skips device type mappings or mappings created by setting the #QURT_PERM_NODUMP attribute. + +@param[in] pid PID of the process for which the information is required. +@param[in] ptr Pointer to a buffer that must be filled in with mappings. +@param[in] count Count of mappings requested. + +@return +Number of mappings filled in the buffer passed by the user. + +@dependencies +None. +*/ +int qurt_process_dump_get_mappings(unsigned int pid, unsigned int *ptr, unsigned count); +/** @endcond */ +/** @cond rest_reg_dist */ +/**@ingroup func_qurt_process_attr_get +Gets the attributes of the process with which it was created. + +@datatypes +#qurt_process_attr_t + +@param[in] pid PID of the process for which the information is required. +@param[in,out] attr Pointer to the user allocated attribute structure. + +@return +#QURT_EOK - Success +#QURT_INVALID - Invalid PID +#QURT_EFATAL - attr is NULL + +@dependencies +None. +*/ +int qurt_process_attr_get(unsigned int pid, qurt_process_attr_t *attr); + +/**@ingroup func_qurt_process_dump_register_cb +Registers the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information. +@param[in] type Callback type; these callbacks are called in the context of the user process domain: \n + #QURT_PROCESS_DUMP_CB_PRESTM -- Before threads of the exiting process are frozen. \n + #QURT_PROCESS_DUMP_CB_ERROR -- After threads are frozen and captured. \n + #QURT_PROCESS_DUMP_CB_ROOT -- After threads are frozen and captured, and CB_ERROR type of callbacks + are called. +@param[in] priority Priority. + +@return +#QURT_EOK -- Success \n +Other values -- Failure + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_register_cb(qurt_cb_data_t *cb_data, qurt_process_dump_cb_type_t type, unsigned short priority); + +/**@ingroup func_qurt_process_dump_deregister_cb +Deregisters the process domain dump callback. + +@datatypes +#qurt_cb_data_t \n +#qurt_process_dump_cb_type_t + +@param[in] cb_data Pointer to the callback information to deregister. +@param[in] type Callback type. + +@return +#QURT_EOK -- Success.\n +Other values -- Failure. + QURT_EFATAL if cb_data is NULL + QURT_EINVALID If invalid cb_type + QURT_EFAILED If invalid cb_data + +@dependencies +None. +*/ +int qurt_process_dump_deregister_cb(qurt_cb_data_t *cb_data,qurt_process_dump_cb_type_t type); + +/** @endcond */ +/** @cond internal_only*/ +/**@ingroup func_qurt_process_set_rtld_debug +Sets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in] address rtld_debug address. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_set_rtld_debug(unsigned int pid,unsigned int address); + +/**@ingroup func_qurt_process_get_rtld_debug +Gets rtld_debug for a process. + +@param[in] pid PID of the process for which rtld_debug must be set. +@param[in,out] address Pointer to the user passed address in which the rtld_debug address must be returned. + +@return +#QURT_EOK - Success +#QURT_EINVALID - Invalid PID +#QURT_EFATAL - Invalid address + +@dependencies +None. +*/ +int qurt_process_get_rtld_debug(unsigned int pid,unsigned int *address); +/** @endcond */ +/**@ingroup func_qurt_process_exit +Exits the current user process with an exit code. + +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exit(int exitcode); + +/**@ingroup func_qurt_process_kill +Kills the process represented by the PID with the exit code. + +@param[in] pid PID of the process to kill. +@param[in] exitcode Exit code. + +@return +#QURT_EFATAL -- No client found with the specified PID value \n +#QURT_EINVALID -- Invalid client \n +#QURT_ENOTALLOWED -- User does not have permission to perform this operation \n +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_kill(int pid, int exitcode); + + +/**@ingroup func_qurt_debugger_register_process +Registers the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. +@param[in] adr Address. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_register_process(int pid, unsigned int adr); + + +/**@ingroup func_qurt_debugger_deregister_process +Deregister the process indicated by the PID with the debug monitor. + +@param[in] pid PID of the process. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_debugger_deregister_process(int pid); + +/**@ingroup func_qurt_process_exec_callback +Executes callbacks in the user process as indicated by the client_handle argument. + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] callback_fn Callback function to execute. +@param[in] stack_base Stack address to use. +@param[in] stack_size Stack size. + +@return +#QURT_EOK -- Success + +@dependencies +None. +*/ +int qurt_process_exec_callback(int client_handle, + unsigned callback_fn, + unsigned stack_base, + unsigned stack_size); + +/**@ingroup func_qurt_process_get_pid +Gets the process ID of the process that the client_handle argument represents. + +@note1hang This API is not supported for unsigned PD, For unsigned PD use qurt_process_get_id() + +@param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). +@param[in] pid Pointer to the address to store the PID. + +@return +#QURT_EOK -- Success +#QURT_EFATAL -- pid pointer passed as NULL + +@dependencies +None. +*/ +int qurt_process_get_pid(int client_handle, int * pid); + +/**@ingroup func_qurt_process_get_dm_status +Gets the debugging session status on the process represented by the pid argument. + +@param[in] pid Process ID +@param[in,out] status Address to store the status: \n + #QURT_DEBUG_NOT_START \n + #QURT_DEBUG_START + +@return +#QURT_EOK - Success \n +#QURT_EINVALID - Error + +@dependencies +None. +*/ +int qurt_process_get_dm_status( unsigned int pid, unsigned int *status); + + +/**@ingroup func_qurt_process_suspend_threads + Suspends user threads in a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in GuestOS/root process. + After the user threads in the target user process are suspended, they cannot be scheduled to run by the kernel + until they resume later. + + This function has one optional argument with one default option. + #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + This function call is a synchronous call, the function returns after the relevant threads are + completely suspended. + + If some user threads in the target user process are set as non-suspendable, this function call does + not suspend these threads. + + If the target user process is already suspended, this function call returns success as the + confirmation on the user process suspending. + + QuRT debugger monitor threads in the target user process are non-suspendable, this function call does + not suspend the threads. + + If the target user process is a secure user process, or a CPZ process, this function call returns error + without suspending the target user process. + + If a user thread in the target user process runs in the guest OS/root process via a QDI call, this function call + does not suspend the thread in the guest OS, but instead marks the thread as pending-suspend. The thread is suspended + when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success while the user thread can be running in GuestOS, and is suspended + when exiting the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Dfault option #QURT_PROCESS_SUSPEND_DEFAULT suspends user threads in the target user process. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid process_id input \n + #QURT_ENOTALLOWED -- Failure because the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_suspend_threads (unsigned int process_id, unsigned int option); + + +/**@ingroup func_qurt_process_resume_threads + Resumes a user process with its process identifier. + The target user process can be a signed user process or an unsigned user process. + The caller is from a thread in the guest OS/root process. + After the user threads in the target user process resume, the kernel scheduler + can schedule the user threads to run based on their thread priorities. + + This function has an optional argument, #QURT_PROCESS_RESUME_DEFAULT, which + resumes user threads in the target user process. + + This is an asynchronous function, it returns after the kernel moves the user thread from + suspended state to runnable state. The threads are scheduled to run based on their thread priorities. + + This function call does not resume threads in the target user process that have been set as non-resumable. + + If the target user process have already resumed, this function call confirms that the user process resumes + by returning success. + + If the target user process is a secure user process or a CPZ process, this function call returns an error without + resuming operation. + + If user threads in the target user process run in the guest OS/root process via QDI call, this function + call clears the mark of suspend-pending on these threads, so that the threads are be suspended when it exits + the guest OS. + + @param[in] process_id Process identifier. + @param[in] option Default option #QURT_PROCESS_RESUME_DEFAULT resumes user threads in the target user process. + + @return + #QURT_EOK -- Success + #QURT_EINVALID -- Failure because of invalid process_id input. + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, on a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_process_resume_threads (unsigned int process_id, unsigned int option); + +/**@ingroup func_qurt_process_vtcm_window_set + Set a VTCM access window for a process. + The caller thread needs to be in SRM process. + + This is an synchronous function, it ensures all running threads of the process have the requested + window in effect.The requested view for all non-running thread will take in effect when they get + scheduled. + + @param[in] pid Process identifier. + @param[in] enable QURT_VTCM_WINDOW_ENABLE enforces VTCM access window defined by high and low offset. + QURT_VTCM_WINDOW_DISABLE high and low offset is ignored and VTCM access is fully + disabled for the process. + @param[in] high_offset Specifies the high window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT restore high offset to reset value. + @param[in] low_offset Specifies the low window offset, in 4K increments, from the base address of the VTCM. + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT restore low offset to reset value. + + @note1hang + when high_offset is set to QURT_VTCM_WINDOW_HI_OFFSET_DEFAULT and low offset is set as + QURT_VTCM_WINDOW_LO_OFFSET_DEFAULT full VTCM range is accessible. Access to VTCM is controlled + via MMU mapping for the process. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_set(int pid, unsigned int enable, unsigned int high_offset, unsigned int low_offset); + +/**@ingroup func_qurt_process_vtcm_window_get + Get the VTCM window for a process. + The caller thread needs to be in SRM process. + + + @param[in] pid Process identifier. + @param[out] enable address to store enable status if set + @param[out] high_offset address to return high window offset, in 4K increments, from the base address of the VTCM + @param[out] low_offset address to return low window offset, in 4K increments, from the base address of the VTCM. + + @note1hang + User must first check the value of enable returned before checking high and low offset. + + @return + #QURT_EOK -- Success + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_ENOTSUPPORTED -- Failure because of the operation is not supported due to limitation in HW capabilities + + @dependencies + None. + */ +int qurt_process_vtcm_window_get(int pid, unsigned int *enable, unsigned int *high_offset, unsigned int *low_offset); + +/**@ingroup func_qurt_process_set_group_config + Enable thread groups in the process with the ceiling priorities setup + + @param[in] process_id Process identifier. + @param[in] group_bitmask 64-bit mask of active thread groups + @param[in] ceiling_priorities array of ceiling priorities for thread group + + @note1hang + This API can only be called by root PD and can only be called once for each process, otherwise it will be + rejected. Group 0 must be enabled in group_bitmask, otherwise QuRT will return error. After this API, all + exisiting threads will be moved to group 0, and if there is any thread's priority higher than ceiling + priority of group 0, it will be lowered to the ceiling value. + Examples 1: + group_bitmask = 0xD7; //'b11010111 + ceiling_priorities[] = {100, 128, 200, 0, 196, 0, 240, 20}; // 0 - does not care + Exmaples 2: + group_mask = 0x5; //'b101 + ceiling_priorities[] = {240, 0, 20}; // 0 - does not care + + + @return + #QURT_EOK -- Success. + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_ENOTALLOWED -- The group has been configured already. + + @dependencies + None. + */ +int qurt_process_set_group_config(unsigned int process_id, unsigned long long group_bitmask, + unsigned char *ceiling_priorities); + + +/**@ingroup func_qurt_process_stid_set + Set the specified stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[in] stid stid to be set + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) if stid needs to set at a process level. + All threads within a process that has default stid (QURT_STID_DEFAULT) will inherit the stid set for a process. + When a non-default group_id is specified, the stid is set only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_set(unsigned int pid, unsigned int group_id , unsigned int stid); + +/**@ingroup func_qurt_process_stid_get + Get the stid for a process or for a thread group within a process. + + @param[in] pid Process identifier. + @param[in] group_id group identifier + @param[out] Pointer to a variable to return stid + + @note1hang + User can pass default group_id (QURT_THREAD_DEFAULT_GROUP_ID) to return process-level stid. + When a non-default group_id is specified, the stid is returned only for a thread group. + + @return + #QURT_EOK -- Success + #QURT_EFATAL -- Invalid PID + #QURT_EVAL -- Failure because of invalid inputs. + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + + @dependencies + None. + */ +int qurt_process_stid_get(unsigned int pid, unsigned int group_id , unsigned int *stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_profile.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_profile.h new file mode 100755 index 0000000000000..2a50c461440f6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_profile.h @@ -0,0 +1,98 @@ +#ifndef QURT_PROFILE_H +#define QURT_PROFILE_H +/** + @file qurt_profile.h + QuRT profiling support. + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +==============================================================================*/ +#include "qurt_thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup profiling_macros +@{ */ +#define QURT_PROFILE_DISABLE 0 /**< Disable profiling. */ +#define QURT_PROFILE_ENABLE 1 /**< Enable profiling. */ + +typedef unsigned int qurt_profile_param_t; + +#define QURT_PROFILE_PARAM_THREAD_READY_TIME 0U /**< Profile thread ready time. */ + +/** @} */ /* end_addtogroup profiling_macros */ + +/** @addtogroup profiling_types + @{ */ +/** Profiling results. */ +typedef union +{ + /** Result associated with #QURT_PROFILE_PARAM_THREAD_READY_TIME. */ + struct + { + unsigned int ticks; /**< Cumulative ticks the thread was ready. */ + } thread_ready_time; + +} qurt_profile_result_t; +/** @} */ /* end_addtogroup profiling_types */ + +/**@ingroup func_qurt_profile_enable2 + * Starts profiling of a specific parameter on a specific thread (as applicable). + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of the thread (if applicable) for which the specified + * paramter must be profiled. + * @param[in] enable #QURT_PROFILE_DISABLE -- disable \n #QURT_PROFILE_ENABLE -- + * enable + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EALREADY -- Measurement already in progress or already stopped \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_enable2 ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + int enable +); + +/**@ingroup func_qurt_profile_get + * Gets the value of the profiling parameter that was previously enabled. + * + * @param[in] param Profiling parameter. + * @param[in] thread_id ID of thread (if applicable) for which the specified + * profiling paramter must be retrieved. + * @param [out] result Profiling result associated with the parameter for the specified + * thread (if applicable). + * + * @return + * #QURT_EOK -- Success \n + * #QURT_EFAILED -- Operation failed; profiling was not enabled \n + * #QURT_ENOTHREAD -- Thread does not exist \n + * #QURT_EINVALID -- Invalid profiling parameter \n + * + * @dependencies + * None. + */ +extern int qurt_profile_get ( + qurt_profile_param_t param, + qurt_thread_t thread_id, + qurt_profile_result_t * result +); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ptrace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ptrace.h new file mode 100755 index 0000000000000..622304dd92865 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_ptrace.h @@ -0,0 +1,37 @@ +/*============================================================================= + + qurt_ptrace.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2013 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef __SYS_PTRACE_H__ +#define __SYS_PTRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum __ptrace_request +{ + /** + Indicates that the process making this request is requesting to be traced. + */ + PTRACE_TRACEME = 0, + PTRACE_EXT_IS_DEBUG_PERMITTED = 500 +}; + +long ptrace(enum __ptrace_request request, unsigned int pid, void*addr, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_PTRACE_H__ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi.h new file mode 100755 index 0000000000000..705408e5cfc6f --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi.h @@ -0,0 +1,185 @@ +#ifndef QDI_H +#define QDI_H + +/** + @file qurt_qdi.h + @brief Prototypes of QuRT Driver Invocation API functions + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + + +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_qdi_open + Opens the specified driver for subsequent operations. + qurt_qdi_open() is the primary mechanism by which a driver user can + obtain a QDI handle. The user provides the name of the driver to the + qurt_qdi_open call, and gets back a handle referencing + the named driver. \n + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_open function prototype is not actually defined as a varargs. + + + @param[in] p Driver name. + @param[in] ... Up to nine additional device-specific arguments can be passed as parameters, + and should follow the POSIX open() convention. \n + - flags -- Optional second parameter (POSIX flags), the handle + access requested (read-only, write-only, or read-write, + for instance) and other flags such as whether the call + should create a new device or only open an existing + device. \n + - mode -- Optional third parameter (POSIX mode); permissions to + configure when a new device is created. @tablebulletend + + @return + Negative value -- Error. \n + Non-negative value -- Success, this result value serves as a handle to the + opened driver. + @dependencies + None. + */ +// int qurt_qdi_open(); +#define qurt_qdi_open(p,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN,(p),##__VA_ARGS__) + +#define qurt_qdi_open_dt(p,q,...) \ + qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC,QDI_OPEN_FROM_DT,(p),(q),##__VA_ARGS__) + +/**@ingroup func_qurt_qdi_handle_invoke + Performs a generic driver operation, which (depending on the specified operation) can be + either be one of the predefined operations listed in @xhyperref{tbl:functionMapping,QDI function mapping} + or a driver-specific operation. + The user provides a QDI handle and an integer + method number, along with 0 to 8 optional 32-bit arguments. + The device driver invocation function is invoked with the + same method number and 0 to 8 optional arguments. The + return value from the invocation function is passed back to + the user as the return value of qurt_qdi_handle_invoke. + + @note1hang For reasons related to the Hexagon standard for varargs functions, the + qurt_qdi_handle_invoke() function prototype is not actually defined as a + varargs function (and would break if it were defined this way). + + @param[in] h Driver handle. + @param[in] m Integer number for the operation to perform. + @param[in] ... Up to eight optional arguments can be passed to the device driver as operation-specific parameters: \n + arg1 -- First parameter \n + arg2 -- Second parameter \n + arg3 -- Third parameter \n + arg4 -- Fourth parameter \n + arg5 -- Fifth parameter \n + arg6 -- Sixth parameter \n + arg7 -- Seventh parameter \n + arg8 -- Eighth parameter + + @return + Integer value defined by the device driver. \n + -1 -- Error. + + @dependencies + None. + */ +// int qurt_qdi_handle_invoke(); +#define qurt_qdi_handle_invoke(h,m,...) \ + _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__) +#define _QDMHI3(a,b,c) qurt_qdi_qhi3(0,b,c) +#define _QDMHI4(a,b,c,d) qurt_qdi_qhi4(0,b,c,(int)(d)) +#define _QDMHI5(a,b,c,d,e) qurt_qdi_qhi5(0,b,c,(int)(d),(int)(e)) +#define _QDMHI6(a,b,c,d,e,f) qurt_qdi_qhi6(0,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMHI7(a,b,c,d,e,f,g) qurt_qdi_qhi7(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMHI8(a,b,c,d,e,f,g,h) qurt_qdi_qhi8(8,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMHI9(a,b,c,d,e,f,g,h,i) qurt_qdi_qhi9(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMHI10(a,b,c,d,e,f,g,h,i,j) qurt_qdi_qhi10(16,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMHI11(a,b,c,d,e,f,g,h,i,j,k) qurt_qdi_qhi11(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMHI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_qdi_qhi12(24,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) +int qurt_qdi_qhi3(int,int,int); +int qurt_qdi_qhi4(int,int,int,int); +int qurt_qdi_qhi5(int,int,int,int,int); +int qurt_qdi_qhi6(int,int,int,int,int,int); +int qurt_qdi_qhi7(int,int,int,int,int,int,int); +int qurt_qdi_qhi8(int,int,int,int,int,int,int,int); +int qurt_qdi_qhi9(int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi10(int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi11(int,int,int,int,int,int,int,int,int,int,int); +int qurt_qdi_qhi12(int,int,int,int,int,int,int,int,int,int,int,int); + +/**@ingroup func_qurt_qdi_write + Writes data to the specified driver. + A predefined invocation routine for drivers that + support a POSIX-like write functionality. + qqurt_qdi_write(handle, buf, len) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_WRITE, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data to write is stored. + @param[in] len Number of bytes of data to write. + + @return + Non-negative integer -- Number of bytes written. \n + Negative error code -- Write could not take place. + + @dependencies + None. + */ +int qurt_qdi_write(int handle, const void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_read + User-visible API to read data from a QDI handle. + A predefined invocation routine for drivers that + support a POSIX-like read functionality. + qurt_qdi_read(handle, buf, len) is equivalent to: + qurt_qdi_handle_invoke(handle, QDI_READ, handle, buf, len); + + @param[in] handle Driver handle. + @param[in] buf Pointer to the memory address where the data read is stored. + @param[in] len Number of bytes of data to read. + + @return + Non-negative integer number -- Bytes read. \n + Negative error code -- Read could not take place. + + @dependencies + None. + */ +int qurt_qdi_read(int handle, void *buf, unsigned len); + +/**@ingroup func_qurt_qdi_close + Closes the specified driver, releasing any resources associated with the open driver. + User-visible API to close a QDI handle. + + This API should be called when the user is done using a + QDI-based handle. When this function is called, the driver can release + any resources held and perform other necessary cleanup + operations. qurt_qdi_close(handle) is equivalent to + qurt_qdi_handle_invoke(handle, QDI_CLOSE, handle) + + @param[in] handle Driver handle. + + @return + 0 -- Success.\n + Negative error code -- Failure. + + @dependencies + None. + */ +int qurt_qdi_close(int handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_constants.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_constants.h new file mode 100755 index 0000000000000..4866fada067f0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_constants.h @@ -0,0 +1,193 @@ +#ifndef QDI_CONSTANTS_H +#define QDI_CONSTANTS_H + +/** + @file qurt_qdi_constants.h + @brief Predefined invocation methods for drivers. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2013-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc.. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Method numbers used for QDI. +|| +|| Intended grouping of method numbers for QDI +|| including future usage: +|| +|| Method 0 should always be unused and not responded to by +|| any driver. +|| Methods 1 and 2 are reserved for name registration and +|| name lookup. +|| Methods 3 through 31 are reserved for POSIX-type operations +|| on open handles. +|| Methods 32 through 127 are reserved for the QDI infrastructure +|| and may be extended in the future to provide standard +|| driver debug services, management services, and system +|| notifications. +|| Methods 128 through 255 are reserved for the use of automatically +|| generated methods such as might be generated by an IDL (interface +|| definition language). The infrastructure may be extended to +|| perform services on these methods based on information provided +|| by the IDL, such as automatic buffer validation, etc. These +|| method numbers should not be used for any "ad hoc" methods. +|| Methods with number >= 256 are "private" method numbers that are +|| outside the scope of the QDI infrastructure. Drivers that want +|| to generate and consume their own "ad hoc" methods are free to +|| use these method numbers as they wish. The infrastructure does +|| not generate these method numbers or respond to them, but +|| passes them on unmolested. +|| +|| All driver implementations *should* return a value of +|| -1 when called with an unsupported method. The standard error +|| return value for POSIX APIs is -1, so we emulate that behavior +|| here. +*/ +/** @cond */ +#define QDI_UNUSED 0 +#define QDI_DEVNAME_REGISTER 1 +#define QDI_OPEN 2 +#define QDI_CLOSE 3 +#define QDI_READ 4 +#define QDI_WRITE 5 +#define QDI_IOCTL 6 +#define QDI_MMAP 7 +#define QDI_OS_FILEOPEN 8 +#define QDI_FLEN 9 +#define QDI_UNLINK 10 +#define QDI_FTELL 22 +#define QDI_SEEK 23 +#define QDI_FSTAT 24 + +#define QDI_FSNAME_REGISTER 150 +#define QDI_FS_OPEN 151 +#define QDI_MMAP2 153 +#define QDI_MPROTECT2 154 +#define QDI_MUNMAP2 155 + +#define QDI_CLIENT_HANDLE_OBJREF_GET 10 + +#define QDI_OS_PROCESS_LOAD 12 +#define QDI_OS_PROCESS_CHOOSE_ASID 13 + +#define QDI_OS_SET_GP 26 +#define QDI_CLIENT_HANDLE_CALLBACK 27 + +#define QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T 19 //reused +#define QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T 80 +#define QDI_CLIENT_HANDLE_HANDLE_RELEASE 81 +#define QDI_CLIENT_HANDLE_COPY_FROM_USER 82 +#define QDI_CLIENT_HANDLE_COPY_TO_USER 83 +#define QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE 86 +#define QDI_CLIENT_HANDLE_SAFE_CACHE_OPS 87 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK 41 +#define QDI_CLIENT_HLOSPOOL_INFO_GET 90 +#define QDI_CLIENT_HLOSPOOL2_INFO_GET 96 + +#define QDI_CLIENT_PID 44 +#define QDI_CLIENT_ASID QDI_CLIENT_PID + +#define QDI_OS_CLIENT_INFO_GET 48 + +#define QDI_OS_MEM_LOOKUP_PHYSADDR 57 + +#define QDI_OS_THREAD_ITERATOR_CREATE 68 +#define QDI_OS_THREAD_ITERATOR_NEXT 69 + +#define QDI_OS_SYSENV 78 + +#define QDI_REGION_USERMALLOC_INIT 180 // This method is for generic handle + + +#define QDI_CLIENT_HANDLE_USER_MALLOC 84 +#define QDI_CLIENT_HANDLE_USER_FREE 85 + +#define QDI_SIGNAL_GROUP_SIGNAL_CREATE 96 +#define QDI_SIGNAL_GROUP_WAIT 98 +#define QDI_SIGNAL_GROUP_POLL 99 +#define QDI_SIGNAL_SET 96 +#define QDI_SIGNAL_CLEAR 97 +#define QDI_SIGNAL_WAIT 98 +#define QDI_SIGNAL_POLL 99 + +#define QDI_OS_WAIT_FOR_MAIN_REAPER 104 + +#define QDI_CLIENT_HANDLE_REFPROXY_INSTALL 105 +#define QDI_CLIENT_HANDLE_REFPROXY_ADD 106 +#define QDI_CLIENT_HANDLE_REFPROXY_REMOVE 107 + +#define QDI_CLIENT_HANDLE_DETACH 116 + +#define QDI_OS_RESERVED1 139 + +#define QDI_CLIENT_HANDLE_BUFFER_LOCK2 142 + +#define QDI_DT_REGISTER 158 +#define QDI_OPEN_DEVICE 159 +#define QDI_OPEN_FROM_DT 160 + +#define QDI_PRIVATE 256 /* Method numbers beginning at 256 + are private method numbers, which + are device-specific and available + for use by device implementors. */ +/* +|| Permission bitmasks for use with qurt_qdi_lock_buffer(). +|| +|| Make sure these match with permission values from qurt_perm_t. +*/ +/** @endcond */ + +/** @addtogroup driver_support_constants +@{ */ +#define QDI_PERM_W 2 /**< Write access. */ +#define QDI_PERM_R 1 /**< Read access. */ +#define QDI_PERM_RW (QDI_PERM_R | QDI_PERM_W) /**< Read/write access. */ + +#define QDI_HANDLE_LOCAL_CLIENT 3 /**< Local client. */ +#define QDI_HANDLE_GENERIC 4 /**< Generic. */ + +#define QDI_REFCNT_BASE 0x510000 /**< */ +#define QDI_REFCNT_MAXED 0x51FFFD /**< */ +#define QDI_REFCNT_INIT 0x51FFFE /**< Driver object is temporary and is eventually deleted.*/ +#define QDI_REFCNT_PERM 0x51FFFF /**< Driver object is permanent and is never deleted. */ +/** @} */ /* end_addtogroup driver_support_constants */ + +/** @cond */ +/* +|| Flags used by process loaders. +*/ + +#define QDI_OS_PROCESS_FLAGS_ISLAND_RESIDENT 0x1 /* Set this flag to request the loaded process + to have island residency. */ +#define QDI_OS_PROCESS_FLAGS_ROOT_RESIDENT 0x2 /* Set this flag to request the loaded process + to have root residency, for example, DL Pager. */ +/* +|| Constants used for qurt_event register API, type field. +*/ + +#define QURT_PROCESS_EXIT 1 + +/* +|| Constants used by QDI extensions. +*/ + +#define QURT_QDI_SINGLETON_TYPE_TRUE 0 +#define QURT_QDI_SINGLETON_TYPE_FALSE 1 +#define QURT_QDI_SINGLETON_TYPE_PER_PROCESS 2 +/** @endcond */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QDI_CONSTANTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_driver.h new file mode 100755 index 0000000000000..e044e25f1bb72 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_driver.h @@ -0,0 +1,868 @@ +#ifndef QURT_QDI_DRIVER_H +#define QURT_QDI_DRIVER_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver. + + EXTERNALIZED FUNCTIONS + None + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None + + Copyright (c) 2018, 2019-2021, 2023 Qualcomm Technologies, Inc. + All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include "stddef.h" +#include "qurt_qdi.h" +#include "qurt_types.h" +#include "qurt_callback.h" +#include "qurt_qdi_constants.h" +#include "qurt_qdi_imacros.h" +#include "qurt_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| This gives the canonical form for the arguments to a QDI +|| driver invocation function. The arguments are as follows: +|| +|| int client_handle (R0) QDI handle that represents the client +|| that made this QDI request. If the +|| client is remote, this is a +|| variable handle; if the client is local +|| (same thread and process), this is +|| set to QDI_HANDLE_LOCAL_CLIENT. +|| +|| qurt_qdi_obj_t *obj (R1) Points at the qdi_object_t structure +|| on which this QDI request is being made. +|| The qdi_object_t structure is usually +|| the first element of a larger structure +|| that contains state associated with the +|| object; because it is usually the first +|| element, the object pointers can be freely +|| interchanged through casts. +|| +|| int method (R2) Integer QDI method that represents +|| the request type. +|| +|| qurt_qdi_arg_t arg1 (R3) First three general purpose arguments +|| qurt_qdi_arg_t arg2 (R4) to the invocation function are passed in +|| qurt_qdi_arg_t arg3 (R5) these slots. +|| +|| qurt_qdi_arg_t arg4 (SP+0) Arguments beyond the first three are +|| qurt_qdi_arg_t arg5 (SP+4) passed on the stack. +|| qurt_qdi_arg_t arg6 (SP+8) +|| qurt_qdi_arg_t arg7 (SP+12) +|| qurt_qdi_arg_t arg8 (SP+16) +|| qurt_qdi_arg_t arg9 (SP+20) +|| +|| The canonical form of the invocation function takes a +|| total of 12 arguments, but not all of them are used. In general, +|| the QDI infrastructure only passes those arguments provided by +|| the caller; if the invocation function accesses additional +|| arguments beyond those provided by the caller, the values are not +|| useful. +*/ +/** @cond */ +#define QDI_INVOKE_ARGS \ + int, struct qdiobj *, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define QDI_EXT_INVOKE_ARGS \ + int, qurt_qdi_man_obj_t*, int, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t, \ + qurt_qdi_arg_t, qurt_qdi_arg_t, qurt_qdi_arg_t + +#define BUFFER_LOCK 1 +#define BUFFER_UNLOCK 0 + +struct qdiobj; +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef union { + void *ptr; /**< Pointer to the driver handle. */ + int num; /**< Method number. */ +} qurt_qdi_arg_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI driver version */ +typedef union { + int num; + struct { + short major; /** Driver major version number. */ + short minor; /** Driver minor version number. */ + }; +} qurt_qdi_version_t; + +typedef int (*qurt_qdi_pfn_invoke_t)(QDI_INVOKE_ARGS); +typedef void (*qurt_qdi_pfn_release_t)(struct qdiobj *); +/** @endcond */ +/** @addtogroup driver_support_types +@{ */ +typedef struct qdiobj { + qurt_qdi_pfn_invoke_t invoke; /**< Invocation function that implements the driver methods.*/ + int refcnt; /**< Reference count, an integer value maintained by the QDI infrastructure that tracks the number of + references to a driver instance. */ + qurt_qdi_pfn_release_t release; /**< Release function that performs details associated with deleting an instance + of the driver object.*/ +} qurt_qdi_obj_t; +/** @} */ /* end_addtogroup driver_support_types */ +/** @cond */ +/** QuRT QDI managed object */ +typedef struct qurt_qdi_man_obj +{ + qurt_qdi_obj_t qdi_obj; + union + { + struct qurt_qdi_ext_driver * opener_obj; + struct qurt_qdi_ext_device * device_obj; + }; +}qurt_qdi_man_obj_t; + +typedef int (*qurt_qdi_ext_pfn_create_t)(int client_id, const char *name, qurt_qdi_version_t version, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_create_device_t)(int client_id, const char *name, qurt_qdi_version_t version, struct qurt_qdi_ext_device * device, qurt_qdi_man_obj_t **qdi_obj); +typedef int (*qurt_qdi_ext_pfn_invoke_t)(QDI_EXT_INVOKE_ARGS); +typedef void (*qurt_qdi_ext_pfn_destroy_t)(qurt_qdi_man_obj_t *qdi_obj); +typedef int (*qurt_qdi_ext_pfn_probe_t)(void *handle, struct qurt_qdi_ext_device **device); + +typedef struct qurt_qdi_ext_obj_info{ + qurt_qdi_man_obj_t *obj; + int qdi_client_id; + struct qurt_qdi_ext_obj_info *next; +}qurt_qdi_ext_obj_info_t; +typedef struct qurt_qdi_ext_obj_info *qurt_qdi_ext_obj_info_ptr; + +/** QuRT QDI device */ +//temporarily add this back while there are still drivers who statically define this structure +struct qurt_qdi_device { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; +}; +typedef struct qurt_qdi_device qurt_qdi_man_device; + +struct qurt_qdi_ext_driver { + qurt_qdi_obj_t opener_obj; + const char* name; + char island_resident; + unsigned char singleton; + qurt_qdi_ext_pfn_create_t create; + qurt_qdi_ext_pfn_invoke_t invoke; + qurt_qdi_ext_pfn_destroy_t destroy; + qurt_mutex_t qurt_qdi_ext_list_lock; + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + qurt_qdi_ext_pfn_create_device_t create_device; + qurt_qdi_version_t version; + qurt_qdi_ext_pfn_probe_t probe; + const char* compatible; + struct qurt_qdi_ext_device * device_list; + //qurt_qdi_ext_device_ptr device_list; +}; +typedef struct qurt_qdi_ext_driver qurt_qdi_ext_driver_t; +//above replaces qurt_qdi_man_device + +extern int qurt_qdi_obj_ref_inc(qurt_qdi_obj_t *); +extern int qurt_qdi_obj_ref_dec(qurt_qdi_obj_t *); + +extern int qurt_qdi_ext_opener (QDI_INVOKE_ARGS); +/** @endcond */ +/**@ingroup func_qurt_qdi_method_default + Processes a method that is unrecognized or unsupported in the driver invocation function. + All arguments passed to the current invocation function (Section @xref{sec:invocationFunction}) must be forwarded + to this function. + + @note1hang Invocation functions must process all unrecognized or unsupported methods + by calling this function. + + @return + None. + + @dependencies + None. +*/ +extern int qurt_qdi_method_default(QDI_INVOKE_ARGS); + +/**@ingroup func_qurt_qdi_handle_create_from_obj_t + Allocates a new device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[out] obj Pointer to the driver object. + + @return + Non-negative integer -- Success; this value is the new handle. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_invoke + Allocates a new island device handle for use with the specified driver object. + + @param[in] client_handle Client handle obtained from the current invocation function (Section 3.4.1). + @param[in] obj Pointer. + + @return + Non-negative integer value that is the new handle -- Success. \n + Negative return value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_island_handle_create_from_obj_t(int client_handle, qurt_qdi_obj_t *obj) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_ISLAND_HANDLE_CREATE_FROM_OBJ_T, + obj); +} + +/**@ingroup func_qurt_qdi_handle_release + Deallocates the specified device handle. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] handle_to_release Handle to release. + + @return + 0 -- Success. \n + Negative value -- Error. + + @dependencies + None. +*/ +static __inline int qurt_qdi_handle_release(int client_handle, int handle_to_release) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_HANDLE_RELEASE, + handle_to_release); +} + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_handle(int client_handle, int object_handle) +{ + qurt_qdi_obj_t *ret; + + ret = NULL; + + qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_OBJREF_GET, + object_handle, + &ret); + + return ret; +} + +/**@ingroup func_qurt_client_add_memory + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory(int client_handle, qurt_addr_t phys_addr, qurt_size_t size); + +/**@ingroup func_qurt_client_add_memory2 + Adds a physical address range to the HLOS physpool of the caller user PD. + + @param[in] client_handle Obtained from the current invocation function (Section 3.4.1). + @param[in] phys_addr Starting 36-bit address of the physical address range. + @param[in] size Size. + + @return + #QURT_EOK -- Pages successfully added. + + @dependencies + None. +*/ +int qurt_client_add_memory2(int user_client_handle, qurt_paddr_64_t phys_addr, qurt_size_t size); + +static __inline qurt_qdi_obj_t * +qurt_qdi_objref_get_from_pointer(qurt_qdi_obj_t *objptr) +{ + qurt_qdi_obj_t * ret = NULL; + + if (qurt_qdi_obj_ref_inc(objptr) < 0) { + ret = NULL; + } else { + ret = objptr; + } + + return ret; +} + +static __inline void +qurt_qdi_objref_release(qurt_qdi_obj_t *objptr) +{ + if (qurt_qdi_obj_ref_dec(objptr) == 1) { + (*objptr->release)(objptr); + } +} + +/**@ingroup func_qurt_qdi_copy_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the driver buffer. + @param[in] src Base address of the user buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_from_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_FROM_USER, + dest, src, len); +} + +/**@ingroup qurt_qdi_copy_string_from_user + Copies the contents of a user memory buffer into the current driver. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param dest Base address of the driver buffer. + @param src Base address of the user buffer. + @param len Number of bytes to copy. NOTE: This is the destination buffer length. + + @return + Negative error result -- privilege or security violation, the copy operation + has crossed a privilege boundary. + + @dependencies + None. +*/ +int qurt_qdi_copy_string_from_user(int client_handle, char *dest, const char *src, unsigned len); + +/**@ingroup func_qurt_qdi_copy_to_user + Copies the contents of a driver memory buffer to user memory. + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] dest Base address of the user buffer. + @param[in] src Base address of the driver buffer. + @param[in] len Number of bytes to copy. + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_copy_to_user(int client_handle, void *dest, const void *src, unsigned len) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_COPY_TO_USER, + dest, src, len); +} + +/**@ingroup func_qurt_qdi_safe_cache_ops + Do cache operations on user memory + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] addr Base address of the user memory. + @param[in] size Size of the user memory. + @param[in] opcode Cache operations (QURT_MEM_CACHE_FLUSH, QURT_MEM_CACHE_INVALIDATE...) + @param[in] type Cache type (QURT_MEM_ICACHE, QURT_MEM_DCACHE) + + @return + Negative value -- Indicates a privilege or security violation, the copy operation has crossed a + privilege boundary + + @dependencies + None. +*/ +static __inline int qurt_qdi_safe_cache_ops(int client_handle, qurt_addr_t addr, qurt_size_t size, + qurt_mem_cache_op_t opcode, qurt_mem_cache_type_t type) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SAFE_CACHE_OPS, + addr, size, opcode, type); +} + + +/**@ingroup func_qurt_qdi_buffer_lock + Prepares for the direct manipulation of a potentially untrusted buffer provided by a QDI + client. + + This function is used to permit a trusted driver to safely access memory that is + provided by a potentially untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + + This function performs the following security checks: \n + - Verifies that the entire buffer is accessible to the client. \n + - Ensures that the pointer remains valid for the remainder of the QDI driver + operation. \n + + @note1hang User buffer addresses are valid only for the duration of the current driver + invocation. + + @param[in] client_handle Obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param[in] buf Pointer to the base address of the client buffer address. + @param[in] len Buffer length (in bytes). + @param[in] perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + - #QDI_PERM_R -- Read access \n + - #QDI_PERM_W -- Write access \n + - #QDI_PERM_RW -- Read/write access @tablebulletend + @param[out] obuf Pointer to the buffer address that the driver must use to access the buffer. + + @return + Negative value -- Error; the operation crosses a privilege boundary, indicating a privilege or security violation. \n + Nonzero value -- User passed a buffer that does not fulfill the requested read/write access permission. + In this case the QDI driver call must be terminated cleanly, with an appropriate error code + returned to the client. \n + Zero -- Success; when this occurs the QDI driver must use the pointer at *obuf to access memory, and not the + pointer passed in as buf -- even if the user process changes the mapping of memory at buf, + the mapping of memory at *obuf remains valid until the driver invocation completes. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK, + buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_lock2 + Prepares for the direct manipulation of a possibly-untrusted buffer provided by a QDI + client. + This API permits a trusted driver to safely access memory + provided by a possibly-untrusted client. A driver calls this function to obtain a safe buffer + pointer for accessing the memory. + This function performs the following security checks: \n + -- Entire buffer is accessible to the client. \n + -- Entire buffer is mapped with permissions passed in perms field \n + -- Entire buffer is physically contiguous \n + In addition to the security checks, the API also locks the client mapping such that the client + cannot remove the mapping while the physical memory is used by the trusted + driver. \n + + @note1 Drivers are responsible for calling qurt_qdi_buffer_unlock() at appropriate time. Not + pairing qurt_qdi_buffer_unlock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client. If the client exits abruptly, the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Safe buffer + unmapping or user buffer unlock is not supported in Island mode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param perms Bitmask value that specifies the read or write access to perform on the + client buffer: \n + -- #QDI_PERM_R -- Read access \n + -- #QDI_PERM_W -- Write access \n + -- #QDI_PERM_RW -- Read/write access \n + @param obuf Optional parameter that returns a pointer to the buffer address that + the driver must use to access the buffer. If NULL is passed, the API + only performs security checks and does not create a mapping to access the user buffer in + a safe way. + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EPRIVILEGE -- One of the security checks on the user buffer failed. \n + QURT_EFAILED -- Mapping cannot be created for the trusted driver. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_lock2(int client_handle, void *buf, unsigned len, + unsigned perms, void **obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_LOCK, buf, len, perms, obuf); +} + +/**@ingroup func_qurt_qdi_buffer_unlock + This API is paired with qurt_qdi_buffer_lock2(). A temporary overlapping mapping + created for the driver is removed. Client mapping for the user buffer is + unlocked. + + @note1 Drivers are responsible for pairing this with qurt_qdi_buffer_lock(). Not + pairing qurt_qdi_buffer_lock() with this API leads to resource leakages and + process exit failures. Drivers can keep track of which buffers are locked for + a particular client, and if the client exits abruptly, all the buffers can be + unlocked on driver release invocation for the exiting client. + + @note2 This API is supported in limited capacity when called from Island mode. Actual + unmapping of driver accessible memory or unlocking of the buffer is not + supported in Island bode. + + @param client_handle Obtained from the current invocation function (Section 3.4.1). + @param buf Pointer to the base address of the client buffer address. + @param len Buffer length (in bytes). + @param obuf Safe buffer address that was returned in the obuf field after calling + qurt_qdi_buffer_lock2(). + + @return + QURT_EINVALID -- Arguments passed to the API are invalid. User buffer pointer is NULL or length of the + buffer is 0. \n + QURT_EOK -- Lock operation was successful. When this occurs, the QDI driver must use the + pointer at *obuf to perform its memory accesses, and not the + pointer passed in as buf. \n + other results -- Safe buffer unmapping failed or unlocking of user buffer failed \n. + + @dependencies + None. +*/ +static __inline int qurt_qdi_buffer_unlock(int client_handle, void *buf, unsigned len, + void *obuf) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_BUFFER_LOCK2, + BUFFER_UNLOCK, buf, len, obuf); +} + +/**@ingroup func_qurt_qdi_user_malloc + Allocates memory area in the QDI heap that is read/write accessible to both the driver and + the client. \n + @note1hang The QDI heap has a limited amount of memory available, and only the + device driver can free the allocated memory. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param size Size. + + @return + Non-zero -- Success; this returned value points to the allocated memory area. \n + Zero -- Error. + + @dependencies + None. +*/ +void *qurt_qdi_user_malloc(int client_handle, unsigned size); + +/**@ingroup func_qurt_qdi_user_free + Deallocates memory area in the QDI heap. + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param ptr Pointer. + + @dependencies + None. +*/ +void qurt_qdi_user_free(int client_handle, void *ptr); + +/**@ingroup funct_qurt_qdi_client_detach + Detaches a client (a process), indicating that the client does not + participate in the qurt_wait() mechanism. This behavior + is opt-in and irrevocable. When a client is detached, it can + not be un-detached. + + @param client_handle Handle of the client to detach. + + @return + Zero -- Success. Detachable clients always return success. + Nonzero value -- client_handle did not refer to a + detachable user client. + + @dependencies + None. +*/ +static __inline int qurt_qdi_client_detach(int client_handle) +{ + return qurt_qdi_handle_invoke(client_handle, QDI_CLIENT_HANDLE_DETACH); +} + +/**@ingroup func_qurt_qdi_signal_group_create + Creates a new signal group for use in a device driver. + A QDI signal group contains up to 32 signals, which can be operated on either + individually (using the qurt_qdi_signal_* functions) or as a group (using the + qurt_qdi_signal_group_* functions). \n + @note1hang Driver implementation is responsible for using the proper signal group + handle in any given situation. \n + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @param client_handle Client handle obtained from the current invocation function (Section @xref{sec:invocationFunction}). + @param p_signal_group_handle_local Returns a handle intended for use by code that + resides in the same context and process as the created signal group + (for example, the device driver implementation that allocated the + signal group). + @param p_signal_group_handle_remote Returns a handle intended for use by code + that resides in a different context and process than the created signal group + (for example, the user-mode client of an OS driver). + + @return + Zero return value indicates success.\n + Negative return value indicates could not create signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_create(int client_handle, + int *p_signal_group_handle_local, + int *p_signal_group_handle_remote) +{ + return qurt_qdi_handle_invoke(client_handle, + QDI_CLIENT_HANDLE_SIGNAL_GROUP_CREATE, + p_signal_group_handle_local, + p_signal_group_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_group_wait + Suspends the current thread until any of the signals are set in the specified signal group. + + If a signal is set in a signal group object, and a thread waits on the signal group object, + the thread is awakened. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @param signal_group_handle Handle of the signal group. + + @return + If the client is remote: + QURT_EOK -- Wait complete \n + QURT_ECANCEL -- Wait cancelled.\n + If the client is local, returns a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_wait(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_group_poll + Returns a value that indicates if any of the signals are set in the specified signal group. + + @param signal_group_handle Handle of the signal group. + + @return + 1 -- Indicates whether any of the signals are set in the signal group.\n + 0 -- Indicates that none of the signals are set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_group_poll(int signal_group_handle) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_POLL); +} + + +/**@ingroup func_qurt_qdi_signal_create + Creates a new signal in the specified signal group. + For more information on signals, see the Hexagon QuRT RTOS User Guide (80-VB419-78). + + @note1hang Driver implementation is responsible for using the proper signal handle in + any given situation. + + @param signal_group_handle Handle of an existing signal group. + @param p_signal_handle_local Returns a handle intended for use by code that resides in + the same context and process as the created signal (for example, + the device driver implementation that allocated the signal). + @param p_signal_handle_remote Returns a handle intended for use by code that resides in + a different context and process than the created signal (for + example, the user-mode client of an OS driver). + + @return + Nonzero value -- No more signals can be created in the specified + signal group. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_create(int signal_group_handle, + int *p_signal_handle_local, + int *p_signal_handle_remote) +{ + return qurt_qdi_handle_invoke(signal_group_handle, + QDI_SIGNAL_GROUP_SIGNAL_CREATE, + p_signal_handle_local, + p_signal_handle_remote); +} + +/**@ingroup func_qurt_qdi_signal_set + Sets the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_set(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_SET); +} + +/**@ingroup func_qurt_qdi_signal_clear + Clears the signal in the specified signal object. + + @param signal_handle Handle of the signal. + + @return + Always returns 0. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_clear(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_CLEAR); +} + +/**@ingroup func_qurt_qdi_signal_wait + Suspends the current thread until the specified signal is set. + If a signal is set in a signal object, and a thread waits on the signal object, the + thread is awakened. If the awakened thread has higher priority than the current thread, a + context switch may occur. + + @param signal_handle Handle of the signal. + + @return + If client is remote: + QURT_EOK -- Wait complete. \n + QURT_ECANCEL -- Wait cancelled.\n + If client is local, return a 32-bit word with current signals. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_wait(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_WAIT); +} + +/**@ingroup func_qurt_qdi_signal_poll + Returns a value that indicates if the specified signal is set. + + @param signal_handle Handle of the signal. + + @return + 1 -- Signal is set. \n + 0 -- Signal is not set. + + @dependencies + None. +*/ +static __inline int qurt_qdi_signal_poll(int signal_handle) +{ + return qurt_qdi_handle_invoke(signal_handle, + QDI_SIGNAL_POLL); +} + +/**@ingroup func_qurt_qdi_devname_register + Registers a QDI device with the generic QDI object in the + current QDI context. + + This function registers an exact name or a directory prefix with a QDI opener object. + Future invocations of qurt_qdi_open() in the context of the caller invokes the + opener object if a match is detected. + + Directory prefix names are specified by ending the name with a forward slash character. + + Example of an exact name: + @code qurt_qdi_devname_register(/dev/foobar, foobar_opener);@endcode + + Example of a directory prefix: + @code qurt_qdi_devname_register(/pipedev/, pipedev_opener);@endcode + + Given the two registrations shown above, the only qurt_qdi_open() requests to + direct to the foobar_opener object are requests for the exact name + "/dev/foobar", Any request beginning with "/pipedev/" is directed to the + pipedev_opener object. + + The pipedev invocation function presumably examines the name argument to + determine exactly how to handle the request. The name is passed to the invocation + function in the a1.ptr argument (Section @xref{sec:invocationFunction}). + + @param name Device name or device name prefix. + @param opener Pointer to the opener object for the device. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. + + @dependencies + None. + */ +static __inline int qurt_qdi_devname_register(const char *name, + qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, + QDI_DEVNAME_REGISTER, + name, + opener); +} + +// Macros for backward compatibility with deprecated APIs +// (These will go away soon) + +#define qurt_qdi_register_devname(name, opener) \ + qurt_qdi_devname_register((name), (void *)(opener)) +#define qurt_qdi_new_handle_from_obj_t(handle, obj) \ + qurt_qdi_handle_create_from_obj_t((handle), (obj)) +#define qurt_qdi_release_handle(client_handle, handle) \ + qurt_qdi_handle_release((client_handle), (handle)) +#define qurt_qdi_lock_buffer(handle, buf, len, perms, obuf) \ + qurt_qdi_buffer_lock((handle), (buf), (len), (perms), (obuf)) +#define qurt_qdi_usermalloc(handle, size) \ + qurt_qdi_user_malloc((handle), (size)) +#define qurt_qdi_userfree(handle, ptr) \ + qurt_qdi_user_free((handle), (ptr)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_ext.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_ext.h new file mode 100755 index 0000000000000..383e1799a15d6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_ext.h @@ -0,0 +1,58 @@ +#ifndef QURT_QDI_EXT_H +#define QURT_QDI_EXT_H + +/** + @file qurt_qdi_driver.h + @brief Definitions, macros, and prototypes used when writing a + QDI driver + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2018, 2019-2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct qurt_qdi_ext_device { + qurt_qdi_ext_obj_info_ptr qurt_qdi_ext_obj_info_head; + struct qurt_qdi_ext_device * next; + char * instance; + fdt_node_handle context; +}; +typedef struct qurt_qdi_ext_device *qurt_qdi_ext_device_ptr; + +/**@ingroup func_qurt_qdi_dt_register + Registers a QDI device with the generic QDI object in the current QDI context, + if and only if a compatible device node is found in the device tree. This + function serves as a device tree aware wrapper for qurt_qdi_devname_register(). + + @param name Device name or device name prefix. + @param opener Pointer to QDI ext specialized opener object for the driver. + + @return + 0 -- Device was successfully registered. \n + Negative error code -- Device was not registered. +*/ +static __inline int qurt_qdi_dt_register(const char *name, qurt_qdi_obj_t *opener) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_DT_REGISTER, name, opener); +} + +static inline void qurt_qdi_ext_deviceobj_set_name (struct qurt_qdi_ext_device * device, char * name) +{ + device->instance = name; +} + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_imacros.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_imacros.h new file mode 100755 index 0000000000000..c0a8448ac87f8 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_imacros.h @@ -0,0 +1,34 @@ +#ifndef QURT_QDI_IMACROS_H +#define QURT_QDI_IMACROS_H + +/** + @file qurt_qdi_imacros.h + @brief Internal macros used for QDI. Mostly consists of tricky (and ugly) + preprocessor hacks that permit us to do varargs function invocations + where we pass optional arguments in registers and where we can do + type casting and checking automatically. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _QDMPASTE(a,b) _QDMPASTE_(a,b) +#define _QDMPASTE_(a,b) a##b +#define _QDMCNT(...) _QDMCNT_(__VA_ARGS__,12,11,10,9,8,7,6,5,4,3,2,1,0) +#define _QDMCNT_(a,b,c,d,e,f,g,h,i,j,k,l,cnt,...) cnt + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_proxy.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_proxy.h new file mode 100755 index 0000000000000..f1d8992ea8811 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_qdi_proxy.h @@ -0,0 +1,55 @@ +/*============================================================================= + + qurt_qdi_proxy.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef _QURT_QDI_PROXY_H +#define _QURT_QDI_PROXY_H + +#include "qurt_qdi_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* APIs allowing operation on the proxy object directly */ +int qurt_qdi_proxy_ref_create(void); + +/* APIs allowing to operate on proxy given a known proxy handle + * 1) using qdi handle of the object + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_handle(int proxy_handle, int qdi_handle); +int qurt_qdi_proxy_ref_sub_by_handle(int proxy_handle, int qdi_handle); + +/* 2) using object reference + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_qdi_proxy_ref_add_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); +int qurt_qdi_proxy_ref_sub_by_object(int proxy_handle, qurt_qdi_obj_t *obj_ptr); + +/* API allowing to associate a proxy object with a particular client given a client handle + * successfule return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_install (int client_handle, int proxy_handle); + +/* APIs allowing operation on proxy object from user client + * successful return: QURT_EOK, anything else -- failure + */ +int qurt_client_proxy_ref_add(int qdi_handle); +int qurt_client_proxy_ref_remove(int qdi_handle); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_QDI_PROXY_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex.h new file mode 100755 index 0000000000000..a013a0bbddb1d --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex.h @@ -0,0 +1,200 @@ +#ifndef QURT_RMUTEX_H +#define QURT_RMUTEX_H +/** + @file qurt_rmutex.h + Prototypes of rmutex API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013 - 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup func_qurt_rmutex_init + Initializes a recursive mutex object. + The recursive mutex is initialized in unlocked state. + + @datatypes + #qurt_mutex_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex_init(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_destroy + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_destroy(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex protects, and continues executing. + + If a thread performs a lock operation on a mutex that is already use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_lock_timed + Locks the specified recursive mutex. The wait must be terminated when the specified timeout expires.\n + + If a thread performs a lock operation on a mutex that is not in use, the thread + gains access to the shared resource that the mutex is protecting, and continues executing. + + If a thread performs a lock operation on a mutex that is already in use by another + thread, the thread is suspended. When the mutex becomes available again (because the + other thread has unlocked it), the thread is awakened and given access to the shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked by itself. However, the mutex does not become available to other threads until the + thread performs a balanced number of unlocks on the mutex. + If timeout expires, this wait must be terminated and no access to the mutex is granted. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + + */ +int qurt_rmutex_lock_timed(qurt_mutex_t *lock, unsigned long long int duration); + +/**@ingroup func_qurt_rmutex_unlock + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a mutex. When the mutex is + unlocked, the thread waiting on the mutex awakens. If the awakened + thread has higher priority than the current thread, a context switch occurs. + + @note1hang When a thread unlocks a recursive mutex, the mutex is not available until + the balanced number of locks and unlocks has been performed on the mutex. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex_unlock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock + Attempts to lock the specified recursive mutex.\n + + If a thread performs a try_lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that is protected by the mutex, and continues + executing.\n + If a thread performs a try_lock operation on a recursive mutex that another thread has + already locked, qurt_rmutex_try_lock immediately returns with a nonzero result + value. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex_try_lock(qurt_mutex_t *lock); + +/**@ingroup func_qurt_rmutex_try_lock_block_once + Attempts to lock a mutex object recursively. If the mutex is available, + it locks the mutex. If the mutex is held by the current thread, + it increases the internal counter and returns 0. If not, it returns a + nonzero value. + If the mutex is already locked by another thread, the caller thread is + suspended. When the mutex becomes available again (because the other + thread has unlocked it), the caller thread is awakened and tries to lock + the mutex; and if it fails, this function returns failure with a nonzero + value. If it succeeds, this function returns success with zero. + + @datatypes + #qurt_mutex_t + + @param[in] lock Pointer to the qurt_mutex_t object. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + @dependencies + None. + */ +int qurt_rmutex_try_lock_block_once(qurt_mutex_t *lock); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex2.h new file mode 100755 index 0000000000000..a37e7e4458c4b --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_rmutex2.h @@ -0,0 +1,183 @@ +#ifndef QURT_RMUTEX2_H +#define QURT_RMUTEX2_H +/** + @file qurt_rmutex2.h + @brief Prototypes of rmutex2 API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup mutex_types +@{ */ +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT rmutex2 type. + Mutex type used with rmutex2 APIs. + */ +typedef struct { + /** @cond */ + unsigned int holder __attribute__((aligned(8))); /* UGP value of the mutex holder. */ + unsigned short waiters; /* Number of waiting threads. */ + unsigned short refs; /* Number of references to this mutex. */ + unsigned int queue; /* Kernel-maintained futex queuevalue. */ + unsigned int excess_locks; /* Number of excess times the holder has locked the mutex. */ + /** @endcond */ +} qurt_rmutex2_t; +/** @} */ /* end_addtogroup mutex_types */ +/** @cond internal_only*/ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_rmutex2_init + + @deprecated use #qurt_rmutex_init instead. + + Initializes a recursive mutex object. + + The recursive mutex is initially unlocked. + + Objects of type rmutex2 solve a potential race condition between + unlock() and destroy() operations. + + @datatypes + #qurt_rmutex2_t + + @param[out] lock Pointer to the recursive mutex object. + + @return + None. + + @dependencies + None. + */ +void qurt_rmutex2_init(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_destroy + + @deprecated use #qurt_rmutex_destroy instead. + + Destroys the specified recursive mutex. \n + @note1hang Recursive mutexes must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont In general, application code must destroy an rmutex2 object prior to + deallocating it; calling qurt_rmutex2_destroy() before deallocating it ensures + that all qurt_rmutex2_unlock() calls complete. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to destroy. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_destroy(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_lock + + @deprecated use #qurt_rmutex_lock instead. + + Locks the specified recursive mutex. \n + + If a thread performs a lock operation on a recursive mutex that is not in use, the + thread gains access to the shared resource that the mutex protects, and continues + to execute. + + If a thread performs a lock operation on a recursive mutex that another thread is using, + the thread is suspended. When the mutex becomes available again + (because the other thread has unlocked it), the thread is awakened and given access to the + shared resource. + + @note1hang A thread is not suspended if it locks a recursive mutex that it has already + locked, but the mutex does not become available until the thread performs a + balanced number of unlocks on the mutex. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_lock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_unlock + + @deprecated use #qurt_rmutex_unlock instead. + + Unlocks the specified recursive mutex. \n + More than one thread can be suspended on a recursive mutex. When the mutex is + unlocked, only the highest-priority thread waiting on the mutex awakens. If the + awakened thread has higher priority than the current thread, a context switch occurs. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to unlock. + + @return + None. + + @dependencies + None. + + */ +void qurt_rmutex2_unlock(qurt_rmutex2_t *lock); + +/**@ingroup func_qurt_rmutex2_try_lock + + @deprecated use #qurt_rmutex_try_lock instead. + + Attempts to lock the specified recursive mutex.\n + + Non-blocking version of qurt_rmutex2_lock(). When a call to qurt_rmutex2_lock() + succeeds immediately, this function behaves similarly, returning 0 for success. + When a call to qurt_rmutex2_lock() does not succeed immediately, this function has + no effect and returns nonzero for failure. + + @datatypes + #qurt_rmutex2_t + + @param[in] lock Pointer to the recursive mutex object to lock. + + @return + 0 -- Success. \n + Nonzero -- Failure. + + */ +int qurt_rmutex2_try_lock(qurt_rmutex2_t *lock); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_RMUTEX2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sclk.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sclk.h new file mode 100755 index 0000000000000..a83cf5f1db889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sclk.h @@ -0,0 +1,145 @@ +#ifndef QURT_SCLK_H +#define QURT_SCLK_H +/** + @file qurt_sclk.h + @brief Header file describing the APIs supported by QuRT system SCLK + feature. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2021, 2023 Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + + +/*============================================================================= + + INCLUDE FILES + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + Conversion from microseconds to sleep ticks. + */ +#define QURT_SYSCLOCK_TIMETICK_FROM_US(us) ((us) * 192ULL / 10UL) +#define qurt_sysclock_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_SYSCLOCK_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_SYSCLOCK_MAX_DURATION (1042499uLL * 3600uLL * 1000uLL * 1000uLL) +#define qurt_sysclock_max_duration() QURT_SYSCLOCK_MAX_DURATION +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_SYSCLOCK_MAX_DURATION_TICKS (1042499uLL * 3600uLL * 19200000uLL) +#define qurt_sysclock_max_duration_ticks() QURT_SYSCLOCK_MAX_DURATION_TICKS +/** + Sleep timer error margin for Qtimer is 192 ticks ~10 us. +*/ +#define QURT_SYSCLOCK_ERROR_MARGIN 192U //QURT_TIMER_MIN_DURATION*timer_freq; +#define qurt_sysclock_error_margin() QURT_SYSCLOCK_ERROR_MARGIN + +/*============================================================================= + + DATA DECLARATIONS + +=============================================================================*/ + +/**@ingroup func_qurt_sysclock_get_hw_ticks + @xreflabel{sec:qurt_sysclock_get_hw_ticks} + Gets the hardware tick count.\n + Returns the current value of a 64-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation must be used with care because of the wrap-around behavior. + + @return + Integer -- Current value of 64-bit hardware counter. + + @dependencies + None. + */ +unsigned long long qurt_sysclock_get_hw_ticks (void); + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_32 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_32} + Gets the hardware tick count in 32 bits.\n + Returns the current value of a 32-bit hardware counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 32 bits are the lower 32 bits of the Qtimer counter. + + @return + Integer -- Current value of the 32-bit timer counter. + + @dependencies + None. + */ +static inline unsigned long qurt_sysclock_get_hw_ticks_32 (void) +{ + //Beginning with v61 there is a HW register that can be read directly. + unsigned long count; + __asm__ __volatile__ (" %0 = c30 " : "=r"(count)); + return count; +} + + +/**@ingroup func_qurt_sysclock_get_hw_ticks_16 + @xreflabel{sec:qurt_sysclock_get_hw_ticks_16} + Gets the hardware tick count in 16 bits.\n + Returns the current value of a 16-bit timer counter. The value wraps around to zero + when it exceeds the maximum value. + + @note1hang This operation is implemented as an inline C function, and should be called from a C/C++ program. + The returned 16 bits are based on the value of the lower 32 bits in Qtimer + counter, right shifted by 16 bits. + + @return + Integer -- Current value of the 16-bit timer counter, calculated from the lower 32 bits in the + Qtimer counter, right shifted by 16 bits. + + @dependencies + None. + */ + + +static inline unsigned short qurt_sysclock_get_hw_ticks_16 (void) +{ + unsigned long ticks; + + //Beginning with v61 there is a HW register that can be read directly. + __asm__ __volatile__ (" %0 = c30 " : "=r"(ticks)); + __asm__ __volatile__ ( "%0 = lsr(%0, #16) \n" :"+r"(ticks)); + + return (unsigned short)ticks; +} +unsigned long long qurt_timer_timetick_to_us(unsigned long long ticks); +#define qurt_sysclock_timetick_to_us(ticks) qurt_timer_timetick_to_us(ticks) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif /* QURT_SCLK_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_secure_proc.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_secure_proc.h new file mode 100755 index 0000000000000..f40c7deb9bca1 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_secure_proc.h @@ -0,0 +1,53 @@ +#ifndef QURT_SECURE_PROC_H +#define QURT_SECURE_PROC_H + +/** + @file qurt_secure_proc.h + @brief Definitions, macros, and prototypes used for handling secure process + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2015, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_process_migrate_secure_process + Migrate the user process to Qurt secure process + + @param secure_phy_address Physical starting address of secure memory + @param secure_memory_size Size of secure memory + @param entry Entry function to secure process + + @return + EOK + Negative return value -- Error. + + @dependencies + None. +*/ +int qurt_process_migrate_secure_process(unsigned long long secure_phy_address, unsigned int secure_memory_size, void entry(unsigned)); + +/**@ingroup qurt_process_get_migration_mem_size + get the size of all writable memory regions in a user PD. This is for preparation on secure process migration. + + @return + size of all writable memory regions in a user PD. + + @dependencies + None. +*/ +int qurt_process_get_migration_mem_size(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sem.h new file mode 100755 index 0000000000000..ee5ce4b2d94ab --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_sem.h @@ -0,0 +1,252 @@ +#ifndef QURT_SEM_H +#define QURT_SEM_H +/** + @file qurt_sem.h + Prototypes of semaphore API. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup semaphore_types +@{ */ + +/** QuRT semaphore type. */ +typedef union { + /** @cond */ + unsigned int raw[2] __attribute__((aligned(8))); + struct { + unsigned short val; /**< */ + unsigned short n_waiting; /**< */ + unsigned int reserved1; /**< */ + unsigned int queue; /**< */ + unsigned int reserved2; /**< */ + }X; /** @endcond */ +} qurt_sem_t; +/** @} */ /* end_addtogroup semaphore_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_sem_add + Releases access to a shared resource (the specified amount increments the semaphore count value).\n + When a thread performs an add operation on a semaphore, the specified value increments the semaphore count. + The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing. \n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel repeatedly awakens the highest-priority waiting thread and decrements + the semaphore count value until either no waiting threads remain or the + semaphore count value is zero. If any of the awakened threads has higher priority + than the current thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] amt Amount to increment the semaphore count value. + + @return + Unused integer value. + + @dependencies + None. + + */ +int qurt_sem_add(qurt_sem_t *sem, unsigned int amt); + +/**@ingroup func_qurt_sem_up + Releases access to a shared resource. When a thread performs an up operation on a semaphore, + the semaphore count value increments. The result depends on the number of threads waiting + on the semaphore: \n + - When no threads are waiting, the current thread releases access to the shared resource + and continues executing.\n + - When one or more threads are waiting and the semaphore count value is nonzero, + the kernel awakens the highest-priority waiting thread and decrements the + semaphore count value. If the awakened thread has higher priority than the current + thread, a context switch can occur. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +static inline int qurt_sem_up(qurt_sem_t *sem) { return qurt_sem_add(sem,1); } + +/**@ingroup func_qurt_sem_down + Requests access to a shared resource. When a thread performs a down operation on a + semaphore, the result depends on the semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Unused integer value. + + @dependencies + None. + */ +int qurt_sem_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_down_timed + When a thread performs a down operation on a semaphore, the result depends on the + semaphore count value: \n + - When the count value is nonzero, it is decremented, and the thread gains access to the + shared resource and continues executing.\n + - When the count value is zero, it is not decremented, and the thread is suspended on the + semaphore. When the count value becomes nonzero (because another thread + released the semaphore) it is decremented, and the suspended thread is awakened + and gains access to the shared resource. Terminate the wait when the specified timeout expires. + If timeout expires, terminate this wait and grant no access to the shared resource. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + @param[in] duration Interval (in microseconds) duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION + + @return + #QURT_EOK -- Success \n + #QURT_ETIMEDOUT -- Timeout + + @dependencies + None. + */ +int qurt_sem_down_timed(qurt_sem_t *sem, unsigned long long int duration); + +/**@ingroup func_qurt_sem_try_down + @xreflabel{hdr:qurt_sem_try_down} + Requests access to a shared resource (without suspend). When a thread performs a try down + operation on a semaphore, the result depends on the semaphore count value: \n + - The count value is decremented when it is nonzero. The down operation returns 0 as + the function result, and the thread gains access to the shared resource and is free to + continue executing.\n + - The count value is not decremented when it is zero. The down operation returns -1 + as the function result, and the thread does not gain access to the shared resource + and should not continue executing. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + 0 -- Success. \n + -1 -- Failure. + + @dependencies + None. + + */ +int qurt_sem_try_down(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init + Initializes a semaphore object. + The default initial value of the semaphore count value is 1. + + @param[out] sem Pointer to the initialized semaphore object. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_destroy + Destroys the specified semaphore.\n + @note1hang Semaphores must be destroyed when they are no longer in use. Failure to do + this causes resource leaks in the QuRT kernel.\n + @note1cont Semaphores must not be destroyed while they are still in use. If this occur, + the behavior of QuRT is undefined. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to destroy. + + @return + None. + + @dependencies + None. + */ +void qurt_sem_destroy(qurt_sem_t *sem); + +/**@ingroup func_qurt_sem_init_val + Initializes a semaphore object with the specified value. + + @datatypes + #qurt_sem_t + + @param[out] sem Pointer to the initialized semaphore object. + @param[in] val Initial value of the semaphore count value. + + @return + None. + + @dependencies + None. + + */ +void qurt_sem_init_val(qurt_sem_t *sem, unsigned short val); + +/**@ingroup func_qurt_sem_get_val + Gets the semaphore count value.\n + Returns the current count value of the specified semaphore. + + @datatypes + #qurt_sem_t + + @param[in] sem Pointer to the semaphore object to access. + + @return + Integer semaphore count value + + @dependencies + None. + */ +static inline unsigned short qurt_sem_get_val(qurt_sem_t *sem ){return sem->X.val;} +int qurt_sem_down_cancellable(qurt_sem_t *sem); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SEM_H */ + diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_shmem.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_shmem.h new file mode 100755 index 0000000000000..980557323708a --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_shmem.h @@ -0,0 +1,89 @@ +#ifndef QURT_SHMEM_H +#define QURT_SHMEM_H + +/** + @file qurt_shmem.h + + @brief + Prototypes of QuRT inter-process shared memory APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MODE_T +#define MODE_T +typedef unsigned int mode_t; +#endif //MODE_T + +/** + * The shm_open() function establishes a connection between a shared memory object and a file descriptor. + * The file descriptor is used by other functions such as mmap() to refer to that shared memory object. + * + * + * @param name Pointer to string naming a shared memory object. Name has to start with "/shm/" + * @param oflag File status flags and file access modes of the open file description. Following + * flags are defined in and supported: + * O_RDONLY: oepn for read access only + * O_RDWR: Open for read or write access + * O_CREAT: If shared memory object doesn't exist, create one. + * @param mode Permission flags (currently ignored) + * + * @return file descriptor (positive number) if operation successful. + * negative error code if failed + * +*/ + +int shm_open(const char * name, int oflag, mode_t mode); + +/** + * The shm_mmap() function create a shared memory mapping in the virtual address space of the + * the calling process. + * + * @param addr The starting address for the new mapping is specified in addr. + * @param len Specifies the lengh of the shared memory region. + * @param prot Describes the desired memory protection of the mapping. Same as the one in mmap of POSIX. + * @param flags Determines whether updates to the mapping is visible or not to other process. Same as + * the one in mmap of POSIX. + * @param fd The starting adddress for the new mapping is returned. + * @param offset unused. + * + * @return The starting adddress for the new mapping is returned. + * negative error code if failed + * +*/ + +void *shm_mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset); + +/** + * The shm_close() function removes a connection between a shared memory object and a file descriptor. + * If there is no file descriptor connects to the shared memory object, the shared memory object will + * be deleted automatically. Shared memory object has same virtual address in any process. This is + * restriction of single virtual address space. + * + * + * @param fd File descriptor of shared memory object + * + * @return 0 if operation successful. + * negative error code if failed + * +*/ + + +int shm_close(int fd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal.h new file mode 100755 index 0000000000000..3a89c53394ad5 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal.h @@ -0,0 +1,518 @@ +#ifndef QURT_SIGNAL_H +#define QURT_SIGNAL_H + +/** + @file qurt_signal.h + @brief Prototypes of kernel signal API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup signals_types +@{ */ +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 /**< Wait any. */ +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 /**< Wait all. */ + +/*===================================================================== + Typedefs + ======================================================================*/ + + +/** QuRT signal type. + */ +typedef union { + /** @cond */ + unsigned long long int raw; + struct { + unsigned int signals; + unsigned int waiting; + unsigned int queue; + unsigned int attribute; + }X; + /** @endcond */ +} qurt_signal_t; + + +/** QuRT 64-bit signal type. + */ +typedef struct { + /** @cond */ + qurt_signal_t signal_sum; + unsigned long long signals; + unsigned long long waiting; + /** @endcond */ +} qurt_signal_64_t; +/** @} */ /* end_addtogroup signals_types */ +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal_init + Initializes a signal object. + Signal returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_init(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_destroy + Destroys the specified signal object. + + @note1hang Signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_destroy(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting on the signal. + + If a thread is waiting on a signal object for any of the specified set of signals to set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared when the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread waits to set any of the signals, or to set all of + them. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_wait(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_timed + @xreflabel{hdr:qurt_signal_wait} + Suspends the current thread until the specified signals are set or until timeout. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + waiting on a signal, and 0 indicates not waiting. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + The specified set of signals can be cleared after the signal is set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value that identifies the individual signals in the signal object to wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] signals Bitmask of signals that are set + @param[in] duration Duration (microseconds) to wait. Must be in the range + [#QURT_TIMER_MIN_DURATION ... #QURT_TIMER_MAX_DURATION] + + @return + #QURT_EOK -- Success; one or more signals were set \n + #QURT_ETIMEDOUT -- Timed-out \n + #QURT_EINVALID -- Duration out of range + + @dependencies + Timed-waiting support in the kernel. +*/ +/* ======================================================================*/ +int qurt_signal_wait_timed(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, unsigned int *signals, unsigned long long int duration); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_any + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on the thread. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, + and one or more of those signals is set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_any(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_wait_all + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to wait on a signal, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal_wait_all(qurt_signal_t *signal, unsigned int mask) +{ + return qurt_signal_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + to set the signal, and 0 indicates not to set it. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_set(qurt_signal_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 32-bit word with current signals + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal_get(qurt_signal_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_clear + Clear signals in the specified signal object. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_clear(qurt_signal_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal_wait_cancellable + @xreflabel{hdr:qurt_signal_wait_cancellable} + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] return_mask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +/* ======================================================================*/ +int qurt_signal_wait_cancellable(qurt_signal_t *signal, unsigned int mask, + unsigned int attribute, + unsigned int *return_mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_init + Initializes a 64-bit signal object.\n + The signal argument returns the initialized object. + The signal object is initially cleared. + + @note1hang Each signal-based object has one or more kernel resources associated with it; + to prevent resource leaks, call qurt_signal_destroy() + when this object is not used anymore. + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the initialized object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_init(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_destroy + Destroys the specified signal object. + + @note1hang 64-bit signal objects must be destroyed when they are no longer in use. Failure + to do this causes resource leaks in the QuRT kernel.\n + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_destroy(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_wait + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not wait on it. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, + and all of those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value, which identifies the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. \n + @note1hang The wait-any and wait-all types are mutually exclusive.\n Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_wait(qurt_signal_64_t *signal, unsigned long long mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_set + Sets signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set it. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifiying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal_64_set(qurt_signal_64_t *signal, unsigned long long mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_get + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal_64_t + + @param[in] *signal Pointer to the signal object to access. + + @return + A 64-bit double word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned long long qurt_signal_64_get(qurt_signal_64_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal_64_clear + Clears signals in the specified signal object. + + Signals are represented as bits 0 through 63 in the 64-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear it. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal_64_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal_64_clear(qurt_signal_64_t *signal, unsigned long long mask); + +#ifdef __cplusplus +} +#endif + +#endif /* QURT_SIGNAL_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal2.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal2.h new file mode 100755 index 0000000000000..43975100cbf75 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_signal2.h @@ -0,0 +1,340 @@ +#ifndef QURT_SIGNAL2_H +#define QURT_SIGNAL2_H + +/** + @file qurt_signal2.h + @brief Prototypes of kernel signal2 API functions. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QURT_SIGNAL_ATTR_WAIT_ANY 0x00000000 +#define QURT_SIGNAL_ATTR_WAIT_ALL 0x00000001 + +/*===================================================================== + Typedefs + ======================================================================*/ + +/** @addtogroup signals2_types +@{ */ +/** qurt_signal2 type. + */ +typedef union { + /** @cond */ + struct{ + unsigned int cur_mask; /* Current set of signal bits that are set. */ + unsigned int sig_state; /* Current state. */ + /* Bit 0 -- in anysignal wait. */ + /* Bit 1 -- in allsignal wait. */ + /* Bit 2 -- in interrupt wait. */ + /* Bits 31-3 -- reference count field. */ + unsigned int queue; /* Kernel-maintained futex queue value. */ + unsigned int wait_mask; /* When sig_state indicates a waiter is present, this is the wait mask. */ + }; + unsigned long long int raw; + /** @endcond */ +} qurt_signal2_t; +/* @} */ /* end_addtogroup signals2_types */ + +/*===================================================================== + Functions +======================================================================*/ + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_init + + @deprecated use #qurt_signal_init instead. + + Initializes a signal2 object. + Signal returns the initialized object. + The signal object is initially cleared. + + Objects of type signal2 solve a potential race condition between + set() and destroy() operations. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the initialized object. + + @return + None. + + @dependencies + Each mutex-based object has an associated + kernel resource(s), therefore users must call qurt_signal2_destroy() + when this object no longer in use. + */ +/* ======================================================================*/ +void qurt_signal2_init(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_destroy + + @deprecated use #qurt_signal_destroy instead. + + Destroys the specified signal object. + + @note1cont Signal objects must not be destroyed while they are still in use. If this + occurs, the behavior of QuRT is undefined. + @note1cont Application code should destroy a signal2 object prior to deallocating it. + Calling qurt_signal2_destroy() before deallocating a + signal2 object ensures completion of all qurt_signal2_set() calls. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to destroy. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_destroy(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait + + @deprecated use #qurt_signal_wait instead. + + Suspends the current thread until the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ANY, the thread will be awakened when + any of the signals specified in the mask are set. + + If a thread calls this API with QURT_SIGNAL_ATTR_WAIT_ALL, the thread will be awakened only + when all the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to wait on. + @param[in] attribute Specifies whether the thread waits for any of the signals to be set, or for all of + them to be set. Values:\n + - QURT_SIGNAL_ATTR_WAIT_ANY \n + - QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @return + A 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_wait(qurt_signal2_t *signal, unsigned int mask, + unsigned int attribute); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_any + + @deprecated use #qurt_signal_wait_any instead. + + Suspends the current thread until any of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened when any of the signals specified in the mask are set. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_any(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ANY); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_wait_all + + @deprecated use #qurt_signal_wait_all instead. + + Suspends the current thread until all of the specified signals are set. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + a signal to wait on. + + The thread will be awakened only when all the signals specified in the mask are set. + + @note1hang At most one thread can wait on a signal object at any given time. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +static inline unsigned int qurt_signal2_wait_all(qurt_signal2_t *signal, unsigned int mask) +{ + return qurt_signal2_wait(signal, mask, QURT_SIGNAL_ATTR_WAIT_ALL); +} + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_set + + @deprecated use #qurt_signal_set instead. + + Sets signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be set, and 0 indicates not to set the signal. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to set in the signal + object. + + @return + None. + + @dependencies + None. +*/ +/* ======================================================================*/ +void qurt_signal2_set(qurt_signal2_t *signal, unsigned int mask); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_get + + @deprecated use #qurt_signal_get instead. + + Gets a signal from a signal object. + + Returns the current signal values of the specified signal object. + + @datatypes + #qurt_signal2_t + + @param[in] *signal Pointer to the signal object to access. + + @return + 32-bit word with current signals. + + @dependencies + None. +*/ +/* ======================================================================*/ +unsigned int qurt_signal2_get(qurt_signal2_t *signal); + +/*======================================================================*/ +/**@ingroup func_qurt_signal2_clear + + @deprecated use #qurt_signal_clear instead. + + Clear signals in the specified signal object. + + Signals are represented as bits [31:0] in the 32-bit mask value. A mask bit value of 1 + indicates that a signal must be cleared, and 0 indicates not to clear the signal. + + @note1hang Signals must be explicitly cleared by a thread when it is awakened -- the wait + operations do not automatically clear them. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to modify. + @param[in] mask Mask value identifying the individual signals to clear in the signal object. + + @return + None. + + @dependencies + None. + */ +/* ======================================================================*/ +void qurt_signal2_clear(qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_signal2_wait_cancellable + + @deprecated use #qurt_signal_wait_cancellable instead. + + Suspends the current thread until either the specified signals are set or the wait operation is cancelled. + The operation is cancelled if the user process of the calling thread is killed, or if the calling thread + must finish its current QDI invocation and return to user space. + + Signals are represented as bits 0 through 31 in the 32-bit mask value. A mask bit value of 1 indicates + that a signal must be waited on, and 0 indicates not to wait on it. + + If a thread is waiting on a signal object for any of the specified set of signals to be set, and one or + more of those signals is set in the signal object, the thread is awakened. + + If a thread is waiting on a signal object for all of the specified set of signals to be set, and all of + those signals are set in the signal object, the thread is awakened. + + @note1hang At most, one thread can wait on a signal object at any given time. + + @note1cont When the operation is cancelled, the caller must assume that the signal is never set. + + @datatypes + #qurt_signal2_t + + @param[in] signal Pointer to the signal object to wait on. + @param[in] mask Mask value identifying the individual signals in the signal object to + wait on. + @param[in] attribute Indicates whether the thread must wait until any of the signals are set, or until all of + them are set. Values:\n + - #QURT_SIGNAL_ATTR_WAIT_ANY \n + - #QURT_SIGNAL_ATTR_WAIT_ALL @tablebulletend + @param[out] p_returnmask Pointer to the 32-bit mask value that was originally passed to the function. + + + @return + #QURT_EOK -- Wait completed. \n + #QURT_ECANCEL -- Wait cancelled. + + + @dependencies + None. +*/ +int qurt_signal2_wait_cancellable(qurt_signal2_t *signal, + unsigned int mask, + unsigned int attribute, + unsigned int *p_returnmask); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SIGNAL2_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_space.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_space.h new file mode 100755 index 0000000000000..2c3f9e4496697 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_space.h @@ -0,0 +1,230 @@ +#ifndef QURT_SPACE_H +#define QURT_SPACE_H +/** + @file qurt_space.h + @brief Prototypes of QuRT process control APIs + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2013, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** This flag is a request to the OS to suspend the processes just before calling main() +But it is going to be obsoleted and replaced by QURT_PROCESS_SUSPEND_ON_STARTUP */ +#define SPAWNN_FLAG_SUSPEND_ON_STARTUP QURT_PROCESS_SUSPEND_ON_STARTUP + +/** + * Creates and starts a process from ELF of a specified name. The slash symbols + * "/" or "\" are ignored. Do not include the directory name in the input. This function + * accepts the the SPAWN flags. Multiple SPAWN flags can be specified by OR'ing the flags. + * + * @param name ELF name of the executable. Name shall not contain directories, + * use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf" + * + * @param return + Process ID -- Success \n + Negative error code -- failure\n + #QURT_EPRIVILEGE -- Caller does not have enough privilege for this operation\n + #QURT_EMEM -- Not enough memory to perform the operation \n + #QURT_EFAILED -- Operation failed \n + #QURT_ENOTALLOWED -- Operation not allowed \n + #QURT_ENOREGISTERED -- Not registered \n + #QURT_ENORESOURCE -- Resource exhaustion \n + #QURT_EINVALID -- Invalid argument value +*/ + +int qurt_spawn_flags(const char * name, int flags); + +/** + Creates and starts a process from an ELF of the specified name. The slash symbols + "/" or "\" are ignored. Do not include the directory name in the input. + + @param name ELF name of the executable. Name shall not contain directories, + use "dsp2.elf", instead of "/prj/qct/.../dsp2.elf". + + @return + Process ID -- Success. \m + Negative error code -- Failure. + +*/ +static inline int qurt_spawn(const char *name) +{ + return qurt_spawn_flags(name,0); +} + +/** + * Returns the process ID of the current process. + * + * @return + * Process ID + * +*/ +#define qurt_getpid qurt_process_get_id + +/** + * The qurt_wait() function waits for status change in a child process. It could be used by parent + * process to block on any child process terminates. + * + * This API returns error if there are no user processes or all user processes got detached. + * + * @param status Pointer to status variable. The variable provides the status value of child process. + * The value comes from exit() system call made by child process. + * + * @return + Process ID of the child process that changes status -- Success \n + * Negative error code -- Failure + * +*/ + +int qurt_wait(int *status); + + +/** @cond */ +/* APIs that allow registering callbacks on spawn of user pd */ +typedef void (*QURT_SPAWN_PFN)(int client_handle, void *data_ptr); //no return, since we won't be error checking it in spawn +typedef int (*QURT_CB_PFN)(int client_handle, void *user_data, void *info); +typedef union { + QURT_SPAWN_PFN spawn_pfn; + QURT_CB_PFN cb_pfn; +} qurt_process_callback_pfn_t; +/** @endcond */ + +/** @cond internal_only */ + +/**@ingroup func_qurt_event_register +Sets the specified bits by mask in the signal passed by the caller. The signal gets set +when the client handle indicated by value goes away (at process exit). Multiple clients can register for the signal +to be set. + +@datatypes + +@param[in] type QURT_PROCESS_EXIT is the only event that can be registered for. +@param[in] value Indicates the client handle of the process for which the event is registered. +@param[in] signal Pointer to the signal object to set when the event occurs. +@param[in] mask Mask bits to set in the signal. +@param[out] data Pointer to the variable that would receive the exit code of the exiting process. +@param[in] datasize Size of the data variable. + +@return +#QURT_EOK -- Success \n +#QURT_EMEM -- Not enough memory to allocate resources \n +#QURT_EVAL -- Invalid values passed to the API + +@dependencies +None. +*/ +int qurt_event_register(int type, int value, qurt_signal_t *psig, unsigned int mask, void *data, unsigned int data_size); + +/**@ingroup func_qurt_callback_register_onspawn +Allows registering for a callback on spawn of any user process. + +@datatypes +#QURT_SPAWN_PFN + +@param[in] pFn Callback function to call when any user process is spawned. +@param[in] user_data Pointer to the argument that the callback must be called with. + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_callback_register_onspawn(QURT_SPAWN_PFN pFn, void *user_data); + +/**@ingroup func_qurt_callback_deregister_onspawn +Allows de-registering callback on spawn. + +@param[in] callback_handle Handle returned by qurt_callback_register_onspawn. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_callback_deregister_onspawn(int callback_handle); + +/**@ingroup func_qurt_process_callback_register +Allows registering for a callback during or after image loading. +Generic callback types: + Functions similarly to qurt_callback_register_onspawn(). Callback is called after process is + loaded, before process thread starts. Callback has no return value and has no info provided + from OS. + pFn - QURT_SPAWN_PFN + type - QURT_PROCESS_CB_GENERIC + arg1 - not used + arg2 - not used + arg3 - not used +Note callback types: + Callback is called during process loading: before segment loading(QURT_PROCESS_NOTE_CB_PRE_MAP), + or after segment loading (QURT_PROCESS_NOTE_CB_POST_MAP). OS provides info to the callback. info + argument in callback is populated with pointer to the mapped note corresponding to the callback. + Callback has return value, loader fails if callback returns a value that is not QURT_EOK. + pFn - QURT_CB_PFN + type - QURT_PROCESS_NOTE_CB_PRE_MAP or QURT_PROCESS_NOTE_CB_POST_MAP + arg1 - note type (ex: NOTE_TYPE_POOL_INFO, NOTE_TYPE_SEGMENT_INFO, NOTE_TYPE_ARB_INFO) + arg2 - note name + arg3 - not used + +@datatypes + +@param[in] pFn Callback function to call +@param[in] type Callback type +@param[in] user_data Pointer to the argument that the callback must be called with. +@param[in] arg1 Arguments interpreted by OS based on callback type +@param[in] arg2 Arguments interpreted by OS based on callback type +@param[in] arg3 Arguments interpreted by OS based on callback type (currently not used) + + +@return If positive value is obtained, handle to be used while deregistering the callback. + Mutliple clients can register for callback on spawn and some clients might choose to deregister. + + If failed, QURT_EFATAL will be returned. + +@dependencies +None. +*/ +int qurt_process_callback_register(qurt_process_callback_pfn_t pFn, + qurt_process_cb_type_t type, + void *user_data, + qurt_process_callback_arg_t arg1, + qurt_process_callback_arg_t arg2, + qurt_process_callback_arg_t arg3); + + + +/**@ingroup func_qurt_process_callback_deregister +Allows de-registering callback for imate loading. +@param[in] callback_handle Handle returned by qurt_process_callback_register. + +@return +#QURT_EOK --de-registering was successful + +@dependencies +None. +*/ +int qurt_process_callback_deregister(int callback_handle); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SPACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_consts.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_consts.h new file mode 100755 index 0000000000000..48a8b6a38c402 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_consts.h @@ -0,0 +1,32 @@ +#ifndef QURT_SRM_CONSTS_H +#define QURT_SRM_CONSTS_H +/** + @file qurt_srm_consts.h + @brief Type definitions for srm + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2020-2021, 2022 by Qualcomm Technologies, Inc. All Rights Reserved +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +#define QURT_SRM_WAKEUP_REQUEST 1U << 0 /**< Value = 1: Send wakeup request to the SRM server. */ +#define QURT_SRM_SET_HANDLE 1U << 1 /**< Value = 2: Set the client handle for a new SRM client. */ +#define QURT_SRM_ALLOC_KERNEL_PAGES 1U << 2 /**< Value = 4: Allocate pages from the kernel VA space. */ +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_CONSTS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_driver.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_driver.h new file mode 100755 index 0000000000000..5489e3dddbcca --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_srm_driver.h @@ -0,0 +1,140 @@ +#ifndef QURT_SRM_DRIVER_H +#define QURT_SRM_DRIVER_H +/** + @file qurt_srm_driver.h + @brief Definitions, macros, and prototypes used by SRM drivers. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. All Rights Reserved. + + =============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Define qurt_srm_driver_t structure, which represents +|| the "registration" object for an SRM driver. +*/ +/** @cond internal_only */ +struct _qurt_srm_driver { + const char *name; + qurt_qdi_obj_t *obj; +}; + +typedef struct _qurt_srm_driver qurt_srm_driver_t; + +/* +|| qurt_srm_object_invoke() is an internal equivalent to qurt_qdi_handle_invoke(). +|| It behaves the same, but it takes a QDI object pointer instead of a handle. +*/ + +#define qurt_srm_object_invoke(o,m,...) \ + _QDMPASTE(_QDMSOI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,o,m,##__VA_ARGS__) +#define _QDMSOI3(a,b,c) qurt_srm_oi3(a,b,c) +#define _QDMSOI4(a,b,c,d) qurt_srm_oi4(a,b,c,(int)(d)) +#define _QDMSOI5(a,b,c,d,e) qurt_srm_oi5(a,b,c,(int)(d),(int)(e)) +#define _QDMSOI6(a,b,c,d,e,f) qurt_srm_oi6(a,b,c,(int)(d),(int)(e),(int)(f)) +#define _QDMSOI7(a,b,c,d,e,f,g) qurt_srm_oi7(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g)) +#define _QDMSOI8(a,b,c,d,e,f,g,h) qurt_srm_oi8(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h)) +#define _QDMSOI9(a,b,c,d,e,f,g,h,i) qurt_srm_oi9(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i)) +#define _QDMSOI10(a,b,c,d,e,f,g,h,i,j) qurt_srm_oi10(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j)) +#define _QDMSOI11(a,b,c,d,e,f,g,h,i,j,k) qurt_srm_oi11(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k)) +#define _QDMSOI12(a,b,c,d,e,f,g,h,i,j,k,l) qurt_srm_oi12(a,b,c,(int)(d),(int)(e),(int)(f),(int)(g),(int)(h),(int)(i),(int)(j),(int)(k),(int)(l)) + +int qurt_srm_oi3(int, qurt_qdi_obj_t *, int); +int qurt_srm_oi4(int, qurt_qdi_obj_t *, int, int); +int qurt_srm_oi5(int, qurt_qdi_obj_t *, int, int, int); +int qurt_srm_oi6(int, qurt_qdi_obj_t *, int, int, int, int); +int qurt_srm_oi7(int, qurt_qdi_obj_t *, int, int, int, int, int); +int qurt_srm_oi8(int, qurt_qdi_obj_t *, int, int, int, int, int, int); +int qurt_srm_oi9(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int); +int qurt_srm_oi10(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int); +int qurt_srm_oi11(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int); +int qurt_srm_oi12(int, qurt_qdi_obj_t *, int, int, int, int, int, int, int, int, int, int); + +#define QDI_SRM_INIT 192 + +/* +|| QURT_SRM_DECLARE_DRIVER() declares an SRM driver to the SRM infrastructure. +|| +|| The three arguments are: +|| unique_id -- Unique C identifier, unused but must be a unique global symbol. +|| name -- Name of the driver by which an SRM client attempts to open it. +|| obj -- Pointer to the singleton object of the driver, which handles things such as +|| initialization and QDI_OPEN requests. +*/ + +#define QURT_SRM_DECLARE_DRIVER(unique_id, xname, xobj) \ + __attribute__((section(".srm.rodata.user.main.DECL"))) const qurt_srm_driver_t unique_id = \ + { .name = xname, .obj = xobj } + + +/*@ingroup func_qurt_srm_mapping_create + Creates a memory mapping in pagetable with specified attributes + + @param[in] client_handle Client handle representing the process for which + mapping would be created. + @param[in] pageno_virt pointer to the virtual page. NULL indicates SRM + would indicate the virtual memory. + @param[in] pageno_phys physical page to be used for the mapping + @param[in] page_count number of 4k pages to be mapped + @param[in] cache_attr cache attributes for the mapping + @param[in] perm permissions to be used for the mapping + + @return value greater than 0 indicates a handle which can be passed to + qdi_close() to remove the mapping. Negative value indicates + an error. + + @dependencies + None. +*/ +int qurt_srm_mapping_create(int client_handle, + unsigned *pageno_virt, + unsigned pageno_phys, + unsigned page_count, + qurt_mem_cache_mode_t cache_attr, + qurt_perm_t perm); + + +/**@ingroup func_qurt_srm_get_pid + Gets the PID for the client_handle that is passed. + + @param[in] client_handle Client handle for which PID is required. + + @return PID of the client + Negative PID value '-1' will be returned in case of Error + + @dependencies + None. +*/ +unsigned qurt_srm_get_pid(int client_handle); + + +/*@ingroup func_qurt_srm_get_thread_id + Gets the thread id of the client requesting a service from SRM + + @param[in] None. + + @return thead id of client thread + + @dependencies + None. +*/ +qurt_thread_t qurt_srm_get_client_thread_id(void); + +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_SRM_DRIVER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_stid.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_stid.h new file mode 100755 index 0000000000000..379f46aaa4b80 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_stid.h @@ -0,0 +1,73 @@ +#ifndef QURT_STID_H +#define QURT_STID_H +/** + @file qurt_stid.h + Prototypes of software thread identifier(stid) interface APIs. + A stid is 8 bit identifier that can be assigned to a software thread. + The performance monitor logic uses stid as a counting match criteria + for maskable events. stid is also used by the hardware debugger + (ISDB) to match breakpoints. + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + + Copyright (c) 2024 Qualcomm Technologies, Inc. + All rights reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_stid_alloc + Allocate a unique stid + + @param[in] pid Process identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - Allocation success + QURT_ENORESOURCE - No stid available for allocation + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_stid_alloc(unsigned int pid, unsigned int *stid); + +/**@ingroup func_qurt_stid_release + Release the stid. + + + @param[in] pid Process identifier + @param[in] stid STID to release + + @note1hang + User shall ensure to clear the released stid from process or thread(s) + to default value (QURT_STID_DEFAULT) before releasing that stid + + @return + QURT_EOK - Release success + QURT_ENOTALLOWED - Operation not allowed for a pid + QURT_EINVALID - Invalid stid + + @dependencies + None. + */ +int qurt_stid_release(unsigned int pid, unsigned int stid); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_STID_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread.h new file mode 100755 index 0000000000000..499699e7c72e2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread.h @@ -0,0 +1,1260 @@ +#ifndef QURT_THREAD_H +#define QURT_THREAD_H +/** + @file qurt_thread.h + @brief Prototypes of Thread API + + EXTERNAL FUNCTIONS + None. + + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018, 2020-2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +#include +#include "qurt_pmu.h" +#include "qurt_api_version.h" +#endif /* __ASSEMBLER__ */ +#include "qurt_consts.h" +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ + + +/* + Bitmask configuration to select DSP hardware threads. + To select all the hardware threads, use #QURT_THREAD_CFG_BITMASK_ALL + and the following: \n + - For QDSP6 V2/V3, all six hardware threads are selected \n + - For QDSP6 V3L, all four hardware threads are selected \n + - For QDSP6 V4, all three hardware threads are selected + */ + +#define QURT_THREAD_CFG_BITMASK_HT0 0x00000001 /**< HTO. */ +#define QURT_THREAD_CFG_BITMASK_HT1 0x00000002 /**< HT1. */ +#define QURT_THREAD_CFG_BITMASK_HT2 0x00000004 /**< HT2. */ +#define QURT_THREAD_CFG_BITMASK_HT3 0x00000008 /**< HT3. */ +#define QURT_THREAD_CFG_BITMASK_HT4 0x00000010 /**< HT4. */ +#define QURT_THREAD_CFG_BITMASK_HT5 0x00000020 /**< HT5. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{sec:qurt_thread_cfg} */ + +#define QURT_THREAD_CFG_BITMASK_ALL 0x000000ffU /**< Select all the hardware threads. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_CFG_USE_RAM 0x00000000 /**< Use RAM. */ +#define QURT_THREAD_CFG_USE_TCM 0x00000100 /**< Use TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_BUS_PRIO_DISABLED 0 /**< Thread internal bus priority disabled. */ +#define QURT_THREAD_BUS_PRIO_ENABLED 1 /**< Thread internal bus priority enabled. */ +/** @} */ /* end_addtogroup thread_macros */ +/** @endcond */ + +#define QURT_THREAD_AUTOSTACK_DISABLED 0 /**< Thread has autostack v2 feature disabled. */ +#define QURT_THREAD_AUTOSTACK_ENABLED 1 /**< Thread has autostack v2 feature enabled. */ + +/* + Macros for QuRT thread attributes. + */ +#define QURT_HTHREAD_L1I_PREFETCH 0x1 /**< Enables hardware L1 instruction cache prefetching. */ +#define QURT_HTHREAD_L1D_PREFETCH 0x2 /**< Enables hardware L1 data cache prefetching. */ +#define QURT_HTHREAD_L2I_PREFETCH 0x4 /**< Enables hardware L2 instruction cache prefetching. */ +#define QURT_HTHREAD_L2D_PREFETCH 0x8 /**< Enables hardware L2 data cache prefetching. */ +#define QURT_HTHREAD_DCFETCH 0x10 /**< Enables DC fetch to the provided virtual address. + DC fetch indicates the hardware that a data memory access is likely. + Instructions are dropped when there is high bus utilization. */ +/** @addtogroup thread_macros +@{ */ +/** @xreflabel{hdr:partition_tcm} */ +/* + Below value is used to create legacy QuRT threads by default. + If a thread has this as the detach_state, the thread can be joined + on until it exits. When we are able to change default behavior of all + QuRT threads to JOINABLE (posix default), we can remove this legacy + behavior. +*/ +#define QURT_THREAD_ATTR_CREATE_LEGACY 0U /**< Create a legacy QuRT thread by default. If a thread has this as a detach state, the thread can be joined on until it exits. */ +#define QURT_THREAD_ATTR_CREATE_JOINABLE 1U /**< Create a joinable thread. */ +#define QURT_THREAD_ATTR_CREATE_DETACHED 2U /**< Create a detached thread. */ +/** @} */ /* end_addtogroup thread_macros */ + + +#define QURT_THREAD_ATTR_NAME_MAXLEN 16 /**< Maximum name length. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_RAM 0 /**< Creates threads in RAM/DDR. */ +#define QURT_THREAD_ATTR_TCB_PARTITION_TCM 1 /**< Creates threads in TCM. */ +/** @cond rest_reg_dist */ +/** @addtogroup thread_macros +@{ */ +#define QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT QURT_THREAD_ATTR_TCB_PARTITION_RAM /**< Backward compatibility. */ +#define QURT_THREAD_ATTR_PRIORITY_DEFAULT 254 /**< Priority.*/ +#define QURT_THREAD_ATTR_ASID_DEFAULT 0 /**< ASID. */ +#define QURT_THREAD_ATTR_AFFINITY_DEFAULT (-1) /**< Affinity. */ +#define QURT_THREAD_ATTR_BUS_PRIO_DEFAULT 255 /**< Bus priority. */ +#define QURT_THREAD_ATTR_AUTOSTACK_DEFAULT 0 /**< Default autostack v2 disabled thread. */ +#define QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT (-2) /**< Timetest ID. */ +#define QURT_THREAD_ATTR_STID_DEFAULT QURT_STID_DEFAULT /**< STID. */ +#define QURT_THREAD_ATTR_STID_ENABLE 1 /**< Indicate to allocate STID during thread creation. */ + +#define QURT_PRIORITY_FLOOR_DEFAULT 255U /**< Default floor. */ +/** @} */ /* end_addtogroup thread_macros */ + +// Option for suspending thread +#define QURT_THREAD_SUSPEND_SYNCHRONOUS 0x0U // bit#0 +#define QURT_THREAD_SUSPEND_ASYNCHRONOUS 0x1U // bit#0 +#define QURT_THREAD_SUSPEND_KEEP_HMX 0x0U // bit#1 +#define QURT_THREAD_SUSPEND_DETACH_HMX 0x2U // bit#1 + +// Option for resuming thread +#define QURT_THREAD_RESUME_DEFAULT 0x0 + +// Thread property IDs +#define QURT_THREAD_PROPERTY_SUSPENDABLE 0x0U +#define QURT_THREAD_PROPERTY_RESUMABLE 0x1 + +// Thread group +#define QURT_THREAD_DEFAULT_GROUP_ID 0x0U +#define QURT_THREAD_GROUP_ID_MASK 0x3FU + +/** @endcond*/ + + +/* The followings are for C code only */ +#ifndef __ASSEMBLER__ +/*============================================================================= + TYPEDEFS +=============================================================================*/ +/** @addtogroup thread_types +@{ */ +/** @cond rest_reg_dist */ +typedef unsigned int qurt_cache_partition_t; /**< QuRT cache partition type. */ + +#define CCCC_PARTITION 0U /**< Use the CCCC page attribute bits to determine the main or auxiliary partition. */ +#define MAIN_PARTITION 1U /**< Use the main partition. */ +#define AUX_PARTITION 2U /**< Use the auxiliary partition. */ +#define MINIMUM_PARTITION 3U /**< Use the minimum. Allocates the least amount of cache (no-allocate policy possible) for this thread. */ +/** @endcond */ + +/** Thread ID type. */ +typedef unsigned int qurt_thread_t; + +/** @cond rest_reg_dist */ +/** Thread attributes. */ +typedef struct _qurt_thread_attr { + + char name[QURT_THREAD_ATTR_NAME_MAXLEN]; /**< Thread name. */ + unsigned char tcb_partition; /**< Indicates whether the thread TCB resides in RAM or + on chip memory (TCM). */ + unsigned char stid; /**< Software thread ID used to configure the stid register + for profiling purposes. */ + unsigned short priority; /**< Thread priority. */ + unsigned char autostack:1; /**< Autostack v2 enabled thread. */ + unsigned char group_id:6; /**< Group ID. */ + unsigned char reserved:1; /**< Reserved bits. */ + unsigned char bus_priority; /**< Internal bus priority. */ + unsigned short timetest_id; /**< Timetest ID. */ + unsigned int stack_size; /**< Thread stack size. */ + void *stack_addr; /**< Pointer to the stack address base. The range of the stack is + (stack_addr, stack_addr+stack_size-1). */ + unsigned short detach_state; /**< Detach state of the thread. */ + +} qurt_thread_attr_t; +/** @endcond */ + +/** @cond rest_reg_dist */ +/** Dynamic TLS attributes. */ +typedef struct qurt_tls_info { + unsigned int module_id; /**< Module ID of the loaded dynamic linked library. */ + unsigned int tls_start; /**< Start address of the TLS data. */ + unsigned int tls_data_end; /**< End address of the TLS RW data. */ + unsigned int tls_end; /**< End address of the TLS data. */ +}qurt_tls_info; +/** @endcond */ + +/** @} */ /* end_addtogroup thread_types */ + +/*============================================================================= + FUNCTIONS +=============================================================================*/ +/**@ingroup func_qurt_thread_attr_init + Initializes the structure used to set the thread attributes when a thread is created. + After an attribute structure is initialized, Explicity set the individual attributes in the structure + using the thread attribute operations. + + The initialize operation sets the following default attribute values: \n + - Name -- NULL string \n + - TCB partition -- QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT + - Priority -- QURT_THREAD_ATTR_PRIORITY_DEFAULT \n + - Autostack -- QURT_THREAD_ATTR_AUTOSTACK_DEFAULT \n + - Bus priority -- QURT_THREAD_ATTR_BUS_PRIO_DEFAULT \n + - Timetest ID -- QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT \n + - stack_size -- 0 \n + - stack_addr -- NULL \n + - detach state -- #QURT_THREAD_ATTR_CREATE_LEGACY \n + - STID -- #QURT_THREAD_ATTR_STID_DEFAULT + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_init (qurt_thread_attr_t *attr) +{ + + attr->name[0] = '\0'; + attr->tcb_partition = QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT; + attr->priority = QURT_THREAD_ATTR_PRIORITY_DEFAULT; + attr->autostack = QURT_THREAD_ATTR_AUTOSTACK_DEFAULT; /* Default attribute for autostack v2*/ + attr->bus_priority = QURT_THREAD_ATTR_BUS_PRIO_DEFAULT; + attr->timetest_id = (unsigned short)QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT; + attr->stack_size = 0; + attr->stack_addr = NULL; + attr->detach_state = QURT_THREAD_ATTR_CREATE_LEGACY; + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + attr->group_id = QURT_THREAD_DEFAULT_GROUP_ID; +} + +/**@ingroup func_qurt_thread_attr_set_name + Sets the thread name attribute.\n + This function specifies the name to use by a thread. + Thread names identify a thread during debugging or profiling. + Maximum name length is 16 charactes \n + @note1hang Thread names differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] name Pointer to the character string containing the thread name. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_name (qurt_thread_attr_t *attr, const char *name) +{ + strlcpy (attr->name, name, QURT_THREAD_ATTR_NAME_MAXLEN); + attr->name[QURT_THREAD_ATTR_NAME_MAXLEN - 1] = '\0'; +} + + +/**@ingroup func_qurt_thread_attr_set_tcb_partition + Sets the thread TCB partition attribute. + Specifies the memory type where a TCB of a thread is allocated. + Allocates TCBs in RAM or TCM/LPM. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] tcb_partition TCB partition. Values:\n + - 0 -- TCB resides in RAM \n + - 1 -- TCB resides in TCM/LCM @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_tcb_partition (qurt_thread_attr_t *attr, unsigned char tcb_partition) +{ + attr->tcb_partition = tcb_partition; +} + +/**@ingroup func_qurt_thread_attr_set_priority + Sets the thread priority to assign to a thread. + Thread priorities are specified as numeric values in the range 1 to 254, with 1 representing + the highest priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] priority Thread priority. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_priority (qurt_thread_attr_t *attr, unsigned short priority) +{ + attr->priority = priority; +} + +/**@ingroup func_qurt_thread_attr_set_detachstate + Sets the thread detach state with which thread is created. + Thread detach state is either joinable or detached; specified by the following values: + - #QURT_THREAD_ATTR_CREATE_JOINABLE \n + - #QURT_THREAD_ATTR_CREATE_DETACHED \n + + When a detached thread is created (QURT_THREAD_ATTR_CREATE_DETACHED), its thread + ID and other resources are reclaimed as soon as the thread exits. When a joinable thread + is created (QURT_THREAD_ATTR_CREATE_JOINABLE), it is assumed that some + thread waits to join on it using a qurt_thread_join() call. + By default, detached state is QURT_THREAD_ATTR_CREATE_LEGACY + If detached state is QURT_THREAD_ATTR_CREATE_LEGACY then other + thread can join before thread exits but it will not wait other thread to join. + + @note1hang For a joinable thread (QURT_THREAD_ATTR_CREATE_JOINABLE), it is very + important that some thread joins on it after it terminates, otherwise + the resources of that thread are not reclaimed, causing memory leaks. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] detachstate Thread detach state. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_detachstate (qurt_thread_attr_t *attr, unsigned short detachstate) +{ + if(detachstate == QURT_THREAD_ATTR_CREATE_JOINABLE || detachstate == QURT_THREAD_ATTR_CREATE_DETACHED){ + attr->detach_state = detachstate; + } +} + + +/**@ingroup func_qurt_thread_attr_set_timetest_id + Sets the thread timetest attribute.\n + Specifies the timetest identifier to use by a thread. + + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] timetest_id Timetest identifier value. + + @return + None. + + @dependencies + None. + */ +static inline void qurt_thread_attr_set_timetest_id (qurt_thread_attr_t *attr, unsigned short timetest_id) +{ + attr->timetest_id = timetest_id; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute.\n + Specifies the size of the memory area to use for a call stack of a thread. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_size Size (in bytes) of the thread stack. + + @return + None. + + @dependencies + None. +*/ + +static inline void qurt_thread_attr_set_stack_size (qurt_thread_attr_t *attr, unsigned int stack_size) +{ + attr->stack_size = stack_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_size2 + @xreflabel{sec:set_stack_size} + Sets the thread stack size attribute for island threads that require a higher guest OS stack size than the stack size + defined in the configuration XML.\n + Specifies the size of the memory area to use for a call stack of an island thread in User and Guest mode. + + The thread stack address (Section @xref{sec:set_stack_addr}) and stack size specify the memory area used as a + call stack for the thread. The user is responsible for allocating the memory area used for + the stack. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] user_stack_size Size (in bytes) of the stack usage in User mode. + @param[in] root_stack_size Size (in bytes) of the stack usage in Guest mode. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_size2 (qurt_thread_attr_t *attr, unsigned short user_stack_size, unsigned short root_stack_size) +{ + union qurt_thread_stack_info{ + unsigned int raw_size; + struct{ + unsigned short user_stack; + unsigned short root_stack; + }; + }user_root_stack_size; + user_root_stack_size.user_stack = user_stack_size; + user_root_stack_size.root_stack = root_stack_size; + + attr->stack_size = user_root_stack_size.raw_size; +} + +/**@ingroup func_qurt_thread_attr_set_stack_addr + @xreflabel{sec:set_stack_addr} + Sets the thread stack address attribute. \n + Specifies the base address of the memory area to use for a call stack of a thread. + + stack_addr must contain an address value that is 8-byte aligned. + + The thread stack address and stack size (Section @xref{sec:set_stack_size}) specify the memory area used as a + call stack for the thread. \n + @note1hang The user is responsible for allocating the memory area used for the thread + stack. The memory area must be large enough to contain the stack that the thread + creates. + + @datatypes + #qurt_thread_attr_t + + @param[in,out] attr Pointer to the thread attribute structure. + @param[in] stack_addr Pointer to the 8-byte aligned address of the thread stack. + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stack_addr (qurt_thread_attr_t *attr, void *stack_addr) +{ + attr->stack_addr = stack_addr; +} + +/**@ingroup func_qurt_thread_attr_set_bus_priority + Sets the internal bus priority state in the Hexagon core for this software thread attribute. + Memory requests generated by the thread with bus priority enabled are + given priority over requests generated by the thread with bus priority disabled. + The default value of bus priority is disabled. + + @note1hang Sets the internal bus priority for Hexagon processor version V60 or greater. + The priority is not propagated to the bus fabric. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + + @param[in] bus_priority Enabling flag. Values: \n + - #QURT_THREAD_BUS_PRIO_DISABLED \n + - #QURT_THREAD_BUS_PRIO_ENABLED @tablebulletend + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_bus_priority ( qurt_thread_attr_t *attr, unsigned short bus_priority) +{ + attr->bus_priority = (unsigned char)bus_priority; +} + +/**@ingroup func_qurt_thread_attr_set_autostack + Enables autostack v2 feature in the thread attributes. + + When autostack is enabled by the subsystem, in the case that + an autostack enabled thread gets framelimit exception, kernel will + allocate more stack for thread and return to normal execution. + + If autostack is not enabled by the subsystem, or it is not enabled + for the thread, the framelimit exception will be fatal. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] autostack Autostack enable or disable flag. Values: \n + - #QURT_THREAD_AUTOSTACK_DISABLED \n + - #QURT_THREAD_AUTOSTACK_ENABLED @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_autostack ( qurt_thread_attr_t *attr, unsigned short autostack) +{ + attr->autostack = (unsigned char)autostack; +} +/**@ingroup qurt_thread_attr_enable_stid + Set STID in the thread attributes. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] enable_stid STID to be set. Values: \n + - #QURT_THREAD_ATTR_STID_DEFAULT (0): Default STID. \n + - #QURT_THREAD_ATTR_STID_ENABLE (1): QuRT assigns an STID that is not already in use \n + - #2 through #255 : User provided STID. @tablebulletend + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_enable_stid ( qurt_thread_attr_t *attr, char enable_stid) +{ + if (enable_stid != '\0') { + attr->stid = enable_stid; + } + else + { + attr->stid = QURT_THREAD_ATTR_STID_DEFAULT; + } +} + +/**@ingroup func_qurt_thread_attr_set_stid + Sets the stid thread attribute. + The default stid value is QURT_THREAD_ATTR_STID_DEFAULT + + @note1hang When a thread is created with non default stid , + the stid set in thread attribute will be assigned to a thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] stid Stid to be set for a thread. + + @return + None + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_stid( qurt_thread_attr_t *attr, unsigned int stid){ + attr->stid = stid; +} + +/**@ingroup func_qurt_thread_attr_set_group_id + Sets group id in the thread attributes. + Primordial/first thread has group ID 0. + If a new thread is created without assigning group_id, it + inherits the group ID from its parent thread. + + @note1hang + 1) Group ID can only be set before creating a thread. It cannot be + changed after the thread is created. + 2) If a non-activated group_id is passed, thread creation will fail. + 3) Only a thread with Group ID #0 can set Group ID for its child threads. + 4) If thread with non-zero group ID set the group ID for its child threads, + QuRT will ingore this parameter and child threads will inherit the parent + thread's group ID. But if passed group ID is not activated, thread creation + will still fail. + + @datatypes + #qurt_thread_attr_t + + @param[in] attr Pointer to the thread attribute structure. + @param[in] group_id Group identifier. Its valid range is 0 ~ 63 + + @return + None. + + @dependencies + None. +*/ +static inline void qurt_thread_attr_set_group_id(qurt_thread_attr_t *attr, unsigned int group_id) +{ + attr->group_id = group_id & QURT_THREAD_GROUP_ID_MASK; +} + +/**@ingroup func_qurt_thread_set_autostack + Sets autostack enable in the TCB. + + @param[in] Pointer to UGP + + @return + None. + + @dependencies + None. +*/ + +void qurt_thread_set_autostack(void *); + + +/**@ingroup func_qurt_thread_get_name + Gets the thread name of current thread.\n + Returns the thread name of the current thread. + Thread names are assigned to threads as thread attributes, see qurt_thread_attr_set_name(). Thread names + identify a thread during debugging or profiling. + + @param[out] name Pointer to a character string, which specifies the address where the returned thread name is stored. + @param[in] max_len Maximum length of the character string that can be returned. + + @return + None. + + @dependencies + None. +*/ +void qurt_thread_get_name (char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_create + @xreflabel{hdr:qurt_thread_create} + Creates a thread with the specified attributes, and makes it executable. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[out] thread_id Returns a pointer to the thread identifier if the thread was + successfully created. + @param[in] attr Pointer to the initialized thread attribute structure that specifies + the attributes of the created thread. + @param[in] entrypoint C function pointer, which specifies the main function of a thread. + @param[in] arg Pointer to a thread-specific argument structure + + + @return + #QURT_EOK -- Thread created. \n + #QURT_EFAILED -- Thread not created. + + @dependencies + None. + */ +int qurt_thread_create (qurt_thread_t *thread_id, qurt_thread_attr_t *attr, void (*entrypoint) (void *), void *arg); + +/**@ingroup func_qurt_thread_stop + Stops the current thread, frees the kernel TCB, and yields to the next highest ready thread. + + @return + void + + @dependencies + None. + */ +void qurt_thread_stop(void); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_resume + When a demand-loading paging solution is enabled, this function + will resumes the execution of a thread that was suspended due to + a page miss. + + @param[in] thread_id Thread identifier. + + @return + #QURT_EOK -- Thread successfully resumed. \n + #QURT_EFATAL -- Resume operation failed. + + @dependencies + None. + */ +int qurt_thread_resume(unsigned int thread_id); +/** @endcond */ + +/**@ingroup func_qurt_thread_get_id + Gets the identifier of the current thread.\n + Returns the thread identifier for the current thread. + + @return + Thread identifier -- Identifier of the current thread. + + @dependencies + None. + */ +qurt_thread_t qurt_thread_get_id (void); + + +/**@ingroup func_qurt_thread_get_l2cache_partition + Returns the current value of the L2 cache partition assigned to the caller thread.\n + + @return + Value of the #qurt_cache_partition_t data type. + + @dependencies + None. + */ +qurt_cache_partition_t qurt_thread_get_l2cache_partition (void); + +/**@ingroup func_qurt_thread_set_timetest_id + Sets the timetest identifier of the current thread. + Timetest identifiers are used to identify a thread during debugging or profiling.\n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @param[in] tid Timetest identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_timetest_id (unsigned short tid); + +/**@ingroup func_qurt_thread_set_cache_partition + Sets the cache partition for the current thread. This function uses the qurt_cache_partition_t type + to select the cache partition of the current thread for the L1 Icache, L1 Dcache, and L2 cache. + + @datatypes + #qurt_cache_partition_t + + @param[in] l1_icache L1 I cache partition. + @param[in] l1_dcache L1 D cache partition. + @param[in] l2_cache L2 cache partition. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_set_cache_partition(qurt_cache_partition_t l1_icache, qurt_cache_partition_t l1_dcache, qurt_cache_partition_t l2_cache); + + +/**@ingroup func_qurt_thread_get_timetest_id + Gets the timetest identifier of the current thread.\n + Returns the timetest identifier of the current thread.\n + Timetest identifiers are used to identify a thread during debugging or profiling. \n + @note1hang Timetest identifiers differ from the kernel-generated thread identifiers used to + specify threads in the API thread operations. + + @return + Integer -- Timetest identifier. + + @dependencies + None. + */ +unsigned short qurt_thread_get_timetest_id (void); + +/**@ingroup func_qurt_thread_exit + @xreflabel{sec:qurt_thread_exit} + Stops the current thread, awakens threads joined to it, then destroys the stopped + thread. + + Threads that are suspended on the current thread (by performing a thread join + Section @xref{sec:thread_join}) are awakened and passed a user-defined status value + that indicates the status of the stopped thread. + + @note1hang Exit must be called in the context of the thread to stop. + + @param[in] status User-defined thread exit status value. + + @return + None. + + @dependencies + None. + */ +void qurt_thread_exit(int status); + +/**@ingroup func_qurt_thread_join + @xreflabel{sec:thread_join} + Waits for a specified thread to finish; the specified thread is another thread within + the same process. + The caller thread is suspended until the specified thread exits. When the unspecified thread + exits, the caller thread is awakened. \n + @note1hang If the specified thread has already exited, this function returns immediately + with the result value #QURT_ENOTHREAD. \n + @note1cont Two threads cannot call qurt_thread_join to wait for the same thread to finish. + If this occurs, QuRT generates an exception (see Section @xref{sec:exceptionHandling}). + + @param[in] tid Thread identifier. + @param[out] status Destination variable for thread exit status. Returns an application-defined + value that indicates the termination status of the specified thread. + + @return + #QURT_ENOTHREAD -- Thread has already exited. \n + #QURT_EOK -- Thread successfully joined with valid status value. + + @dependencies + None. + */ +int qurt_thread_join(unsigned int tid, int *status); + +/**@ingroup qurt_thread_detach + @xreflabel{sec:thread_detach} + Detaches a joinable thread. The specified thread is another thread within the + same process. Create the thread as a joinable thread; only joinable threads + can be detached. + If a joinable thread is detached, it finishes execution and exits. + + @param[in] tid Thread identifier. + + @return + #QURT_ENOTHREAD -- Thread specifed by TID does not exist. \n + #QURT_EOK -- Thread successfully detached. + + @dependencies + None. + */ +int qurt_thread_detach(unsigned int tid); + + +/**@ingroup func_qurt_thread_get_priority + Gets the priority of the specified thread. \n + Returns the thread priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. \n + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + + @return + -1 -- Invalid thread identifier. \n + 1 through 254 -- Thread priority value. + + @dependencies + None. + */ +int qurt_thread_get_priority (qurt_thread_t threadid); + +/**@ingroup func_qurt_thread_set_priority + Sets the priority of the specified thread.\n + Thread priorities are specified as numeric values in a range as large as 1 through 254, with lower + values representing higher priorities. 1 represents the highest possible thread priority. + Priority 0 and 255 are internally used by the kernel for special purposes. + + @note1hang QuRT can be configured to have different priority ranges. For more + information, see Section @xref{sec:AppDev}. + + @datatypes + #qurt_thread_t + + @param[in] threadid Thread identifier. + @param[in] newprio New thread priority value. + + @return + 0 -- Priority successfully set. \n + -1 -- Invalid thread identifier. \n + + @dependencies + None. + */ +int qurt_thread_set_priority (qurt_thread_t threadid, unsigned short newprio); + + + +/**@ingroup func_qurt_thread_attr_get + Gets the attributes of the specified thread. + + @datatypes + #qurt_thread_t \n + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[out] attr Pointer to the destination structure for thread attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid argument. + + @dependencies + None. + */ +int qurt_thread_attr_get (qurt_thread_t thread_id, qurt_thread_attr_t *attr); + + + +/**@ingroup func_qurt_thread_get_tls_base + Gets the base address of thread local storage (TLS) of a dynamically loaded module + for the current thread. + + @datatypes + #qurt_tls_info + + @param[in] info Pointer to the TLS information for a module. + + @return + Pointer to the TLS object for the dynamically loaded module.\n + NULL -- TLS information is invalid. + + @dependencies + None. + */ +void * qurt_thread_get_tls_base(qurt_tls_info* info); + +/**@ingroup func_qurt_thread_pktcount_get + Gets the PKTCOUNT of a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + PKTCOUNT + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_get (qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_pktcount_set + Sets the PKTCOUNT for the current QuRT thread. + + @return + Value to which pktcount is set. + + @dependencies + None. + */ + +long long int qurt_thread_pktcount_set (long long int); + +/**@ingroup func_qurt_thread_stid_get + Gets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] thread_id Thread identifier. + + @return + STID + + @dependencies + None. + */ + +char qurt_thread_stid_get(qurt_thread_t thread_id); + +/**@ingroup func_qurt_thread_stid_get2 + Returns the set stid for a thread + + @param[in] thread_id thread identifier + @param[out] stid Pointer to a variable to return stid + + @return + QURT_EOK - success + QURT_ENOTALLOWED - operation not allowed for a thread + QURT_EINVALID - Invalid input + + @dependencies + None. + */ +int qurt_thread_stid_get2(unsigned int thread_id, unsigned int *stid); + +/**@ingroup func_qurt_thread_stid_set + Sets the STID for a specified thread. + + @datatypes + #qurt_thread_t + + @param[in] stid Thread identifier. + + @return + #QURT_EOK -- STID set created. \n + #QURT_EFAILED -- STID not set. + + @dependencies + None. + */ + +int qurt_thread_stid_set(char stid); + +/**@ingroup qurt_thread_stid_set2 + Sets the stid for a specified thread. + + @datatypes + #qurt_thread_attr_t + + @param[in] thread_id Thread identifier. + @param[in] stid Stid to be set for a thread. + + @return + QURT_EOK -- Success + #QURT_EPRIVILEGE -- Failure because caller does not have enough privilege for this operation. + #QURT_EVAL -- Failure because of invalid inputs. + + @dependencies + None. +*/ +int qurt_thread_stid_set2(unsigned int thread_id, unsigned int stid); + +/** @cond internal_only */ +/**@ingroup func_qurt_thread_get_running_ids + Returns the thread IDs of the running threads in the system; use only during fatal error handling. + + @datatypes + #qurt_thread_t + + @param[in,out] * Array of thread identifier of size #QURT_MAX_HTHREAD_LIMIT + 1. + + @return + #QURT_EINVALID -- Incorrect argument \n + #QURT_ENOTALLOWED -- API not called during error handling \n + #QURT_EOK -- Success, returns a NULL-terminated array of thread_id + + @dependencies + None. + */ +int qurt_thread_get_running_ids(qurt_thread_t *); +/** @endcond */ + + +/**@ingroup func_qurt_thread_get_thread_id + Gets the thread identifier of the thread with the matching name in the same process + of the caller. + + @datatypes + #qurt_thread_t + + @param[out] thread_id Pointer to the thread identifier. + @param[in] name Pointer to the name of the thread. + + @return + #QURT_EINVALID -- No thread with matching name in the process of the caller \n + #QURT_EOK -- Success + + @dependencies + None. + */ +int qurt_thread_get_thread_id (qurt_thread_t *thread_id, char *name); + +/**@ingroup func_qurt_sleep + Suspends the current thread for the specified amount of time. + + @note1hang Because QuRT timers are deferrable, this call is guaranteed to block + at least for the specified amount of time. If power-collapse is + enabled, the maximum amount of time this call can block depends on + the earliest wakeup from power-collapse past the specified duration. + + @param[in] duration Duration (in microseconds) for which the thread is suspended. + + @return + None. + + @dependencies + None. + */ +void qurt_sleep (unsigned long long int duration); + + +/**@ingroup func_qurt_system_set_priority_floor + Sets a priority floor to move threads with thread priority lower than the floor out of the running state. + Running threads with thread priority lower than the priority floor are moved into the kernel ready queue, and they + are not scheduled to run when the thread priority is lower than the floor. + Later the caller should reset the priority floor back to the default value of QURT_PRIORITY_FLOOR_DEFAULT. + Threads in the kernel ready queue are scheduled to run when the thread priority is higher than the floor. + + The priority floor is set and associated to the user process of the caller. When the caller gets into QuRTOS and + sets a new floor, the new floor is associated to its original user process, not the QuRTOS process. + The floor associated to the user process is reset when the user process exits or is killed, but not at the time + when the user thread of the caller exits. + + The priority floor cannot be set to a priority higher than the thread priority of the caller. + + The priority floor cannot be set to a priority lower than the default #QURT_PRIORITY_FLOOR_DEFAULT system floor. + + This function is not supported in Island mode. + + After the system floor is set above QURT_PRIORITY_FLOOR_DEFAULT, power collapse is skipped, and sleep task + is not scheduled to run. + + @param[in] priority_floor Priority floor. + + @return + #QURT_EOK -- Success \n + #QURT_ENOTALLOWED -- Floor setting is not allowed + + @dependencies + None. + */ +int qurt_system_set_priority_floor (unsigned int priority_floor); + + +/**@ingroup func_qurt_thread_suspend_thread + Suspend a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent process. + After the target thread is suspended, the kernel will not schedule it to run until it is resumed later. + + If the target thread is set as non-suspendable, this function call returns an error without suspending + the target thread. + + If the target thread is already suspended, this function call returns success to confirm + the target thread suspend. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + suspending the target thread. + + If the target thread is running in the guest OS/root process via a QDI call, this function call does not suspend + the target thread in guest OS, but marks the target thread as suspend-pending. The target thread is + suspended when it exits the guest OS, before executing the first instruction in the user process. + In this case, the function returns success even with the #QURT_THREAD_SUSPEND_SYNCHRONOUS option, while the target + thread can runn in the guest OS, and is suspended when exiting the guest OS. + + QuRT debug monitor threads that are in a user process are non-suspendable. This function does not suspend + those threads. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, multiple options can be ORed. \n + #QURT_THREAD_SUSPEND_SYNCHRONOUS (default) -- set to synchronous function call, + the function returns after the thread is completely suspended.\n + #QURT_THREAD_SUSPEND_ASYNCHRONOUS -- set to asynchronous function call, the function returns + after the kernel acts to suspend the target thread. The target thread + might still be running before it is completely suspended. \n + #QURT_THREAD_SUSPEND_KEEP_HMX (default) -- keep the HMX attachment on the target thread + if it locks the HMX with qurt_hmx_lock(). In this case, the HMX cannot be re-used by other threads. \n + #QURT_THREAD_SUSPEND_DETACH_HMX -- detach HMX from the target thread if it locks the HMX with qurt_hmx_lock(). + Later when the target thread resumes, the HMX is re-attached to the thread. Note that, this option is only + supported for the caller from the same user process of the target thread, not for a caller from the parent + process of the target thread, or other processes. With the HMX detach option, Qurt does not save the HMX + context. Thus, the HMX context state will be lost. It is the responsibility of caller to ensure HMX operations + and its context state saving when calling qurt_thread_suspend_thread() with the HMX detach option. + If a thread from another process uses this detach option, QURT_EHMXNOTDETACHABLE will be returned; in this + case, if the caller is qualified to suspend the target thread, the target thread will be moved to suspended + state without HMX detached. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in secure process/CPZ process. + #QURT_EHMXNOTDETACHABLE -- Failure because HMX is not detachable from the target thread. + + @dependencies + None. + */ +int qurt_thread_suspend_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_resume_thread + Resume a QuRT thread with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be a thread from the same user process of the target thread, or from its parent + process. After the target thread resumes, the kernel scheduler can schedule the thread to run based on + the thread priority. + + There is an option argument in this function, with only one default option as of now, + QURT_THREAD_RESUME_DEFAULT: resume the target thread in default way. + + By default, this is an asynchronous function. The function returns after kernel moves the + target thread from suspended state to runnable state. The thread is scheduled to run based on its + thread priority. + + If the target thread is set as non-resumable, this function call does not resume the target thread. + + If the target thread has already resumed, this function confirms that the target thread resumes + by returning success. + + If the target thread is in a secure user process or CPZ process, this function call returns an error without + resuming the operation. + + If the target thread runs in the guest OS/root process via a QDI call, this function call clears the mark of + suspend-pending on the target thread, and the target thread is not suspended when it exits the + guest OS. + + @param[in] thread_id Thread identifier. + @param[in] option Optional argument, #QURT_THREAD_RESUME_DEFAULT, which resumes the target thread. + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + #QURT_EHMXNOTAVAIL -- Failure because when resume a HMX thread, the HMX is not available/free for the HMX thread resume. + + @dependencies + None. + */ +int qurt_thread_resume_thread (unsigned int thread_id, unsigned int option); + + +/**@ingroup func_qurt_thread_set_thread_property + Set a QuRT thread property with its thread identifier. + The target thread can be in a signed user process or an unsigned user process. + The caller thread can be from the same user process of the target thread, or from its parent process. + + If the target thread is in a secure user process, or CPZ process, this function call returns an error without + changing the property of the target thread. + + @param[in] thread_id Thread identifier \n + @param[in] property_id Thread property identifier \n + #QURT_THREAD_PROPERTY_SUSPENDABLE -- thread is suspendable. Default is TRUE. \n + #QURT_THREAD_PROPERTY_RESUMEABLE -- thread is resumable. Default is TRUE + @param[in] value Proper value: \n + TRUE(1) -- TRUE for the property \n + FALSE(0) -- FALSE for the property + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Failure because of invalid thread_id input \n + #QURT_ENOTALLOWED -- Failure because of the operation is not allowed, for example, in a secure process/CPZ process. + + @dependencies + None. + */ +int qurt_thread_set_thread_property( unsigned int thread_id, unsigned int property_id, unsigned int value ); + +/**@ingroup func_qurt_thread_get_group_id + Get the group id of the thread specified by thread_id.\n + + @param[in] thread_id Thread identifier + @param[out] group_id Pointer to the variable of group identifier + + @return + #QURT_EOK -- Success \n + #QURT_EINVALID -- Thread id is invalid, or the process has no groups enabled \n + #QURT_ENOTALLOWED -- Operation is not allowed \n + + @dependencies + None. +*/ +int qurt_thread_get_group_id(qurt_thread_t thread_id, unsigned int* group_id); + +#endif /* __ASSEMBLER__ */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread_context.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread_context.h new file mode 100755 index 0000000000000..bab09deec8889 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_thread_context.h @@ -0,0 +1,234 @@ +#ifndef QURT_THREAD_CONTEXT_H +#define QURT_THREAD_CONTEXT_H +/** + @file qurt_thread_context.h + @brief Kernel thread context structure + +EXTERNAL FUNCTIONS + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2018-2022 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond internal_only */ + +#define THREAD_ITERATOR_END ((qurt_thread_t)(-1)) /**< Thread iterator is complete. */ + + +/**@ingroup func_qurt_thread_iterator_create +Gives the ability to the caller to enumerate threads in the system. + +@return +Handle of the newly created iterator must be passed for +subsequent operations on the iterator. + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_create(void) +{ + return qurt_qdi_handle_invoke(QDI_HANDLE_GENERIC, QDI_OS_THREAD_ITERATOR_CREATE); +} + +/**@ingroup func_qurt_thread_iterator_next +Iterates over the list of threads in the system. + +@datatypes +#qurt_thread_t + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#THREAD_ITERATOR_END -- iterator has reached the end of the thread list. \n +Other values indicate a valid thread_id. + +@dependencies +None. +*/ +static inline qurt_thread_t qurt_thread_iterator_next(int iter) +{ + return (qurt_thread_t)qurt_qdi_handle_invoke(iter, QDI_OS_THREAD_ITERATOR_NEXT); +} + +/**@ingroup func_qurt_thread_iterator_destroy +Cleans up thread iterator resources. + +@param[in] iter Iterator handle returned by qurt_thread_iterator_create(). + +@return +#QURT_EOK -- Successful completion of operation \n +#QURT_EFATAL -- Invalid handle passed + +@dependencies +None. +*/ +static inline int qurt_thread_iterator_destroy(int iter) +{ + return qurt_qdi_close(iter); +} + +/**@ingroup func_qurt_thread_context_get_tname +Gets the name of the thread from the specified thread ID. + +@param[in] thread_id Thread for which name is returned. +@param[in,out] name Pointer to the local buffer where name is copied back. +@param[in] max_len Size of the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_tname(unsigned int thread_id, char *name, unsigned char max_len); + +/**@ingroup func_qurt_thread_context_get_prio +Gets the priority for the specified thread. + +@param[in] thread_id Thread for which priority is returned. +@param[in,out] prio Pointer to the local variable where priority is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_prio(unsigned int thread_id, unsigned char *prio); + +/**@ingroup func_qurt_thread_context_get_pcycles +Gets pcycles for the specified thread. + +@param[in] thread_id Thread for which processor cycles are returned. +@param[in,out] pcycles Pointer to the local variable where processor cycles are written. + +@return +#QURT_EOK -- Success \n +Failure otherwise. + +@dependencies +None. +*/ +int qurt_thread_context_get_pcycles(unsigned int thread_id, unsigned long long int *pcycles); + +/**@ingroup func_qurt_thread_context_get_stack_base +Gets the stack base address for the specified thread. + +@param[in] thread_id Thread for which stack base address is returned. +@param[in,out] sbase Pointer to the local variable where stack base address is written. + +@return +QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_base(unsigned int thread_id, unsigned int *sbase); + +/**@ingroup func_qurt_thread_context_get_stack_size +Gets the stack size for the specified thread. + +@param[in] thread_id Thread for which stack size is returned. +@param[in,out] ssize Pointer to the local variable where stack size is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_stack_size(unsigned int thread_id, unsigned int *ssize); + +/**@ingroup func_qurt_thread_context_get_pid +Gets the process ID for the specified thread. + +@param[in] thread_id Thread for which process ID is returned. +@param[in,out] pid Pointer to the local variable where process id is written. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pid(unsigned int thread_id, unsigned int *pid); + +/**@ingroup func_qurt_thread_context_get_pname +Gets the process name for the specified thread. + +@param[in] thread_id Represents the thread for which process name is returned. +@param[in, out] name Pointer to the local buffer where process name is copied back. +@param[in] len Length allocated to the local buffer. + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_thread_context_get_pname(unsigned int thread_id, char *name, unsigned int len); + +/** @addtogroup thread_types +@{ */ +/** Structure that defines how TCB is interpreted to crash dump tools.*/ +/* Keys are defined in consts.h */ +struct qurt_debug_thread_info { +/** @cond */ + char name[QURT_MAX_NAME_LEN]; /**< Name of the thread. */ + struct { + unsigned key; + unsigned val; + } os_info[40]; + unsigned gen_regs[32]; /**< General mode registers. */ + unsigned user_cregs[32]; /**< User mode registers. */ + unsigned guest_cregs[32]; /**< Guest mode registers. */ + unsigned monitor_cregs[64]; /**< Monitor mode registers. */ +/** @endcond */ +}; /* should add up to 1K */ +/** @} */ /* end_addtogroup thread_types */ + + +/**@ingroup func_qurt_system_tcb_dump_get +Cleans up thread iterator resources. + +@datatypes +#qurt_thread_t + +@param[in] thread_id Thread on which the operation must be performed. +@param[in, out] ptr Pointer to the local buffer where contents are written. +@param[in] size Size of the debug thread information structure obtained by calling + qurt_system_tcb_dump_get_size(). + +@return +#QURT_EOK -- Success \n +Failure otherwise + +@dependencies +None. +*/ +int qurt_system_tcb_dump_get(qurt_thread_t thread_id, void *ptr, size_t size); +/** @endcond */ + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_THREAD_CONTEXT_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_timer.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_timer.h new file mode 100755 index 0000000000000..7bdfdb8f3c3df --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_timer.h @@ -0,0 +1,560 @@ +#ifndef QURT_TIMER_H +#define QURT_TIMER_H +/** + @file qurt_timer.h + @brief Prototypes of qurt_timer API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + + +#include "qurt_anysignal.h" +#include "qurt_signal2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/**@addtogroup timer_const_macros +@{ */ +/** + Default values. +*/ +/** @xreflabel{hdr:QURT_TIMER_ONESHOT}*/ +#define QURT_TIMER_DEFAULT_TYPE QURT_TIMER_ONESHOT /**< One shot.*/ +#define QURT_TIMER_DEFAULT_DURATION 1000uL /**< Default duration. */ +#define QURT_TIMER_DEFAULT_EXPIRY 0uL /**< Default expiration. */ + +/** + Conversion from microseconds to timer ticks. + */ +#define QURT_TIMER_TIMETICK_FROM_US(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + +/** + Conversion from timer ticks to microseconds at the nominal frequency. +*/ +#define QURT_TIMER_TIMETICK_TO_US(ticks) qurt_timer_timetick_to_us(ticks) + +/** Minimum microseconds value is 100 microseconds (sleep timer).*/ +#define QURT_TIMER_MIN_DURATION 100uL + +/** + Maximum microseconds value for Qtimer is 1,042,499 hours. +*/ +#define QURT_TIMER_MAX_DURATION QURT_SYSCLOCK_MAX_DURATION + +/** + Timer clock for Qtimer is 19.2 MHz. +*/ +#define QURT_TIMER_MAX_DURATION_TICKS QURT_SYSCLOCK_MAX_DURATION_TICKS + +/** + Sleep timer error margin for Qtimer is 1,000 ticks ~52 us. +*/ +#define QURT_TIMETICK_ERROR_MARGIN QURT_SYSCLOCK_ERROR_MARGIN + +/* + qurt_timer group defines. +*/ +#define QURT_TIMER_MAX_GROUPS 5U /**< Maximum groups.*/ +#define QURT_TIMER_DEFAULT_GROUP 0U /**< Default groups. */ +/** @} */ /* end_addtogroup timer_const_macros */ + +/** @addtogroup timer_types +@{ */ +/** + QuRT timer types. + */ +typedef enum +{ + QURT_TIMER_ONESHOT = 0, /**< One shot.*/ + /** @xreflabel{hdr:QURT_TIMER_PERIODIC}*/ + QURT_TIMER_PERIODIC /**< Periodic. */ +} qurt_timer_type_t; + + +/*============================================================================= + TYPEDEFS +=============================================================================*/ + +/** QuRT timer type.*/ +typedef unsigned int qurt_timer_t; + +/** QuRT timer duration type. */ +typedef unsigned long long qurt_timer_duration_t; + +/** QuRT timer time type. */ +typedef unsigned long long qurt_timer_time_t; + +typedef void (*pfn_t)(void); +/** QuRT timer attribute type. */ +typedef struct +{ + /** @cond */ + unsigned int magic; /**< Magic number to verify the qmsgq_attr_t pointer. */ + + qurt_timer_duration_t duration; /**< Specifies the duration of the new timer. */ + + qurt_timer_time_t expiry; /**< Specifies the absolute expiry of the new timer. */ + + qurt_timer_duration_t remaining; /**< Specifies the remaining time of an active timer. */ + + qurt_timer_type_t type; /**< Specifies the timer type; only #QURT_TIMER_ONESHOT and + #QURT_TIMER_PERIODIC are supported. */ + + unsigned int group; /**< Group number of the timer; the criterion used to disable or enable the set + of timers. */ + pfn_t pFn; /**< Callback other than the signal set */ + /** @endcond */ +} +qurt_timer_attr_t; + +/** @} */ /* end_addtogroup timer_types */ +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_timer_stop + @xreflabel{sec:qurt_timer_stop} + Stops a running timer. + The timer must be a one-shot timer. + + @note1hang Restart stopped timers with the timer restart operation, + see Section @xref{sec:qurt_timer_restart}. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one shot timer. \n + #QURT_EMEM -- Out of memory error. + + @dependencies + None. + */ +int qurt_timer_stop (qurt_timer_t timer); + +/**@ingroup func_qurt_timer_restart + @xreflabel{sec:qurt_timer_restart} + Restarts a stopped timer with the specified duration. The timer must be a one-shot timer. + Timers stop after they have expired or after they are explicitly stopped with qurt_timer_stop(). + A restarted timer expires after the specified duration, the starting time is when the function is called. + + @note1hang Timers stop after they have expired or after they are explicitly + stopped with the timer stop operation, see Section @xref{sec:qurt_timer_stop}. + + @datatypes + #qurt_timer_t \n + #qurt_timer_duration_t + + @param[in] timer Timer object. + @param[in] duration Timer duration (in microseconds) before the restarted timer + expires again. + The valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Invalid timer ID or duration value. \n + #QURT_ENOTALLOWED -- Timer is not a one-shot timer. \n + #QURT_EMEM -- Out-of-memory error. + + @dependencies + None. + */ +int qurt_timer_restart (qurt_timer_t timer, qurt_timer_duration_t duration); + + +/**@ingroup func_qurt_timer_create + Creates a timer.\n + Allocates and initializes a timer object, and starts the timer. + + @note1hang A timer event handler must be defined to wait on the specified signal + to handle the timer event. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t \n + #qurt_anysignal_t + + @param[out] timer Pointer to the created timer object. + @param[in] attr Pointer to the timer attribute structure. + @param[in] signal Pointer to the signal object set when timer expires. + @param[in] mask Signal mask, which specifies the signal to set in the signal object when the + time expires. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to create the timer. \n + #QURT_EINVALID -- One of the arguments in the attr field is invalid. \n + Other error code -- Operation failed. \n + + @dependencies + None. + */ +int qurt_timer_create (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_anysignal_t *signal, unsigned int mask); + +int qurt_timer_create_sig2 (qurt_timer_t *timer, const qurt_timer_attr_t *attr, + const qurt_signal2_t *signal, unsigned int mask); + +/**@ingroup func_qurt_timer_attr_init + Initializes the specified timer attribute structure with default attribute values: \n + - Timer duration -- #QURT_TIMER_DEFAULT_DURATION (Section @xref{dox:timers}) \n + - Timer type -- #QURT_TIMER_ONESHOT \n + - Timer group -- #QURT_TIMER_DEFAULT_GROUP + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_init(qurt_timer_attr_t *attr); + + +/*Tech Comm note: removed qurt_timer_attr_set_pfn from documentation 9/10/2020 +@ingroup func_qurt_timer_attr_set_pfn + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the destination structure for the timer attributes. + @param[in] pFn pFn. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_pfn(qurt_timer_attr_t *attr, pfn_t pFn); + + +/**@ingroup func_qurt_timer_attr_set_duration + Sets the timer duration in the specified timer attribute structure.\n + + The timer duration specifies the interval (in microseconds) between the creation of the + timer object and the generation of the corresponding timer event. + + The timer duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). Otherwise, the set operation is ignored. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] duration Timer duration (in microseconds). + Valid range is #QURT_TIMER_MIN_DURATION to + #QURT_TIMER_MAX_DURATION. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_attr_set_expiry + Sets the absolute expiry time in the specified timer attribute structure.\n + The timer expiry specifies the absolute time (in microseconds) of the generation of the + corresponding timer event.\n + Timer expiries are relative to when the system first began executing. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_time_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] time Timer expiry. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_expiry(qurt_timer_attr_t *attr, qurt_timer_time_t time); + +/**@ingroup func_qurt_timer_attr_get_duration + Gets the timer duration from the specified timer attribute structure. + The value returned is the duration that was originally set for the timer. + + @note1hang This function does not return the remaining time of an active timer; + use qurt_timer_attr_get_remaining() to get the remaining time. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attributes object + @param[out] duration Pointer to the destination variable for timer duration. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_duration(qurt_timer_attr_t *attr, qurt_timer_duration_t *duration); + +/**@ingroup func_qurt_timer_attr_get_remaining + Gets the timer remaining duration from the specified timer attribute structure. \n + + The timer remaining duration indicates (in microseconds) how much time remains before + the generation of the next timer event on the corresponding timer. + In most cases this function assumes that the timer attribute structure was obtained by + calling qurt_timer_get_attr(). + + @note1hang This attribute is read-only and thus has no set operation defined for it. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_duration_t + + @param[in] attr Pointer to the timer attribute object. + @param[out] remaining Pointer to the destination variable for remaining time. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_remaining(qurt_timer_attr_t *attr, qurt_timer_duration_t *remaining); + +/**@ingroup func_qurt_timer_attr_set_type + Sets the timer type in the specified timer attribute structure. + + The timer type specifies the functional behavior of the timer: \n + - A one-shot timer (#QURT_TIMER_ONESHOT) waits for the specified timer duration + and then generates a single timer event. After this the timer is nonfunctional. \n + - A periodic timer (#QURT_TIMER_PERIODIC) repeatedly waits for the specified + timer duration and then generates a timer event. The result is a series of timer + events with interval equal to the timer duration. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in,out] attr Pointer to the timer attribute structure. + @param[in] type Timer type. Values are: \n + - #QURT_TIMER_ONESHOT -- One-shot timer. \n + - #QURT_TIMER_PERIODIC -- Periodic timer. @tablebulletend + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_type(qurt_timer_attr_t *attr, qurt_timer_type_t type); + +/**@ingroup func_qurt_timer_attr_get_type + Gets the timer type from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t \n + #qurt_timer_type_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] type Pointer to the destination variable for the timer type. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_type(qurt_timer_attr_t *attr, qurt_timer_type_t *type); + +/**@ingroup func_qurt_timer_attr_set_group + Sets the timer group identifier in the specified timer attribute structure.\n + The timer group identifier specifies the group that the timer belongs to. Timer groups are + used to enable or disable one or more timers in a single operation. \n + The timer group identifier value must be between 0 and (#QURT_TIMER_MAX_GROUPS - 1). + See Section @xref{dox:timers}. + + @datatypes + #qurt_timer_attr_t + + @param[in,out] attr Pointer to the timer attribute object. + @param[in] group Timer group identifier; + Valid range is 0 to (#QURT_TIMER_MAX_GROUPS - 1). + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_set_group(qurt_timer_attr_t *attr, unsigned int group); + +/**@ingroup func_qurt_timer_attr_get_group + Gets the timer group identifier from the specified timer attribute structure. + + @datatypes + #qurt_timer_attr_t + + @param[in] attr Pointer to the timer attribute structure. + @param[out] group Pointer to the destination variable for the timer group identifier. + + @return + None. + + @dependencies + None. + */ +void qurt_timer_attr_get_group(qurt_timer_attr_t *attr, unsigned int *group); + +/**@ingroup func_qurt_timer_get_attr + @xreflabel{hdr:qurt_timer_get_attr} + Gets the timer attributes of the specified timer when it was created. + + @datatypes + #qurt_timer_t \n + #qurt_timer_attr_t + + @param[in] timer Timer object. + @param[out] attr Pointer to the destination structure for timer attributes. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_get_attr(qurt_timer_t timer, qurt_timer_attr_t *attr); + +/**@ingroup func_qurt_timer_delete + Deletes the timer.\n + Destroys the specified timer and deallocates the timer object. + + @datatypes + #qurt_timer_t + + @param[in] timer Timer object. + + @return + #QURT_EOK -- Success. \n + #QURT_EVAL -- Argument passed is not a valid timer. + + @dependencies + None. + */ +int qurt_timer_delete(qurt_timer_t timer); + +/**@ingroup func_qurt_timer_sleep + Suspends the current thread for the specified amount of time. + The sleep duration value must be between #QURT_TIMER_MIN_DURATION and + #QURT_TIMER_MAX_DURATION (Section @xref{dox:timers}). + + @datatypes + #qurt_timer_duration_t + + @param[in] duration Interval (in microseconds) between when the thread is suspended + and when it is re-awakened. + + @return + #QURT_EOK -- Success. \n + #QURT_EMEM -- Not enough memory to perform the operation. + + @dependencies + None. + */ + +int qurt_timer_sleep(qurt_timer_duration_t duration); + +/**@ingroup func_qurt_timer_group_disable + Disables all timers that are assigned to the specified timer group. + If a specified timer is already disabled, ignore it. + If a specified timer is expired, do not process it. + If the specified timer group is empty, do nothing. + + @note1hang When a timer is disabled its remaining time does not change, thus it + cannot generate a timer event. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_disable (unsigned int group); + +/**@ingroup func_qurt_timer_group_enable + Enables all timers that are assigned to the specified timer group. + If a specified timer is already enabled, ignore it. + If a specified timer is expired, process it. + If the specified timer group is empty, do nothing. + + @param[in] group Timer group identifier. + + @return + #QURT_EOK -- Success. + + @dependencies + None. + */ +int qurt_timer_group_enable (unsigned int group); + + +/** + Notifies the timer server recovery from power collapse. The server + must account for any missed interrupts during power collapse. + */ +void qurt_timer_recover_pc (void); + +/** + Determines whether the Qtimer is initialized. + + @return + 0 -- Not initialized. \n + Nonzero -- Initialized. + */ +static inline int qurt_timer_is_init (void) {return 1;} + +/**@ingroup func_qurt_timer_get_ticks + Gets current ticks. The ticks are accumulated since the RTOS + has started. Each tick is equal to a single timer clock + cycle, where the frequency is 32 KHz on RGPT or 19.2 MHz on Qtimer. + + @return + Ticks since system started. + */ +unsigned long long qurt_timer_get_ticks (void); + +#define qurt_timer_timetick_from_us(us) QURT_SYSCLOCK_TIMETICK_FROM_US(us) + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TIMER_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tlb.h new file mode 100755 index 0000000000000..b1b2d261d31c0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tlb.h @@ -0,0 +1,215 @@ +#ifndef QURT_TLB_H +#define QURT_TLB_H + +/** + @file qurt_tlb.h + @brief Prototypes of TLB API + The TLB APIs allow explicit control of the portion of TLB between TLB_first_replaceble and TLB_LAST_REPLACEABLE. + Both are nonconfigurable for the time being. This portion of TLB is permanently assigned/locked unless manually removed + by qurt_tlb_remove. Implementation does not change depending on the configuration, such as whether CONFIG_STATIC is set or not. + In CONFIG_STATIC=y, TLB_LAST_REPLACEABLE is set to the last TLB index, which indicates that the entire TLB is permanently + assigned and is not backed up by page table (page table does not exist). TLB indicies are maintained through a 64-bit bitmask. + A new entry is placed in the first available slot. + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2013, 2021, 2023 +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. +=============================================================================*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tlb_entry_create + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (such as if the address is not aligned with the + size), the entry is created and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the ASID argument to -1. + + @datatypes + #qurt_addr_t \n + #qurt_paddr_t \n + #qurt_mem_cache_mode_t \n + #qurt_perm_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr Physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry is not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry is not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry is not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_t paddr, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_create_64 + Creates a new TLB entry with the specified mapping attributes in the TLB of the Hexagon processor. \n + @note1hang If the specified attributes are not valid (the address is not aligned with the + size), the entry is not created, and an error result is returned.\n + @note1cont To set the G bit in the new TLB entry, set the asid argument to -1. + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] paddr_64 64-bit physical memory address. + @param[in] size Size of memory region to map (in bytes). + @param[in] cache_attribs Cache mode (writeback, and so on). + @param[in] perms Access permissions. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully created.\n + #QURT_EFATAL -- Entry was not created; the TLB is full. \n + #QURT_ETLBCREATESIZE -- Entry was not created; the incorrect size was specified. \n + #QURT_ETLBCREATEUNALIGNED -- Entry was not created; an unaligned address was specified. \n + #QURT_EINVALID -- Invalid cache attributes / permissions provided. + + */ +int qurt_tlb_entry_create_64 (unsigned int *entry_id, qurt_addr_t vaddr, qurt_paddr_64_t paddr_64, qurt_size_t size, qurt_mem_cache_mode_t cache_attribs, qurt_perm_t perms, int asid); + +/**@ingroup func_qurt_tlb_entry_delete + Deletes the specified TLB entry from the TLB of the Hexagon processor. + If the specified entry does not exist, no deletion occurs and an error result is returned. + + @param[in] entry_id TLB entry identifier. + + @return + #QURT_EOK -- TLB entry successfully deleted. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_delete (unsigned int entry_id); + +/**@ingroup func_qurt_tlb_entry_query + Searches for the specified TLB entry in the TLB of the Hexagon processor. + If the TLB entry is found, its entry identifier is returned. + + @datatypes + #qurt_addr_t + + @param[out] entry_id TLB entry identifier. + @param[in] vaddr Virtual memory address. + @param[in] asid ASID (space ID). + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_query (unsigned int *entry_id, qurt_addr_t vaddr, int asid); + +/**@ingroup func_qurt_tlb_entry_set + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[in] entry 64-bit TLB entry to store. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set (unsigned int entry_id, unsigned long long int entry); + +/**@ingroup func_qurt_tlb_entry_get + Gets the TLB entry. \n + Returns the specified 64-bit TLB entry in the TLB of the Hexagon processor. + + @param[in] entry_id TLB entry identifier. + @param[out] entry 64-bit TLB entry. + + @return + #QURT_EOK -- TLB entry successfully returned. \n + #QURT_EFATAL -- TLB entry does not exist. + + @dependencies + None. + **/ +int qurt_tlb_entry_get (unsigned int entry_id, unsigned long long int *entry); + +/**@ingroup func_qurt_tlb_get_pager_physaddrs + Searches the TLB of the Hexagon processor, and returns all physical addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_phys_addrs Pointer to the return array of pager physical addresses. + + @return + Integer -- Number of addresses returned in array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_physaddr(unsigned int** pager_phys_addrs); + +/**@ingroup func_qurt_tlb_get_pager_virtaddr + Searches the TLB of the Hexagon processor, and returns all virtual addresses that belong to the pager. + Each returned address indicates the starting address of an active page. + +The function return value indicates the number of addresses returned. + + @param[out] pager_virt_addrs Pointer to the return array of pager virtual addresses. + + @return + Integer -- Number of addresses returned in the array. + + @dependencies + None. +*/ + +unsigned int qurt_tlb_get_pager_virtaddr(unsigned int** pager_virt_addrs); + + +/**@ingroup func_qurt_tlb_entry_set2 + Sets the TLB entry by storing an entry at the specified location + in the TLB of the Hexagon processor. An additional option can be passed + to lock the TLB entry in the TLB of the Hexagon processor. + + @param[in] id TLB entry identifier. + @param[in] tlb 64-bit TLB entry to store. + @param[in] lock Nonzero value indicates that the TLB entry must be locked in the hardware TLB. + + @return + #QURT_EOK -- Entry successfully stored in the TLB. \n + #QURT_EFATAL -- Entry not set at the specified location. + + @dependencies + None. + **/ +int qurt_tlb_entry_set2(unsigned id, unsigned long long tlb, unsigned lock); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLB_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tls.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tls.h new file mode 100755 index 0000000000000..6ec3b39ff5cb0 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_tls.h @@ -0,0 +1,100 @@ +#ifndef QURT_TLS_H +#define QURT_TLS_H +/** + @file qurt_tls.h + @brief Prototypes of TLS APIs + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================= + FUNCTIONS +=============================================================================*/ + +/**@ingroup func_qurt_tls_create_key + @xreflabel{sec:tls_create_key} + Creates a key for accessing a thread local storage data item.\n + Subsequent get and set operations use the key value. + + @note1hang The destructor function performs any clean-up operations needed by a thread + local storage item when its containing thread is deleted (Section @xref{sec:qurt_thread_exit}). + + @param[out] key Pointer to the newly created thread local storage key value. + @param[in] destructor Pointer to the key-specific destructor function. Passing NULL + specifies that no destructor function is defined for the key. + + @return + #QURT_EOK -- Key successfully created. \n + #QURT_ETLSAVAIL -- No free TLS key available. + + @dependencies + None. + */ +int qurt_tls_create_key (int *key, void (*destructor)(void *)); + +/**@ingroup func_qurt_tls_set_specific + Stores a data item to thread local storage along with the specified key. + + @param[in] key Thread local storage key value. + @param[in] value Pointer to user data value to store. + + @return + #QURT_EOK -- Data item successfully stored. \n + #QURT_EINVALID -- Invalid key. \n + #QURT_EFAILED -- Invoked from a non-thread context. + */ +int qurt_tls_set_specific (int key, const void *value); + +/**@ingroup func_qurt_tls_get_specific + Loads the data item from thread local storage. \n + Returns the data item that is stored in thread local storage with the specified key. + The data item is always a pointer to user data. + + @param[in] key Thread local storage key value. + + @return + Pointer -- Data item indexed by key in thread local storage. \n + 0 (NULL) -- Key out of range. + + @dependencies + None. + */ +void * __attribute__((section(".text.qurt_tls_get_specific "))) qurt_tls_get_specific (int key); + + +/**@ingroup func_qurt_tls_delete_key + Deletes the specified key from thread local storage. + + @note1hang Explicitly deleting a key does not execute any destructor function that is + associated with the key (Section @xref{sec:tls_create_key}). + + @param[in] key Thread local storage key value to delete. + + @return + #QURT_EOK -- Key successfully deleted. \n + #QURT_ETLSENTRY -- Key already free. + + @dependencies + None. + */ +int qurt_tls_delete_key (int key); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TLS_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_trace.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_trace.h new file mode 100755 index 0000000000000..541f8f1d34bf6 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_trace.h @@ -0,0 +1,317 @@ +#ifndef QURT_TRACE_H +#define QURT_TRACE_H +/** + @file qurt_trace.h + @brief Prototypes of system call tracing helpers API + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2021-2023 by Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + GLOBAL VARIABLES +=============================================================================*/ +/** @cond internal_only */ +/** @addtogroup etm_macros +@{ */ +/* ETM trace types. */ +#define QURT_ETM_TYPE_PC_ADDR (1U<<0) /**< PC address.*/ +#define QURT_ETM_TYPE_MEMORY_ADDR (1U<<1) /**< Memory address. */ +#define QURT_ETM_TYPE_TESTBUS (1U<<2) /**< Test bus. */ +#define QURT_ETM_TYPE_CYCLE_ACCURATE (1U<<3) /**< Cycle accurate. */ +#define QURT_ETM_TYPE_CYCLE_COARSE (1U<<4) /**< Cycle coarse. */ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR) /**< PC and memory address. */ +#define QURT_ETM_TYPE_PC_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC address and test bus. */ +#define QURT_ETM_TYPE_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< Memory address and test bus.*/ +#define QURT_ETM_TYPE_PC_AND_MEMORY_ADDR_AND_TESTBUS (QURT_ETM_TYPE_PC_ADDR|QURT_ETM_TYPE_MEMORY_ADDR|QURT_ETM_TYPE_TESTBUS) /**< PC, memory address, and test bus. */ + +/* ETM routes. */ +#define QURT_ETM_ROUTE_TO_QDSS 0U /**< ETM route to QDSS. */ +#define QURT_ETM_ROUTE_TO_Q6ETB 1U /**< ETM route to Q6ETB. */ + +/* ETM filters. */ +#define QURT_ETM_TRACE_FILTER_ALL_DEFAULT 0U /*< Filter all as default. */ +#define QURT_ETM_TRACE_FILTER_HNUM0 (1U<<0) /*< Filter HNUM0. */ +#define QURT_ETM_TRACE_FILTER_HNUM1 (1U<<1) /*< Filter HNUM1. */ +#define QURT_ETM_TRACE_FILTER_HNUM2 (1U<<2) /*< Filter HNUM2. */ +#define QURT_ETM_TRACE_FILTER_HNUM3 (1U<<3) /*< Filter HNUM3. */ +#define QURT_ETM_TRACE_FILTER_HNUM4 (1U<<4) /*< Filter HNUM4. */ +#define QURT_ETM_TRACE_FILTER_HNUM5 (1U<<5) /*< Filter HNUM5. */ +#define QURT_ETM_TRACE_FILTER_HNUM6 (1U<<6) /*< Filter HNUM6. */ +#define QURT_ETM_TRACE_FILTER_HNUM7 (1U<<7) /*< Filter HNUM7. */ +#define QURT_ETM_TRACE_FILTER_HNUM8 (1U<<8) /*< Filter HNUM8. */ +#define QURT_ETM_TRACE_FILTER_HNUM9 (1U<<9) /*< Filter HNUM9. */ +#define QURT_ETM_TRACE_FILTER_HNUM10 (1U<<10) /*< Filter HNUM10. */ +#define QURT_ETM_TRACE_FILTER_HNUM11 (1U<<11) /*< Filter HNUM11. */ +#define QURT_ETM_TRACE_FILTER_HNUM12 (1U<<12) /*< Filter HNUM12. */ +#define QURT_ETM_TRACE_FILTER_HNUM13 (1U<<13) /*< Filter HNUM13. */ +#define QURT_ETM_TRACE_FILTER_HNUM14 (1U<<14) /*< Filter HNUM14. */ +#define QURT_ETM_TRACE_FILTER_HNUM15 (1U<<15) /*< Filter HNUM15. */ +#define QURT_ETM_TRACE_FILTER_ALL QURT_ETM_TRACE_FILTER_ALL_DEFAULT + +#define QURT_ETM_TRACE_FILTER_CLUSTER0 (1<<16) /*< Filter trace cluster0 address. */ +#define QURT_ETM_TRACE_FILTER_CLUSTER1 (1<<17) /*< Filter trace cluster1 address. */ +#define QURT_ETM_TRACE_FILTER_PC_RANGE (1<<19) /*< Filter PC address range. */ + +/* ETM memory source - PC or data access */ +#define QURT_ETM_SOURCE_PC 0U /**< ETM memory source of SAC* is PC. */ +#define QURT_ETM_SOURCE_DATA 1U /**< ETM memory source of SAC* is data. */ + +/* Period between synchronization traces */ +#define QURT_ETM_ASYNC_PERIOD 0 /**< Async.*/ +#define QURT_ETM_ISYNC_PERIOD 1 /**< Isync.*/ +#define QURT_ETM_GSYNC_PERIOD 2 /**< Gsync. */ + +/* ETM enable flags */ +#define QURT_ETM_OFF 0U /**< ETM off. */ +#define QURT_ETM_ON 1U /**< ETM on. */ +/** @endcond */ +/** @} */ /* end_addtogroup etm_macros */ + +/** @addtogroup function_tracing_macro +@{ */ +/* ETM setup return values */ +#define QURT_ETM_SETUP_OK 0 /**< ETM setup OK. */ +#define QURT_ETM_SETUP_ERR 1 /**< ETM setup error. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* ETM breakpoint types */ +#define QURT_ETM_READWRITE_BRKPT 0U /**< ETM read/write breakpoint. */ +#define QURT_ETM_READ_BRKPT 1U /**< ETM read breakpoint. */ +#define QURT_ETM_WRITE_BRKPT 2U /**< ETM write breakpoint. */ +#define QURT_ETM_BRKPT_INVALIDATE 3U /**< Invalidate breakpoint. */ +/** @addtogroup function_tracing_macro +@{ */ +/* ATB status flags */ +#define QURT_ATB_OFF 0 /**< ATB off. */ +#define QURT_ATB_ON 1 /**< ATB on. */ +/** @} */ /* end_addtogroup function_tracing_macro */ +/* DTM enable flags */ +#define QURT_DTM_OFF 0 /**< DTM off. */ +#define QURT_DTM_ON 1 /**< DTM on. */ + +/** @addtogroup function_tracing_datatypes +@{ */ +/**STM trace information. */ +typedef struct qurt_stm_trace_info { + /** @cond */ + unsigned int stm_port_addr[6]; /* STM port address to which trace data must be written.*/ + unsigned int thread_event_id; /* Event ID for context switches.*/ + unsigned int interrupt_event_id; /* Event ID for interrupts. */ + unsigned int marker; /* Marker value that must be written at the beginning of the trace. */ + /** @endcond */ +} qurt_stm_trace_info_t; +/** @} */ /* end_addtogroup function_tracing_datatypes */ +/*============================================================================= + GLOBAL FUNCTIONS +=============================================================================*/ + + +/**@ingroup func_qurt_trace_get_marker + Gets the kernel trace marker.\n + Returns the current value of the kernel trace marker. + The marker consists of a hardware thread identifier and an index into the kernel trace + buffer. The trace buffer records kernel events. + + @note1hang Using this function with qurt_trace_changed() + determines whether certain kernel events occurred in a block of code. + + @return + Integer -- Kernel trace marker. + + @dependencies + None. +*/ +unsigned int qurt_trace_get_marker(void); + +/**@ingroup func_qurt_trace_changed + Determines whether specific kernel events have occurred. \n + Returns a value that indicates whether the specified kernel events are recorded in the + kernel trace buffer since the specified kernel trace marker was obtained. + + The prev_trace_marker parameter specifies a kernel trace marker that was obtained by calling + qurt_trace_get_marker(). + @cond rest_dist For more information on the mask value, see the description of the trace_mask element in + @xhyperref{80VB41992,80-VB419-92}. \n @endcond + + @note1hang Used with qurt_trace_get_marker(), this function determines whether + certain kernel events occurred in a block of code.\n + @note1cont This function cannot determine whether a specific kernel event type has + occurred unless that event type has been enabled in the trace_mask element + of the system configuration file. \n + @note1cont QuRT supports the recording of interrupt and context switch events only (such as + a trace_mask value of 0x3). + + @param[in] prev_trace_marker Previous kernel trace marker. + @param[in] trace_mask Mask value that indicates which kernel events to check for. + + @returns + 1 -- Kernel events of the specified type have occurred since the + specified trace marker was obtained.\n + 0 -- No kernel events of the specified type have occurred since the + specified trace marker was obtained. + + @dependencies + None. +*/ +int qurt_trace_changed(unsigned int prev_trace_marker, unsigned int trace_mask); + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +/** @addtogroup function_tracing_macro +@{ */ +#ifndef QURT_DEBUG +#define QURT_TRACE(str, ...) __VA_ARGS__ + /**< Function tracing is implemented with the QURT_TRACE debug macro, which + optionally generates printf statements both before and after every function call that is + passed as a macro argument. + + For example, in the following macro calls in the source code: + @code + QURT_TRACE(myfunc, my_func(33)) + + @endcode + generates the following debug output: + @code + myfile:nnn: my_func >>> calling my_func(33) + myfile:nnn: my_func >>> returned my_func(33) + @endcode + The debug output includes the source file and line number of the function call, along with + the text of the call. Compile the client source file with -D __FILENAME__ + defined for its file name. + + The library function qurt_printf() generates the debug output. + The QURT_DEBUG symbol controls generation of the debug output. If this symbol is + not defined, function tracing is not generated.\n + @note1hang The debug macro is accessed through the QuRT API header file. + */ +#else +#define QURT_TRACE(str, ...) \ + do { \ + qurt_printf("%s:%d: %s: >>> calling %s\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + __VA_ARGS__; \ + qurt_printf("%s:%d: %s: <<< %s returned\n",__FILENAME__,__LINE__,(str),#__VA_ARGS__); \ + } while (0); +#endif +/** @} */ /* end_addtogroup function_tracing_macro */ + +/**@ingroup func_qurt_etm_set_pc_range + Sets the PC address range for ETM filtering. + Depending on the Hexagon core design, a maximum of four PC ranges are supported. + + @param[in] range_num 0 to 3. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_pc_range(unsigned int range_num, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_range + Sets the address range for ETM filtering. + It allows the user to select the source type of addresses - QURT_ETM_SOURCE_PC and QURT_ETM_SOURCE_DATA. + + @param[in] addr_source_type Type of the address source:\n + - #QURT_ETM_SOURCE_PC \n + - #QURT_ETM_SOURCE_DATA @tablebulletend + @param[in] trig_block_num 0 to 3. + @param[in] pid pid of the process + 1. Any valid PID number will enable the ASID based trace filtering. + 2. QURT_ETM_NO_PID - Disable the ASID based trace filtering. + @param[in] low_addr Lower boundary of PC address range. + @param[in] high_addr Higher boundary of PC address range. + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. +*/ +unsigned int qurt_etm_set_range(unsigned int addr_source_type, unsigned int trig_block_num, unsigned int pid, unsigned int low_addr, unsigned int high_addr); + +/**@ingroup func_qurt_etm_set_atb + Sets the advanced trace bus (ATB) state to notify QuRT that the ATB is actively enabled or disabled. + QuRT performs the corresponding actions at low power management. + + @param[in] flag Values: \n + #QURT_ATB_ON \n + #QURT_ATB_OFF + + @returns + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure + + @dependencies + None. +*/ +unsigned int qurt_etm_set_atb(unsigned int flag); + +/**@ingroup func_qurt_etm_set_sync_period + Sets the period for types of synchronization trace packets. \n + ASYNC defines the period between alignment synchronization packets. + Period is in terms of bytes in the packet stream. \n + ISYNC defines the period between instruction synchronization packets. + Period is per thread and is defined as the bytes sent out for that thread. \n + GSYNC is the defined period in thread cycles between GSYNC packets. + + @param[in] sync_type Type of synchronization packets: \n + #QURT_ETM_ASYNC_PERIOD \n + #QURT_ETM_ISYNC_PERIOD \n + #QURT_ETM_GSYNC_PERIOD + @param[in] period Period value. + + @return + #QURT_ETM_SETUP_OK -- Success. \n + #QURT_ETM_SETUP_ERR -- Failure. + + @dependencies + None. + */ +unsigned int qurt_etm_set_sync_period(unsigned int sync_type, unsigned int period); + +/**@ingroup func_qurt_stm_trace_set_config + Sets up a STM port for tracing events. + + @datatypes + #qurt_stm_trace_info_t + + @param[in] stm_config_info Pointer to the STM trace information used to set up the trace + in the kernel. + The strucure must have the following:\n + - One port address per hardware thread \n + - Event ID for context switches \n + - Event ID for interrupt tracing n + - Header or marker to identify the beginning of the trace. @tablebulletend + + @return + #QURT_EOK -- Success. \n + #QURT_EINVALID -- Failure; possibly because the passed port address is not in the page table. + + @dependencies + None. + */ +unsigned int qurt_stm_trace_set_config(qurt_stm_trace_info_t *stm_config_info); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TRACE_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_types.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_types.h new file mode 100755 index 0000000000000..bdb83a3fe2fb2 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_types.h @@ -0,0 +1,294 @@ +#ifndef QURT_TYPES_H +#define QURT_TYPES_H +/** + @file qurt_types.h + @brief Contains types common to all configurations + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) Qualcomm Technologies, Inc. +All Rights Reserved. +Confidential and Proprietary - Qualcomm Technologies, Inc. + +=============================================================================*/ + + +//#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================= + CONSTANTS AND MACROS +=============================================================================*/ +#define PGA_BITFIELD_MASK(hi,lo) (((~0u)>>(31U-((hi)-(lo))))<<(lo)) +#define PGA_BITFIELD_GET(x,hi,lo) (((x)&PGA_BITFIELD_MASK((hi),(lo)))>>(lo)) +#define PGA_BITFIELD_INS(hi,lo,v) (((v)<<(lo))&PGA_BITFIELD_MASK((hi),(lo))) +#define PGA_BITFIELD_SET(x,hi,lo,v) ((x)=((x)&~PGA_BITFIELD_MASK((hi),(lo)))|PGA_BITFIELD_INS((hi),(lo),(v))) +#define QURT_PGATTR_C_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 3U, 0U) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_GET(pga) PGA_BITFIELD_GET((pga).pga_value, 5U, 4U) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_C_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 3U, 0U, (v)) /* Bits 3-0: cache */ +#define QURT_PGATTR_A_SET(pga,v) PGA_BITFIELD_SET((pga).pga_value, 5U, 4U, (v)) /* Bits 5-4: bus attr */ +#define QURT_PGATTR_MKRAW(v) ((qurt_pgattr_t){.pga_value = (v)}) +#define QURT_PGATTR_MK(c,a) QURT_PGATTR_MKRAW(PGA_BITFIELD_INS(3U,0U,(c))|PGA_BITFIELD_INS(5U,4U,(a))) + +/*return types for qurt_island_get_status2*/ +#define QURT_ISLAND_MODE_NORMAL 0U /**< Normal operating mode */ +#define QURT_ISLAND_MODE_ISLAND 1U /**< Island mode */ +#define QURT_ISLAND_MODE_EXITING 2U /**< In transition from Island mode to Normal mode */ + +/*============================================================================= + FORWARD DECLARATIONS & TYPEDEFS +=============================================================================*/ +/** @addtogroup memory_management_types +@{ */ +typedef unsigned int qurt_addr_t; /**< QuRT address type.*/ +typedef unsigned int qurt_paddr_t; /**< QuRT physical memory address type. */ +/** @cond rest_reg_dist */ +typedef unsigned long long qurt_addr_64_t; /**< QuRT 64-bit memory address type. */ +typedef unsigned long long qurt_paddr_64_t; /**< QuRT 64-bit physical memory address type. */ +typedef unsigned int qurt_mem_region_t; /**< QuRT memory regions type. */ +typedef unsigned int qurt_mem_fs_region_t; /**< QuRT memory FS region type. */ +/**@endcond */ +typedef unsigned int qurt_mem_pool_t; /**< QuRT memory pool type.*/ +typedef unsigned int qurt_size_t; /**< QuRT size type. */ +/** @cond */ +typedef unsigned long long qurt_mmu_entry_t;/**< QuRT MMU entry type. */ +#define QURT_PHYSPOOL_NAME_LEN (32) +typedef char qurt_physpool_name_t[QURT_PHYSPOOL_NAME_LEN]; + + +/* + * Mapping type + * + * QMEM_MAPPING_VIRTUAL is the default mode, in which the system + * picks up the available range of the virtual address, and maps it to + * available contiguous physical addresses. Physical-to-virtual + * is not guaranteed to be 1:1; both virtual and physical memory is + * contiguous. + * + * In QMEM_MAPPING_IDEMPOTENT mode, the user provides the physical address; + * the kernel allocates 1:1 physical-to-virtual memory. Primary use of + * of this mapping is to allocate physical-to-virtual memory 1:1. + * + * In QMEM_MAPPING_PHYS_CONTIGUOUS mode, the virtual address might + * not be the same as the physical address. But the physical address of the + * memory region is guaranteed to be contiguous starting at the provided + * address, it is required to provide a fixed physical address. The primary + * use of this mapping is to allocate physical memory from a particular + * address, where 1:1 physical-to-virtual is not required. + * + * QMEM_MAPPING_NONE mode must be used to reserve a virtual memory + * area (VMA); no physical memory is reserved or mapped to this virtual + * space; all standard qmem_region APIs apply to a VMA, however physical + * address is always INVALID_ADDR. qmem_region_create() in this mode + * returns a handle to the VMA, both virt_addr and phys_addr must + * be set to INVALID_ADDR, kernel allocates any available virtual + * memory of the specified size. Obtain the starting virtual address + * of VMA through qmem_region_attr_getvirtaddr(). + * Primary purpose of this mapping mode is to provide a mechanism for + * delayed binding in QuRT, for example reserve virtual memory and map it at + * some later time to possibly discontiguous physical blocks. Thus, a + * single VMA can be partitioned among several physical-virtual mappings + * created via qmem_region_create() with QMEM_VIRTUAL_FIXED mapping mode. + * Each VMA keeps track of associated mapped regions. + * Deletion of VMA succeeds only if all associated "virtual_fixed" + * regions are freed prior to VMA deletion. + * + * Use QMEM_MAPPING_VIRTUAL_FIXED mode to create a region + * from virtual space that has been reserved via qmem_region_create() + * with QMEM_MAPPING_NONE mapping. A valid virt_add is required, if + * phys_addr is specified, the kernel attempts to map it accordingly, + * if no phys_addr is specified, kernel maps any available physical + * memory. All standard qmem_region APIs apply to such region. Remapping + * a virtual range without prior freeing of the region is not permitted. + * When such region is deleted its corresponding VMA remains intact. + * + * QMEM_MAPPING_PHYS_DISCONTIGUOUS mode can obtain contiguous + * virtual memory but physical memory can be discontiguous. This method + * tries to club small physical memory blocks to obtain requested + * memory and is useful in case where there is no contiguous full block + * of requested size. If client does not need contiguous physical memory, + * (for example, if client does not use physical addressing), this helps + * use smaller physical memory blocks rather than using contiguous memory. + * Note: When memory is allocated through this method, physical address is + * not returned to the caller using the qurt_mem_region_attr_get() API as there might + * not be a single physical address. + * + */ +/**@endcond */ +/** QuRT memory region mapping type. */ +typedef enum { + QURT_MEM_MAPPING_VIRTUAL=0, /**< Default mode. The region virtual address range maps to an + available contiguous area of physical memory. For the most + efficient use of virtual memory, the QuRT system + chooses the base address in physical memory. This works for most memory + use cases.*/ + QURT_MEM_MAPPING_PHYS_CONTIGUOUS = 1, /**< The region virtual address space must be mapped to a + contiguous area of physical memory. This is necessary when the + memory region is accessed by external devices that bypass Hexagon + virtual memory addressing. The base address in physical + memory must be explicitly specified.*/ + QURT_MEM_MAPPING_IDEMPOTENT=2, /**< Region virtual address space maps + to the identical area of physical memory. */ + QURT_MEM_MAPPING_VIRTUAL_FIXED=3, /**< Virtual address space of the region maps either to the + specified area of physical memory or (if no area is specified) + to available physical memory. Use this mapping to create + regions from virtual space that was reserved by calling + qurt_mem_region_create() with mapping. */ + QURT_MEM_MAPPING_NONE=4, /**< Reserves a virtual memory area (VMA). Remapping a virtual range is not + permitted without first deleting the memory region. When such a region is + deleted, its corresponding virtual memory addressing remains intact. */ + QURT_MEM_MAPPING_VIRTUAL_RANDOM=7, /**< System chooses a random virtual address and + maps it to available contiguous physical addresses.*/ + QURT_MEM_MAPPING_PHYS_DISCONTIGUOUS=8, /**< While virtual memory is contiguous, allocates in discontiguous physical + memory blocks. This helps when there are smaller contiguous blocks + than the requested size. + Physical address is not provided as part of the get_attr call */ + QURT_MEM_MAPPING_INVALID=10, /**< Reserved as an invalid mapping type. */ +} qurt_mem_mapping_t; + + +/** QuRT cache mode type. */ +typedef enum { + QURT_MEM_CACHE_WRITEBACK=7, /**< Write back. */ + QURT_MEM_CACHE_NONE_SHARED=6, /**< Normal uncached memory that can be shared with other subsystems.*/ + QURT_MEM_CACHE_WRITETHROUGH=5, /**< Write through. */ + QURT_MEM_CACHE_WRITEBACK_NONL2CACHEABLE=0, /**< Write back non-L2-cacheable.*/ + QURT_MEM_CACHE_WRITETHROUGH_NONL2CACHEABLE=1, /**< Write through non-L2-cacheable. */ + QURT_MEM_CACHE_WRITEBACK_L2CACHEABLE=QURT_MEM_CACHE_WRITEBACK, /**< Write back L2 cacheable. */ + QURT_MEM_CACHE_WRITETHROUGH_L2CACHEABLE=QURT_MEM_CACHE_WRITETHROUGH, /**< Write through L2 cacheable. */ + QURT_MEM_CACHE_DEVICE = 4, /**< Volatile memory-mapped device. Access to device memory cannot be cancelled by interrupts, re-ordered, or replayed.*/ + QURT_MEM_CACHE_NONE = 4, /**< Deprecated -- use #QURT_MEM_CACHE_DEVICE instead. */ + QURT_MEM_CACHE_DEVICE_SFC = 2, /**< Enables placing limitations on the number of outstanding transactions. */ + QURT_MEM_CACHE_INVALID=10, /**< Reserved as an invalid cache type. */ +} qurt_mem_cache_mode_t; + +/** Memory access permission. */ +#define QURT_PERM_NONE 0x0U /**< No permission. */ +#define QURT_PERM_READ 0x1U /**< Read permission. */ +#define QURT_PERM_WRITE 0x2U /**< Write permission. */ +#define QURT_PERM_EXECUTE 0x4U /**< Execution permission. */ +#define QURT_PERM_NODUMP 0x8U + /**< Skip dumping the mapping. During process domain dump, must skip + some mappings on host memory to avoid a race condition + where the memory is removed from the host and DSP process + crashed before the mapping is removed. */ +#define QURT_PERM_FULL QURT_PERM_READ | QURT_PERM_WRITE | QURT_PERM_EXECUTE /**< Read, write, and execute permission. */ + +typedef unsigned char qurt_perm_t; + + +/** @cond rest_reg_dist*/ +/** QuRT cache type; specifies data cache or instruction cache. */ +typedef enum { + QURT_MEM_ICACHE, /**< Instruction cache.*/ + QURT_MEM_DCACHE /**< Data cache.*/ +} qurt_mem_cache_type_t; + +/** QuRT cache operation code type. */ +typedef enum { + QURT_MEM_CACHE_FLUSH, /**< Flush. */ + QURT_MEM_CACHE_INVALIDATE, /**< Invalidate */ + QURT_MEM_CACHE_FLUSH_INVALIDATE, /**< Flush invalidate. */ + QURT_MEM_CACHE_FLUSH_ALL, /**< Flush all. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_ALL, /**< Flush invalidate all. */ + QURT_MEM_CACHE_TABLE_FLUSH_INVALIDATE, /**< Table flush invalidate. */ + QURT_MEM_CACHE_FLUSH_INVALIDATE_L2, /**< L2 flush invalidate.*/ +} qurt_mem_cache_op_t; + +/** QuRT memory region type. */ +typedef enum { + QURT_MEM_REGION_LOCAL=0, /**< Local. */ + QURT_MEM_REGION_SHARED=1, /**< Shared.*/ + QURT_MEM_REGION_USER_ACCESS=2, /**< User access. */ + QURT_MEM_REGION_FS=4, /**< FS. */ + QURT_MEM_REGION_INVALID=10, /**< Reserved as an invalid region type. */ +} qurt_mem_region_type_t; + +/* Cache and bus attributes are combined into a value of this type for convenience, + and macros for combining and extracting fields are defined here. */ +/** @cond */ +struct qurt_pgattr { + unsigned pga_value; /**< PGA value.*/ +}; +typedef struct qurt_pgattr qurt_pgattr_t; +/** @endcond */ +/** QuRT memory region attributes type.*/ +/* QMEM_MAPPING_IDEMPOTENT and QMEM_MAPPING_PHYS_CONTIGUOUS mode can specify physaddr. + virtaddr cannot be specified for a memory region, it can only be queried by the + qmem_attr_getvirtaddr() function. + */ +typedef struct { + /** @cond */ + qurt_mem_mapping_t mapping_type; + unsigned char perms; + unsigned short owner; + qurt_pgattr_t pga; + unsigned ppn; //physical page number (physical>>12) + qurt_addr_t virtaddr; + qurt_mem_region_type_t type; + qurt_size_t size; + /** @endcond */ +} qurt_mem_region_attr_t; + + +/** QuRT user physical memory pool type. */ +typedef struct { + /** @cond */ + char name[32]; + struct ranges{ + unsigned int start; + unsigned int size; + } ranges[MAX_POOL_RANGES]; + /** @endcond */ +} qurt_mem_pool_attr_t; + +/** QuRT memory pool status type.*/ +typedef struct _qurt_mem_pool_status { + + qurt_size_t contig_size; /**< Largest contiguous free memory in bytes. */ + qurt_size_t free_size; /**< Total free memory in bytes. */ + qurt_size_t total_size; /**< Total declared memory in bytes. */ + +} qurt_mem_pool_status_t; + +typedef enum { + HEXAGON_L1_I_CACHE = 0, /**< Hexagon L1 instruction cache. */ + HEXAGON_L1_D_CACHE = 1, /**< Hexagon L1 data cache. */ + HEXAGON_L2_CACHE = 2 /**< Hexagon L2 cache. */ +} qurt_cache_type_t; + +typedef enum { + FULL_SIZE = 0, /**< Fully shared cache, without partitioning. */ + HALF_SIZE = 1, /**< 1/2 for main, 1/2 for auxiliary. */ + THREE_QUARTER_SIZE = 2, /**< 3/4 for main, 1/4 for auxiliary. */ + SEVEN_EIGHTHS_SIZE = 3 /**< 7/8 for main, 1/8 for auxiliary; for L2 cache only. */ +} qurt_cache_partition_size_t; + +typedef enum { + QURT_PROCESS_CB_GENERIC, /**< generic unconditional cb called after image loading. */ + QURT_PROCESS_NOTE_CB_PRE_MAP, /**< note cb called before segment loading. */ + QURT_PROCESS_NOTE_CB_POST_MAP /**< note cb called after segment loading. */ +} qurt_process_cb_type_t; + +typedef union { + void *ptr; + int num; +} qurt_process_callback_arg_t; + + +/**@endcond*/ + +/** @} */ /* end_addtogroup memory_management_types */ +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif /* QURT_TYPES_H */ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_user_dma.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_user_dma.h new file mode 100755 index 0000000000000..e05a6429fd703 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_user_dma.h @@ -0,0 +1,44 @@ +#ifndef QURT_USER_DMA_H +#define QURT_USER_DMA_H + +/** + @file qurt_user_dma.h + @brief Definitions, macros, and prototypes used for handling user DMA. + + EXTERNALIZED FUNCTIONS + none + + INITIALIZATION AND SEQUENCING REQUIREMENTS + none + + Copyright (c) 2021 by Qualcomm Technologies, Inc. All Rights Reserved. + Confidential and Proprietary - Qualcomm Technologies, Inc. + ======================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@ingroup qurt_user_dma_dmsyncht + Sends the DMSyncht command to the user DMA engine. + + Call this function to ensure all posted DMA memory operations are + complete. + + This stalls the current thread until the instruction + is complete and returns. + + @return + QURT_EOK - On dmsyncht completion \n + QURT_ENOTSUPPORTED - User DMA not supported + + @dependencies + None. +*/ +int qurt_user_dma_dmsyncht(void); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_vtlb.h b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_vtlb.h new file mode 100755 index 0000000000000..e064042e447ac --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/include/qurt/qurt_vtlb.h @@ -0,0 +1,76 @@ +/*============================================================================= + + qurt_vtlb.h + +GENERAL DESCRIPTION + +EXTERNAL FUNCTIONS + None. + +INITIALIZATION AND SEQUENCING REQUIREMENTS + None. + +Copyright (c) 2019, 2021, 2023 by Qualcomm Technologies, Inc. All Rights Reserved. +=============================================================================*/ +#ifndef QURT_VTLB_H +#define QURT_VTLB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +|| Names starting with "qurt_i_vtlb" are the internal low-level functions. +|| These should be considered subject to change. +*/ + +int qurt_i_vtlb_entry_create(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension); + +int qurt_i_vtlb_entry_create_with_pid(unsigned *pIndex, + unsigned tlb_lo, + unsigned tlb_hi, + unsigned extension, + unsigned target_pid); + +int qurt_i_vtlb_entry_delete(unsigned index); + +int qurt_i_vtlb_entry_read(unsigned index, unsigned *tlbinfo); + +int qurt_i_vtlb_entry_write(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension); + +int qurt_i_vtlb_entry_write_with_pid(unsigned index, unsigned tlb_lo, unsigned tlb_hi, unsigned extension, unsigned target_pid); + +int qurt_i_vtlb_entry_probe(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex); + +int qurt_i_vtlb_entry_probe_with_pid(const void *vaddr, unsigned *tlbinfo, unsigned *pIndex, unsigned target_pid); + + +int qurt_i_vtlb_statistics(unsigned *stats); // Returns stats[0] -- total number of VTLB entries + // stats[1] -- number of available VTLB entries + // stats[2] -- max size of VTLB tree since boot + +//can return index to an entry that was specialed, change it to take addresses instead of pages +int qurt_i_vtlb_set_special(int index, unsigned pageno, unsigned asid, unsigned size); + +int qurt_i_vtlb_queue_ppage(unsigned pageno, unsigned vtlb_index); + +#define QURT_VTLB_EXT_DEFAULT 0U +#define QURT_VTLB_EXT_LOCKED 1U +#define QURT_VTLB_EXT_EXCLUDE_DUMP 2U /* Temporary ability to skip certain mappings in pd dump */ +#define QURT_VTLB_EXT_FREELIST 0x800000u + +#define QURT_VTLB_ERR_OVERLAP -64 +#define QURT_VTLB_ERR_TREE_NO_SPACE -65 +#define QURT_VTLB_ERR_INVALID_SIZE -68 +#define QURT_VTLB_ERR_INVALID_EXT -69 +#define QURT_VTLB_ERR_DEL_PGT_LOCKED -70 +#define QURT_VTLB_ERR_PGT_LOCK_CNT -71 + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif + +#endif // QURT_VTLB_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libposix.a new file mode 100755 index 0000000000000..a9a8baba7faf1 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurt.a new file mode 100755 index 0000000000000..0ba0327f99d81 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurtcfs.a new file mode 100755 index 0000000000000..339de1f596ddb Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_island.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_island.a new file mode 100755 index 0000000000000..98d0a1128a8a4 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_island.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_main.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_main.a new file mode 100755 index 0000000000000..e95a77af5ed1a Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/libtimer_main.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libposix.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libposix.a new file mode 100755 index 0000000000000..6aaca8da9e012 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libposix.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurt.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurt.a new file mode 100755 index 0000000000000..ba96bbf241f10 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurt.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurtcfs.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurtcfs.a new file mode 100755 index 0000000000000..339de1f596ddb Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libqurtcfs.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libtimer.a b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libtimer.a new file mode 100755 index 0000000000000..f2f6d0b611216 Binary files /dev/null and b/prebuilts/Hexagon_SDK/6.2.0.1/rtos/qurt/computev79/lib/pic/libtimer.a differ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/tools/HEXAGON_Tools/.lock b/prebuilts/Hexagon_SDK/6.2.0.1/tools/HEXAGON_Tools/.lock new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/dsp_capabilities_utils.h b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/dsp_capabilities_utils.h new file mode 100755 index 0000000000000..2cafe29dfe9aa --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/dsp_capabilities_utils.h @@ -0,0 +1,164 @@ +/**============================================================================= +@file + dsp_capabilities_utils.h + +@brief + Wrapper functions for FastRPC Capability APIs. + +Copyright (c) 2020-2021 Qualcomm Technologies Incorporated. +All Rights Reserved. Qualcomm Proprietary and Confidential. +=============================================================================**/ +#ifndef DSP_CAPABILITIES_UTILS_H +#define DSP_CAPABILITIES_UTILS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include "AEEStdErr.h" +#include "remote.h" + +#if !defined (_WINDOWS) + #pragma weak remote_system_request +#endif + /** + * Wrapper for FastRPC Capability API: query DSP support. + * + * @param[out] domain pointer to supported domain. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + */ +int get_dsp_support(int *domain); + + /** + * Wrapper for FastRPC Capability API: query VTCM information. + * + * @param[in] domain value of domain in the queried. + * @param[out] capability capability value of the attribute queried. + * @param[in] attr value of the attribute to the queried. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + */ +int get_vtcm_info(int domain, uint32_t *capability, uint32_t attr); + + /** + * Wrapper for FastRPC Capability API: query unsigned pd support on CDSP domain. + * + * @return true if unsigned pd is supported. + * false if unsigned pd is not supported, capability query failed. + */ + +bool get_unsignedpd_support(void); + + /** + * Wrapper for FastRPC Capability API: query unsigned pd support. + * + * @param[in] domain value of domain in the queried. + * @return true if unsigned pd is supported. + * false if unsigned pd is not supported, capability query failed. + */ + +bool is_unsignedpd_supported(int domain_id); + + /** + * is_valid_domain_id API: query a domain id is valid. + * + * @param[in] domain value of domain in the queried. + * @param[in] compute_only value of domain is only compared with CDSP domains supported by the target when enabled. + * @return true if value of domain is valid. + * false if value of domain is not valid. + */ + +bool is_valid_domain_id(int domain_id, int compute_only); + + /** + * get_domain API: get domain struct from domain value. + * + * @param[in] domain value of a domain + * @return Returns domain struct of the domain if it is supported or else + * returns NULL. + * + */ + +domain* get_domain(int domain_id); + + /** + * get_domains_info API: get information for all the domains available on the device + * + * @param[in] domain_type pointer to domain type + * @param[in] num_domains pointer to number of domains + * @param[in] domains_info pointer to save discovered domains information. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + * + * It is user's responsibility to free the memory used to store the domains info whose address is present in domains_info before closing the application. + * + */ + +int get_domains_info(char *domain_type, int *num_domains, fastrpc_domain **domains_info); + + /** + * is_async_fastrpc_supported API: query a domain id has async fastrpc supported or not + * + * @param[in] domain_id value of a domain + * @return Returns true or false stating support of Async FastRPC + * + */ + +bool is_async_fastrpc_supported(int domain_id); + + /** + * is_status_notification_supported API: query the DSP for STATUS_NOTIFICATION_SUPPORT information + * + * @param[in] domain_id value of a domain + * @return Returns true or false stating status notification support information + * + */ +bool is_status_notification_supported(int domain_id); + + /** + * get_hmx_support_info API: query the DSP for HMX SUPPORT information + * + * @param[in] domain_id value of a domain + * @param[out] capability capability value of the attribute queried. + * @param[in] attr value of the attribute to the queried. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + * + */ +int get_hmx_support_info(int domain, uint32_t *capability, uint32_t attr); + + /** + * get_hex_arch_ver API: query the Hexagon processor architecture version information + * + * @param[in] domain_id value of a domain + * @param[out] capability capability value of the attribute queried. + * The last byte of the capability value represents the architecture of the DSP being queried in hexadecimal format. + * Eg. 0x8D73 represents a v73 architecture. The other byte stands for other capabilities depending on the device. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + * + */ +int get_hex_arch_ver(int domain, uint32_t *capability); + + /** + * get_hvx_support_info API: query the DSP for HVX SUPPORT information + * + * @param[in] domain_id value of a domain + * @param[out] capability capability value of the attribute queried. + * @param[in] attr value of the attribute to the queried. + * @return 0 if query is successful. + * non-zero if error, return value points to the error. + * + */ +int get_hvx_support_info(int domain, uint32_t *capability, uint32_t attr); + + +#ifdef __cplusplus +} +#endif + +#endif //DSP_CAPABILITIES_UTILS_H diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/mem_utils.h b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/mem_utils.h new file mode 100755 index 0000000000000..16f002ef060fa --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/mem_utils.h @@ -0,0 +1,54 @@ +/**============================================================================= +@file + mem_utils.h + +@brief + Abstract operating system specific timing APIs. + +Copyright (c) 2021 Qualcomm Technologies Incorporated. +All Rights Reserved. Qualcomm Proprietary and Confidential. +=============================================================================**/ + +#ifndef MEM_UTILS_H_ +#define MEM_UTILS_H_ + + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef _WINDOWS + #include +#else +#ifdef __hexagon__ +#else + #include + #include +#endif +#endif + + +#ifndef MEMALIGN + #ifdef _WINDOWS + #define MEMALIGN(alignment,size) _aligned_malloc(size,alignment) + #else + #define MEMALIGN(alignment,size) memalign(alignment,size) + #endif +#endif + + +#ifndef ALIGNED_FREE + #ifdef _WINDOWS + #define ALIGNED_FREE(ptr) _aligned_free(ptr) + #else + #define ALIGNED_FREE(ptr) free(ptr) + #endif +#endif + +#ifdef __cplusplus +} +#endif + + +#endif //MEM_UTILS_H_ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/os_defines.h b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/os_defines.h new file mode 100755 index 0000000000000..a7b5947fa908e --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/os_defines.h @@ -0,0 +1,97 @@ +/**============================================================================= +@file + os_defines.h + +@brief + Abstract operating system specific defines, includes and global variables + to make it convenient for developers to code for multiple OS platforms. + +Copyright (c) 2021 Qualcomm Technologies Incorporated. +All Rights Reserved. Qualcomm Proprietary and Confidential. +=============================================================================**/ + +#ifndef OS_DEFINES_H_ +#define OS_DEFINES_H_ + + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Offset to differentiate HLOS and Hexagon error codes. + Stores the value of AEE_EOFFSET for Hexagon. */ +#ifndef DSP_OFFSET + #define DSP_OFFSET 0x80000400 +#endif + + +/* Errno for connection reset by peer. */ +#ifndef ECONNRESET + #ifdef __hexagon__ + #define ECONNRESET 104 + #endif +#endif + + +/* Abstraction of different OS specific sleep APIs. + SLEEP accepts input in seconds. */ +#ifndef SLEEP + #ifdef __hexagon__ + #define SLEEP(x) {/* Do nothing for simulator. */} + #else + #ifdef _WINDOWS + #define SLEEP(x) Sleep(1000*x) /* Sleep accepts input in milliseconds. */ + #else + #define SLEEP(x) sleep(x) /* sleep accepts input in seconds. */ + #endif + #endif +#endif + + +/* Include windows specific header files. */ +#ifdef _WINDOWS + #include + #include + #define _CRT_SECURE_NO_WARNINGS 1 + #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 + /* Including this file for custom implementation of getopt function. */ + #include "getopt_custom.h" +#endif + + +/* Includes and defines for all HLOS except windows */ +#if !defined(__hexagon__) && !defined (_WINDOWS) + #include "unistd.h" + #include +#endif + + +/* Includes and defines for Hexagon and all HLOS except Windows. */ +#if !defined (_WINDOWS) + /* Weak reference to remote symbol for compilation. */ + #pragma weak remote_session_control + #pragma weak remote_handle_control + #pragma weak remote_handle64_control + #pragma weak fastrpc_mmap + #pragma weak fastrpc_munmap +#endif + + +/* Includes and defines for hexagon */ +#ifdef __hexagon__ +#endif + + +/* Includes and defines for Android */ +#ifdef ANDROID +#endif + + +#ifdef __cplusplus +} +#endif + + + +#endif //OS_DEFINES_H_ diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/pd_status_notification.h b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/pd_status_notification.h new file mode 100755 index 0000000000000..6579058b8e451 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/pd_status_notification.h @@ -0,0 +1,25 @@ +#include +#include +#include "AEEStdErr.h" +#include "remote.h" +#include "dsp_capabilities_utils.h" + + + /** + * request_status_notifications_enable API: Allow users to enable status notification from client PD. + * + * @param[in] domain value of a domain + * @param[in] Context of the client + * @param[in] callback function for status notification + * @return 0 if successful. + * non-zero if error, return value points to the error. + * + */ + +#ifdef __cplusplus +extern "C" { +#endif +int request_status_notifications_enable(int domain_id, void *context, int(*notif_callback_fn)(void *context, int domain, int session, remote_rpc_status_flags_t status)); +#ifdef __cplusplus +} +#endif diff --git a/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/time_utils.h b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/time_utils.h new file mode 100755 index 0000000000000..969747f26f309 --- /dev/null +++ b/prebuilts/Hexagon_SDK/6.2.0.1/utils/examples/time_utils.h @@ -0,0 +1,64 @@ +/**============================================================================= +@file + time_utils.h + +@brief + Abstract operating system specific timing APIs. + +Copyright (c) 2021 Qualcomm Technologies Incorporated. +All Rights Reserved. Qualcomm Proprietary and Confidential. +=============================================================================**/ + +#ifndef TIME_UTILS_H_ +#define TIME_UTILS_H_ + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _WINDOWS + #include +#else +#ifdef __hexagon__ + #include "hexagon_sim_timer.h" +#else + #include +#endif +#endif + +unsigned long long get_time(void); +void sleep_in_microseconds(unsigned long long); + +/* Abstraction of different OS specific usleep APIs. + USLEEP accepts input in microseconds. */ +#ifndef USLEEP + #ifdef __hexagon__ + #define USLEEP(x) {/* Do nothing for simulator. */} + #else + #ifdef _WINDOWS + #define USLEEP(x) sleep_in_microseconds(x) + #else + #include + #define USLEEP(x) usleep(x) + #endif + #endif +#endif + +/* Abstraction of different OS specific timer APIs. + GET_TIME returns the value of time*/ +#ifndef GET_TIME + #ifdef __hexagon__ + #define GET_TIME hexagon_sim_read_pcycles + #else + #define GET_TIME get_time + #endif +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif //TIME_UTILS_H_ diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuCommon.h new file mode 100755 index 0000000000000..fdbfc1136d556 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuCommon.h @@ -0,0 +1,50 @@ +//============================================================================= +// +// Copyright (c) 2020-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN CPU Common components + * + * This file defines versioning and other identification details + * and supplements QnnCommon.h for CPU backend + */ + +#ifndef QNN_CPU_COMMON_H +#define QNN_CPU_COMMON_H + +#include "QnnCommon.h" + +/// CPU Backend identifier +#define QNN_BACKEND_ID_CPU 3 + +/// CPU interface provider +#define QNN_CPU_INTERFACE_PROVIDER_NAME "CPU_QTI_AISW" + +// CPU API Version values +#define QNN_CPU_API_VERSION_MAJOR 1 +#define QNN_CPU_API_VERSION_MINOR 1 +#define QNN_CPU_API_VERSION_PATCH 0 + +// clang-format off +/// Macro to set Qnn_ApiVersion_t for CPU backend +#define QNN_CPU_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_CPU_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_CPU_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_CPU_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +#endif // QNN_CPU_COMMON_H \ No newline at end of file diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuGraph.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuGraph.h new file mode 100755 index 0000000000000..750cfd0b501f1 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuGraph.h @@ -0,0 +1,117 @@ +//============================================================================= +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN CPU component Graph API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnGraph.h for CPU backend + */ + +#ifndef QNN_CPU_GRAPH_H +#define QNN_CPU_GRAPH_H + +#include "QnnGraph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief This enum provides different CPU graph configuration + * options associated with QnnGraph + */ +typedef enum { + QNN_CPU_GRAPH_CONFIG_OPTION_OP_DEBUG_CALLBACK = 1, + QNN_CPU_GRAPH_CONFIG_OPTION_UNDEFINED = 0x7fffffff +} QnnCpuGraph_ConfigOption_t; + +/* @brief CallBack function pointer to be filled by user. + * This callback will be called after each op execution. + * Only outputTensor id and data buffer is valid, consumable. + * Memory is owned by BE which is valid throughout the callback. + * Client should not update any parameter and argument of opConfig. + * NULL tensor/buffer indicate invalid data buffer. + */ +typedef Qnn_ErrorHandle_t (*QnnCpuGraph_OpDebugCallback_t)(Qnn_OpConfig_t* opConfig, + void* callBackParam); + +/* @brief Structure to be filled by user. + * This structure will have callback function and callback reference data. + * Memory is owned by BE which is valid throughout the callback. + * Client should not update any parameter and argument of opConfig. + * NULL callback function indicate no debug option. + */ +typedef struct { + void* callBackParam; + QnnCpuGraph_OpDebugCallback_t cpuGraphOpDebugCallback; +} QnnCpuGraph_OpDebug_t; + +// clang-format off +/// QnnCpuGraph_OpDebug_t initializer macro +#define QNN_CPU_GRAPH_OP_DEBUG_INIT \ + { \ + NULL, /*callBackParam*/ \ + NULL /*cpuGraphOpDebugCallback*/ \ + } +// clang-format on + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +/** + * @brief Structure describing the set of configurations supported by graph. + * Objects of this type are to be referenced through QnnGraph_CustomConfig_t. + * + * The struct has two fields - option and a union of corresponding config values + * Based on the option corresponding item in the union can be used to specify + * config. + * Below is the map between QnnCpuGraph_ConfigOption_t and config value + * + * \verbatim embed:rst:leading-asterisk + * +----+------------------------------------------+------------------------------------+ + * | # | Config Option | Configuration Struct/value | + * +====+==========================================+====================================+ + * | 1 | QNN_CPU_GRAPH_CONFIG_DEBUG_CALLBACK | QnnCpuGraph_OpDebug_t | + * +----+------------------------------------------+------------------------------------+ + * \endverbatim + */ +typedef struct { + QnnCpuGraph_ConfigOption_t option; + union UNNAMED { + QnnCpuGraph_OpDebug_t cpuGraphOpDebug; + }; +} QnnCpuGraph_CustomConfig_t; + +/// QnnCpuGraph_CustomConfig_t initializer macro +#define QNN_CPU_GRAPH_CUSTOM_CONFIG_INIT \ + { \ + QNN_CPU_GRAPH_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + QNN_CPU_GRAPH_OP_DEBUG_INIT /*cpuGraphOpDebugCallback*/ \ + } \ + } + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuOpPackage.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuOpPackage.h new file mode 100755 index 0000000000000..97bdab8dfd3f9 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/CPU/QnnCpuOpPackage.h @@ -0,0 +1,224 @@ +//============================================================================== +// +// Copyright (c) 2020-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** @file + * @brief CPU Operation Package component API + * + * Provides interface to interact with OpPackage libraries registered + * with the CPU backend. + */ + +#ifndef QNN_CPU_OP_PACKAGE_H +#define QNN_CPU_OP_PACKAGE_H + +#include "CPU/QnnCpuCommon.h" +#include "QnnGraph.h" +#include "QnnOpPackage.h" +#include "QnnTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define QNN_CPUOPPACKAGE_TENSOR_DATA_FORMAT_FLAT_BUFFER 0 + +/** + * @brief A value representing a tensor data format. + */ +typedef uint32_t QnnCpuOpPackage_TensorDataFormat_t; + +/** + * @brief A value representing a profile data in ms. + */ +typedef double QnnCpuOpPackage_ProfileData_t; + +/** + * @brief An enum to specify a param type. + */ +typedef enum { + QNN_CPU_PARAMTYPE_SCALAR = 0, + QNN_CPU_PARAMTYPE_TENSOR = 1, + QNN_CPU_PARAMTYPE_STRING = 2, + // Unused, present to ensure 32 bits. + QNN_CPU_PARAMTYPE_UNDEFINED = 0xFFFFFFFF +} QnnCpuOpPackage_ParamType_t; + +/** + * @brief An enum to specify tensor data type. + */ +typedef enum { + QNN_CPU_DATATYPE_BOOL_8 = 0x0508, + QNN_CPU_DATATYPE_INT_8 = 0x0008, + QNN_CPU_DATATYPE_INT_32 = 0x0032, + QNN_CPU_DATATYPE_UINT_8 = 0x0108, + QNN_CPU_DATATYPE_UINT_32 = 0x0132, + QNN_CPU_DATATYPE_FLOAT_32 = 0x0232, + // Unused, present to ensure 32 bits. + QNN_CPU_DATATYPE_UNDEFINED = 0x7FFFFFFF +} QnnCpuOpPackage_DataType_t; + +/** + * @brief An enum to specify logging level. + */ +typedef enum { + QNN_CPU_MSG_ERROR = 1, + QNN_CPU_MSG_DEBUG = 2, + QNN_CPU_MSG_LOW = 3, + QNN_CPU_MSG_MED = 4, + QNN_CPU_MSG_HIGH = 5, + // Unused, present to ensure 32 bits + QNN_CPU_MSG_UNDEFINED = 0x7FFFFFFF +} QnnCpuOpPackage_MsgType_t; + +/** + * @brief An enum to specify the profiling type. + */ +typedef enum { + QNN_CPU_PROFILE_BASIC = 1, + QNN_CPU_PROFILE_DETAILED = 2, + // Unused, present to ensure 32 bits + QNN_CPU_PROFILE_UNDEFINED = 0x7FFFFFFF +} QnnCpuOpPackage_ProfileType_t; + +/** + * @brief A struct which defines the Global infrastructure. + */ +typedef struct _QnnOpPackage_GlobalInfrastructure_t { + // Message + void (*reportMessage)(QnnCpuOpPackage_MsgType_t msgType, const char* msg, ...); + + // Profile + void (*profile)(QnnCpuOpPackage_ProfileType_t profileType, + QnnCpuOpPackage_ProfileData_t timeInMsec); +} QnnCpuOpPackage_GlobalInfra_t; + +// clang-format off +/// QnnCpuOpPackage_GlobalInfra_t initializer macro +#define QNN_CPU_OP_PACKAGE_GLOBAL_INFRA_INIT \ + { \ + NULL, /*reportMessage*/ \ + NULL /*profile*/ \ + } +// clang-format on + +typedef Qnn_ErrorHandle_t (*QnnCpuOpPackage_OpImplFn_t)(void* opPkgNodeData); + +/** + * @brief A struct which defines the OpImpl definition. + */ +typedef struct _QnnOpPackage_OpImpl_t { + QnnCpuOpPackage_OpImplFn_t opImplFn; + void* userData; +} QnnCpuOpPackage_OpImpl_t; + +// clang-format off +/// QnnCpuOpPackage_OpImpl_t initializer macro +#define QNN_CPU_OP_PACKAGE_OPIMPL_INIT \ + { \ + NULL, /*kernelFn*/ \ + NULL /*userData*/ \ + } +// clang-format on + +/** + * @brief A struct which describes the properties of a tensor. + * + */ +typedef struct { + QnnCpuOpPackage_TensorDataFormat_t dataFormat; + QnnCpuOpPackage_DataType_t dataType; + uint32_t rank; + uint32_t* maxDimensions; + uint32_t* currentDimensions; + void* data; + Qnn_QuantizeParams_t quantizeParams; +} QnnCpuOpPackage_Tensor_t; + +// clang-format off +/// QnnCpuOpPackage_Tensor_t initializer macro +#define QNN_CPU_OP_PACKAGE_TENSOR_INIT \ + { \ + QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, /*dataFormat*/ \ + QNN_CPU_DATATYPE_UNDEFINED, /*dataType*/ \ + 0, /*rank*/ \ + NULL, /*maxDimensions*/ \ + NULL, /*currentDimensions*/ \ + NULL, /*data*/ \ + QNN_QUANTIZE_PARAMS_INIT /*quantizeParams*/ \ + } +// clang-format on + +/** + * @brief A struct which describes the parameters of a node. + * + */ +typedef struct { + QnnCpuOpPackage_ParamType_t type; + const char* name; + union { + double scalarParam; + const char* string; + QnnCpuOpPackage_Tensor_t* tensorParam; + }; +} QnnCpuOpPackage_Param_t; + +// clang-format off +/// QnnCpuOpPackage_Param_t initializer macro +#define QNN_CPU_OP_PACKAGE_PARAM_INIT \ + { \ + QNN_CPU_PARAMTYPE_UNDEFINED, /*type*/ \ + NULL, /*name*/ \ + { \ + 0 /*scalarParam*/ \ + } \ + } +// clang-format on + +/** + * @brief A struct which describes the node. + * + */ +typedef struct _QnnOpPackage_Node_t { + const char* name; + const char* packageName; + const char* typeName; + uint32_t numOfParams; + QnnCpuOpPackage_Param_t** params; + uint32_t numOfInputs; + QnnCpuOpPackage_Tensor_t** inputs; + uint32_t numOfOutputs; + QnnCpuOpPackage_Tensor_t** outputs; +} QnnCpuOpPackage_Node_t; + +// clang-format off +/// QnnCpuOpPackage_Node_t initializer macro +#define QNN_CPU_OP_PACKAGE_NODE_INIT \ + { \ + NULL, /*name*/ \ + NULL, /*packageName*/ \ + NULL, /*typeName*/ \ + 0, /*numOfParams*/ \ + NULL, /*params*/ \ + 0, /*numOfInputs*/ \ + NULL, /*inputs*/ \ + 0, /*numOfOutputs*/ \ + NULL /*outputs*/ \ + } +// clang-format on + +/** + * @brief Graph infrastructure. + * + */ +typedef _QnnOpPackage_GraphInfrastructure_t QnnCpuOpPackage_GraphInfrastructure_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // QNN_CPU_OP_PACKAGE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspBackend.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspBackend.h new file mode 100755 index 0000000000000..e2b6c69dffbdf --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspBackend.h @@ -0,0 +1,108 @@ +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN DSP component Backend API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnBackend.h for DSP backend + */ + +#ifndef QNN_DSP_BACKEND_H +#define QNN_DSP_BACKEND_H + +#include "QnnBackend.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +// clang-format off + +/* @brief Enum describing the set of custom configs supported by DSP backend. +*/ +typedef enum { + /// The accelerator will always attempt to fold relu activation + /// into the immediate preceding convolution operation. This optimization + /// is correct when quantization ranges for convolution are equal or + /// subset of the Relu operation. For graphs, where this cannot be + /// guaranteed, the client should set this option to true + QNN_DSP_BACKEND_CONFIG_OPTION_FOLD_RELU_ACTIVATION_INTO_CONV_OFF = 0, + /// The accelerator will always attempt to all Convolution + /// operation using HMX instructions. Convolution that have + /// short depth and/or weights that are not symmetric could + /// exhibit inaccurate results. In such cases, clients must + /// set this option to true to guarantee correctness of the operation + QNN_DSP_BACKEND_CONFIG_OPTION_SHORT_DEPTH_CONV_ON_HMX_OFF = 1, + /// Every APP side user process that uses a DSP via FastRPC + /// has a corresponding dynamic user process domain on the DSP side. + /// QNN by default opens RPC session as unsigned PD, + /// in case this option is set to true, + /// RPC session will be opened as signed PD (requires signed .so). + QNN_DSP_BACKEND_CONFIG_OPTION_USE_SIGNED_PROCESS_DOMAIN = 2, + /// set QnnDspBackend_DspArch_t for offline prepare mode + QNN_DSP_BACKEND_CONFIG_OPTION_ARCH = 3, + /// UNKNOWN enum option that must not be used + QNN_DSP_BACKEND_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnDspBackend_ConfigOption_t; + +typedef enum { + QNN_DSP_BACKEND_DSP_ARCH_NONE = 0, + QNN_DSP_BACKEND_DSP_ARCH_V65 = 65, + QNN_DSP_BACKEND_DSP_ARCH_V66 = 66, + QNN_DSP_BACKEND_DSP_ARCH_V68 = 68, + QNN_DSP_BACKEND_DSP_ARCH_V69 = 69, + QNN_DSP_BACKEND_DSP_ARCH_V73 = 73, + QNN_DSP_BACKEND_DSP_ARCH_UNKNOWN = 0x7fffffff +} QnnDspBackend_DspArch_t; + +/** + * @brief Structure describing the set of configurations supported by the backend. + * Objects of this type are to be referenced through QnnBackend_CustomConfig_t. + */ +typedef struct QnnDspBackend_CustomConfig { + QnnDspBackend_ConfigOption_t option; + union UNNAMED { + bool foldReluActivationIntoConvOff; + bool shortDepthConvOnHmxOff; + bool useSignedProcessDomain; + QnnDspBackend_DspArch_t arch; + }; +} QnnDspBackend_CustomConfig_t ; + +/// QnnDspBackend_CustomConfig_t initializer macro +#define QNN_DSP_BACKEND_CUSTOM_CONFIG_INIT \ + { \ + QNN_DSP_BACKEND_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + false /*foldReluActivationIntoConvOff*/ \ + } \ + } + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspCommon.h new file mode 100755 index 0000000000000..8b5ad49d04d6e --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspCommon.h @@ -0,0 +1,61 @@ +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN DSP Common components + * + * This file defines versioning and other identification details + * and supplements QnnCommon.h for DSP backend + */ + +#ifndef QNN_DSP_COMMON_H +#define QNN_DSP_COMMON_H + +#include "QnnCommon.h" + +/// DSP Backend identifier +#define QNN_BACKEND_ID_DSP 5 + +/// DSP interface provider +#define QNN_DSP_INTERFACE_PROVIDER_NAME "DSP_QTI_AISW" + +// DSP API Version values +#define QNN_DSP_API_VERSION_MAJOR 5 +#define QNN_DSP_API_VERSION_MINOR 0 +#define QNN_DSP_API_VERSION_PATCH 1 + +// clang-format off + +/// Macro to set Qnn_ApiVersion_t for DSP backend +#define QNN_DSP_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_DSP_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_DSP_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_DSP_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +// DSP Binary Version values +#define QNN_DSP_BINARY_VERSION_MAJOR 1 +#define QNN_DSP_BINARY_VERSION_MINOR 0 +#define QNN_DSP_BINARY_VERSION_PATCH 0 + +// DSP Context blob Version values +#define QNN_DSP_CONTEXT_BLOB_VERSION_MAJOR 1 +#define QNN_DSP_CONTEXT_BLOB_VERSION_MINOR 0 +#define QNN_DSP_CONTEXT_BLOB_VERSION_PATCH 0 + +#endif // QNN_DSP_COMMON_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspDevice.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspDevice.h new file mode 100755 index 0000000000000..eecf62f5cbc02 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspDevice.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN DSP component Device API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnDevice.h for DSP backend + */ +#ifndef QNN_DSP_DEVICE_H +#define QNN_DSP_DEVICE_H + +#include "QnnDevice.h" +#include "QnnDspPerfInfrastructure.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _QnnDevice_Infrastructure_t { + QnnDspPerfInfrastructure_CreatePowerConfigIdFn_t createPowerConfigId; + QnnDspPerfInfrastructure_DestroyPowerConfigIdFn_t destroyPowerConfigId; + QnnDspPerfInfrastructure_SetPowerConfigFn_t setPowerConfig; + QnnDspPerfInfrastructure_SetMemoryConfigFn_t setMemoryConfig; + QnnDspPerfInfrastructure_SetThreadConfigFn_t setThreadConfig; +} QnnDspDevice_Infrastructure_t; + +#define QNN_DSP_DEVICE_INFRASTRUCTURE_INIT \ + { \ + NULL, /*createPowerConfigId*/ \ + NULL, /*destroyPowerConfigId*/ \ + NULL, /*setPowerConfig*/ \ + NULL, /*setMemoryConfig*/ \ + NULL /*setThreadConfig*/ \ + } + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspGraph.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspGraph.h new file mode 100755 index 0000000000000..dd1c5220c8721 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspGraph.h @@ -0,0 +1,171 @@ +//============================================================================= +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + * @brief QNN DSP component Graph API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnGraph.h for DSP backend + */ + +#ifndef QNN_DSP_GRAPH_H +#define QNN_DSP_GRAPH_H + +#include "QnnGraph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief This enum provides different DSP graph optimization + * options that can be used to finalize the graph + * for optimum performance. + */ +typedef enum { + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_SCHEDULE_THRESHOLD = 1, + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_RETRIES = 2, + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_OPTIMIZATION_FLAG = 3, + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC = 4, + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_UNKNOWN = 0x7fffffff +} QnnDspGraph_OptimizationType_t; + +// clang-format off + +/** + * @brief Struct describing the set of optimization types + * and the values associated with each optimization type. + * + * Below is the Map between QnnDspGraph_OptimizationType_t and allowable values: + * + * \verbatim embed:rst:leading-asterisk + * +----+------------------------------------------------------------+-----------------------------------------------------------+ + * | # | OptimizationType option | Allowable values | + * +====+============================================================+===========================================================+ + * | 1 | QNN_DSP_GRAPH_OPTIMIZATION_TYPE_SCHEDULE_THRESHOLD | Reserved | + * +----+------------------------------------------------------------+-----------------------------------------------------------+ + * | 2 | QNN_DSP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_RETRIES | Reserved | + * +----+------------------------------------------------------------+-----------------------------------------------------------+ + * | 3 | QNN_DSP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_OPTIMIZATION_FLAG | Defines the optimization strategy used by the HTP backend | + * | | | | + * | | | 1 = Faster preparation time, less optimal graph | + * | | | | + * | | | 2 = More optimal graph but may take longer to prepare | + * +----+------------------------------------------------------------+-----------------------------------------------------------+ + * | 4 | QNN_DSP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC | Reserved | + * +----+------------------------------------------------------------+-----------------------------------------------------------+ + * \endverbatim + */ +typedef struct { + QnnDspGraph_OptimizationType_t type; + float floatValue; +} QnnDspGraph_OptimizationOption_t; + +/// QnnDspGraph_OptimizationOption_t initializer macro +#define QNN_DSP_GRAPH_OPTIMIZATION_OPTION_INIT \ + { \ + QNN_DSP_GRAPH_OPTIMIZATION_TYPE_UNKNOWN, /*type*/ \ + 0.0f /*floatValue*/ \ + } +// clang-format on + +/** + * @brief This enum provides different DSP graph configuration + * options associated with QnnGraph + */ +typedef enum { + QNN_DSP_GRAPH_CONFIG_OPTION_OPTIMIZATION = 1, + QNN_DSP_GRAPH_CONFIG_OPTION_ENCODING = 2, + QNN_DSP_GRAPH_CONFIG_OPTION_PRIORITY = 3, + QNN_DSP_GRAPH_CONFIG_OPTION_PRECISION = 4, + QNN_DSP_GRAPH_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnDspGraph_ConfigOption_t; + +typedef enum { + QNN_DSP_GRAPH_ENCODING_DYNAMIC = 1, + /** @deprecated + */ + QNN_DSP_GRAPH_ENCOING_DYNAMIC = QNN_DSP_GRAPH_ENCODING_DYNAMIC, + QNN_DSP_GRAPH_ENCODING_STATIC = 2, + /** @deprecated + */ + QNN_DSP_GRAPH_ENCOING_STATIC = QNN_DSP_GRAPH_ENCODING_STATIC, + QNN_DSP_GRAPH_ENCODING_UNKNOWN = 0x7fffffff, + /** @deprecated + */ + QNN_DSP_GRAPH_ENCOING_UNKNOW = QNN_DSP_GRAPH_ENCODING_UNKNOWN +} QnnDspGraph_Encoding_t; + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +// clang-format off + +/** + * @brief Structure describing the set of configurations supported by graph. + * Objects of this type are to be referenced through QnnGraph_CustomConfig_t. + * + * The struct has two fields - option and a union of corresponding config values + * Based on the option corresponding item in the union can be used to specify + * config. + * + * Below is the Map between QnnDspGraph_ConfigOption_t and config value + * + * \verbatim embed:rst:leading-asterisk + * +----+------------------------------------------+------------------------------------+ + * | # | Config Option | Configuration Struct/value | + * +====+==========================================+====================================+ + * | 1 | QNN_DSP_GRAPH_CONFIG_OPTION_OPTIMIZATION | QnnDspGraph_OptimizationOption_t | + * +----+------------------------------------------+------------------------------------+ + * | 2 | QNN_DSP_GRAPH_CONFIG_OPTION_ENCODING | QnnDspGraph_Encoding_t | + * +----+------------------------------------------+------------------------------------+ + * | 3 | QNN_DSP_GRAPH_CONFIG_OPTION_PRECISION | Qnn_Precision_t | + * +----+------------------------------------------+------------------------------------+ + * | 4 | QNN_DSP_GRAPH_CONFIG_OPTION_PRIORITY | Qnn_Priority_t | + * +----+------------------------------------------+------------------------------------+ + * \endverbatim + */ +typedef struct { + QnnDspGraph_ConfigOption_t option; + union { + QnnDspGraph_OptimizationOption_t optimizationOption; + QnnDspGraph_Encoding_t encoding; + Qnn_Priority_t priority; + Qnn_Precision_t precision; + }; +} QnnDspGraph_CustomConfig_t; + +// clang-format on +/// QnnDspGraph_CustomConfig_t initializer macro +#define QNN_DSP_GRAPH_CUSTOM_CONFIG_INIT \ + { \ + QNN_DSP_GRAPH_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + QNN_DSP_GRAPH_OPTIMIZATION_OPTION_INIT /*optimizationOption*/ \ + } \ + } + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspOpPackage.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspOpPackage.h new file mode 100755 index 0000000000000..c8760ecb6b798 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspOpPackage.h @@ -0,0 +1,42 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef QNN_DSP_OP_PACKAGE_HPP +#define QNN_DSP_OP_PACKAGE_HPP + +#include "QnnOpPackage.h" +#include "QnnTypes.h" +#include "Udo/UdoImplDsp.h" + +/** + * @brief A struct which defines the Global infrastructure. + */ +typedef struct _QnnOpPackage_GlobalInfrastructure_t { + /// include the UdoMalloc, UdoFree and so on + Udo_DspGlobalInfrastructure_t* dspGlobalInfra; +} QnnDspOpPackage_GlobalInfrastructure_t; + +/** + * @brief A struct which defines the operation info. + */ +typedef struct _QnnOpPackage_OperationInfo_t { + char* opType; + uint32_t numOfStaticParams; + uint32_t numOfInputs; + uint32_t numOfOutputs; + + Udo_CreateOpFactoryFunction_t createOpFactory; + Udo_CreateOperationFunction_t createOperation; + Udo_ExecuteOpFunction_t executeOp; + Udo_ReleaseOpFunction_t releaseOp; + Udo_ReleaseOpFactoryFunction_t releaseOpFactory; + Udo_ValidateOperationFunction_t validateOp; + Udo_QueryOperationFunction_t queryOp; +} QnnDspOpPackage_OperationInfo_t; + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspPerfInfrastructure.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspPerfInfrastructure.h new file mode 100755 index 0000000000000..c9b1aa3020b9e --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspPerfInfrastructure.h @@ -0,0 +1,448 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** @file + * @brief QNN DSP component Performance Infrastructure API + * + * Provides interface to the client to control performance and system + * settings of the QNN DSP Accelerator + */ + +#ifndef QNN_DSP_PERF_INFRASTRUCTURE_H +#define QNN_DSP_PERF_INFRASTRUCTURE_H + +#include "QnnCommon.h" +#include "QnnTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// max rpc polling time allowed - 9999 us +#define QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIG_MAX_RPC_POLLING_TIME 9999 + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief QNN DSP PerfInfrastructure API result / error codes. + * + */ +typedef enum { + QNN_DSP_PERF_INFRASTRUCTURE_MIN_ERROR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE, + //////////////////////////////////////////////////////////////////////// + + QNN_DSP_PERF_INFRASTRUCTURE_NO_ERROR = QNN_SUCCESS, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_HANDLE_PTR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 0, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 1, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED_CONFIG = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 2, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_TRANSPORT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 3, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 4, + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_FAILED = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 5, + + //////////////////////////////////////////////////////////////////////// + QNN_DSP_PERF_INFRASTRUCTURE_MAX_ERROR = QNN_MAX_ERROR_PERF_INFRASTRUCTURE, + /// UNDEFINED value that must not be used by client + QNN_DSP_PERF_INFRASTRUCTURE_ERROR_UNDEFINED = 0x7fffffff +} QnnDspPerfInfrastructure_Error_t; + +/** + * @brief Used to allow client start (non-zero value) or stop participating + * (zero value) in DCVS + * + */ +typedef uint32_t QnnDspPerfInfrastructure_DcvsEnable_t; + +/** + * @brief Allows client to set up the sleep latency in microseconds + * + */ +typedef uint32_t QnnDspPerfInfrastructure_SleepLatency_t; + +/** + * @brief Allows client to disable sleep or low power modes. + * Pass a non-zero value to disable sleep in DSP + * + */ +typedef uint32_t QnnDspPerfInfrastructure_SleepDisable_t; + +/** + * @brief sets the minimum size by which user heap should grow + * when heap is exhausted. This API is expected to be + * called only once per backend and has a process wide impact + * + * Grow size provided in bytes and defaults to 16MB + */ +typedef uint32_t QnnDspPerfInfrastructure_MemGrowSize_t; + +/** + * @brief sets the vtcm size to use for graphs that + * are prepared offline. This API should be set up + * before users can finalize a graph offline. It allows + * the QNN DSP backend to configure the serialized + * context for the available vtcm on target + * + * VTCM size provided in MB and does not have a default + */ +typedef uint32_t QnnDspPerfInfrastructure_VtcmSize_t; + +/** + * @brief sets the number of HVX threads for QNN DSP + */ +typedef uint32_t QnnDspPerfInfrastructure_HvxThreadNumber_t; + +/** + * @brief These are the different voltage corners that can + * be requested by the client to influence the voting scheme + * for DCVS + * + */ +typedef enum { + /// Maps to HAP_DCVS_VCORNER_DISABLE. + /// Disable setting up voltage corner + DCVS_VOLTAGE_CORNER_DISABLE = 0x10, + /// Maps to HAP_DCVS_VCORNER_SVS2. + /// Set voltage corner to minimum value supported on platform + DCVS_VOLTAGE_VCORNER_MIN_VOLTAGE_CORNER = 0x20, + /// Maps to HAP_DCVS_VCORNER_SVS2. + /// Set voltage corner to SVS2 value for the platform + DCVS_VOLTAGE_VCORNER_SVS2 = 0x30, + /// Maps to HAP_DCVS_VCORNER_SVS. + /// Set voltage corner to SVS value for the platform + DCVS_VOLTAGE_VCORNER_SVS = 0x40, + /// Maps to HAP_DCVS_VCORNER_SVS_PLUS. + /// Set voltage corner to SVS_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_SVS_PLUS = 0x50, + /// Maps to HAP_DCVS_VCORNER_NOM. + /// Set voltage corner to NOMINAL value for the platform + DCVS_VOLTAGE_VCORNER_NOM = 0x60, + /// Maps to HAP_DCVS_VCORNER_NOM_PLUS. + /// Set voltage corner to NOMINAL_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_NOM_PLUS = 0x70, + /// Maps to HAP_DCVS_VCORNER_TURBO. + /// Set voltage corner to TURBO value for the platform + DCVS_VOLTAGE_VCORNER_TURBO = 0x80, + /// Maps to HAP_DCVS_VCORNER_TURBO_PLUS. + /// Set voltage corner to TURBO_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_TURBO_PLUS = 0x90, + /// Maps to HAP_DCVS_VCORNER_MAX. + /// Set voltage corner to maximum value supported on the platform + DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER = 0xA0, + /// UNKNOWN value that must not be used by client + DCVS_VOLTAGE_VCORNER_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_VoltageCorner_t; + +/** + * @brief This enum defines all the possible power mode + * that a client can set to influence DCVS mode + */ +typedef enum { + /// Maps to HAP_DCVS_V2_ADJUST_UP_DOWN. + /// Allows for DCVS to adjust up and down + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_ADJUST_UP_DOWN = 0x1, + /// Maps to HAP_DCVS_V2_ADJUST_ONLY_UP. + /// Allows for DCVS to adjust up only + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_ADJUST_ONLY_UP = 0x2, + /// Maps to HAP_DCVS_V2_POWER_SAVER_MODE. + /// Higher thresholds for power efficiency + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER_MODE = 0x4, + /// Maps to HAP_DCVS_V2_POWER_SAVER_AGGRESSIVE_MODE. + /// Higher thresholds for power efficiency with faster ramp down + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER_AGGRESSIVE_MODE = 0x8, + /// Maps to HAP_DCVS_V2_PERFORMANCE_MODE. + /// Lower thresholds for maximum performance + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_PERFORMANCE_MODE = 0x10, + /// Maps to HAP_DCVS_V2_DUTY_CYCLE_MODE. + /// The below value applies only for HVX clients: + /// - For streaming class clients: + /// - detects periodicity based on HVX usage + /// - lowers clocks in the no HVX activity region of each period. + /// - For compute class clients: + /// - Lowers clocks on no HVX activity detects and brings clocks up on detecting HVX activity + /// again. + /// - Latency involved in bringing up the clock will be at max 1 to 2 ms. + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_DUTY_CYCLE_MODE = 0x20, + /// UNKNOWN value that must not be used by client + QNN_DSP_PERF_INFRASTRUCTURE_POWERMODE_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_PowerMode_t; + +/** + * @brief This enum defines all the possible performance + * options in Dsp Performance Infrastructure that + * relate to setting up of power levels + */ +typedef enum { + /// config enum implies the usage of dcvsEnableConfig struct. For dcvs v2, if not provided, will + /// set to false + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_ENABLE = 1, + /// config enum implies the usage of sleepLatencyConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_SLEEP_LATENCY = 2, + /// config enum implies the usage of sleepDisableConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_SLEEP_DISABLE = 3, + /// config enum implies the usage of dcvsPowerModeConfig struct. If not provided, power save mode + /// will be used + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_POWER_MODE = 4, + /// config enum implies the usage of dcvsVoltageCornerConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_VOLTAGE_CORNER = 5, + /// config enum implies the usage of busVoltageCornerConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_BUS_VOLTAGE_CORNER = 6, + /// config enum implies the usage of coreVoltageCornerConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_CORE_VOLTAGE_CORNER = 7, + /// config enum implies the usage of rpcControlLatencyConfig struct + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_CONTROL_LATENCY = 9, + /// config enum implies the usage of rpcPollingTimeConfig struct + /// this config is only supported on V69 and later + /// if enabled, this config is applied to entire process + /// max allowed is QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIG_MAX_RPC_POLLING_TIME us + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_POLLING_TIME = 10, + /// config HMX timeout interval in us. The HMX is turned off after the set interval + /// time if no interaction with it after an inference is finished. + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_HMX_TIMEOUT_INTERVAL_US = 11, + /// UNKNOWN config option which must not be used + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_PowerConfigOption_t; + +/** + * @brief Allows client to set up the RPC control latency in microseconds + * + */ +typedef uint32_t QnnDspPerfInfrastructure_RpcControlLatency_t; + +/** + * @brief Allows client to set up the RPC polling time in microseconds + */ +typedef uint32_t QnnDspPerfInfrastructure_RpcPollingTime_t; + +/** + * @brief Allows client to set up the HMX timeout interval in microseconds + */ +typedef uint32_t QnnDspPerfInfrastructure_HmxTimeoutIntervalUs_t; + +/** + * @brief This struct provides performance infrastructure configuration + * associated with setting up of power levels + */ +typedef struct { + QnnDspPerfInfrastructure_PowerConfigOption_t config; + union { + QnnDspPerfInfrastructure_DcvsEnable_t dcvsEnableConfig; + QnnDspPerfInfrastructure_SleepLatency_t sleepLatencyConfig; + QnnDspPerfInfrastructure_SleepDisable_t sleepDisableConfig; + QnnDspPerfInfrastructure_PowerMode_t dcvsPowerModeConfig; + QnnDspPerfInfrastructure_VoltageCorner_t dcvsVoltageCornerMinConfig; + QnnDspPerfInfrastructure_VoltageCorner_t dcvsVoltageCornerTargetConfig; + QnnDspPerfInfrastructure_VoltageCorner_t dcvsVoltageCornerMaxConfig; + QnnDspPerfInfrastructure_VoltageCorner_t busVoltageCornerMinConfig; + QnnDspPerfInfrastructure_VoltageCorner_t busVoltageCornerTargetConfig; + QnnDspPerfInfrastructure_VoltageCorner_t busVoltageCornerMaxConfig; + QnnDspPerfInfrastructure_VoltageCorner_t coreVoltageCornerMinConfig; + QnnDspPerfInfrastructure_VoltageCorner_t coreVoltageCornerTargetConfig; + QnnDspPerfInfrastructure_VoltageCorner_t coreVoltageCornerMaxConfig; + QnnDspPerfInfrastructure_RpcControlLatency_t rpcControlLatencyConfig; + QnnDspPerfInfrastructure_RpcPollingTime_t rpcPollingTimeConfig; + QnnDspPerfInfrastructure_HmxTimeoutIntervalUs_t hmxTimeoutIntervalUsConfig; + }; +} QnnDspPerfInfrastructure_PowerConfig_t; + +/// QnnDspPerfInfrastructure_PowerConfig_t initializer macro +#define QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIG_INIT \ + { \ + QNN_DSP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + 0 /*dcvsEnableConfig*/ \ + } \ + } + +/** + * @brief This enum defines all the possible performance + * options in Dsp Performance Infrastructure that + * relate to system memory settings + */ +typedef enum { + /// sets memory grow size + QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_GROW_SIZE = 1, + /// set the size of VTCM configuration (in MB) to use + /// This setting is applicable only for off target usage. + /// For on-target usage, refer QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_VTCM_USAGE_FACTOR + QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_VTCM_SIZE = 2, + /// set the vtcm usage factor on-target + QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_VTCM_USAGE_FACTOR = 3, + /// UNKNOWN config option that must not be used + QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_MemoryConfigOption_t; + +/** + * @brief This enum defines all the possible performance + * options in Dsp Performance Infrastructure that + * relate to thread settings + */ +typedef enum { + /// sets number of HVX threads + QNN_DSP_PERF_INFRASTRUCTURE_THREAD_CONFIGOPTION_NUMBER_OF_HVX_THREADS = 1, + /// UNKNOWN config option that must not be used + QNN_DSP_PERF_INFRASTRUCTURE_THREAD_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_ThreadConfigOption_t; + +/** + * @brief This enum defines all the possible vtcm + * usage configuration. These settings apply only + * for on-target libraries + * + */ +typedef enum { + /// use all the vtcm available on target + QNN_DSP_PERF_INFRASTRUCTURE_VTCM_USE_FULL = 1, + /// use bare minimal vtcm available on target. This is + /// not supported in the current release. + QNN_DSP_PERF_INFRASTRUCTURE_VTCM_USE_MIN = 2, + QNN_DSP_PERF_INFRASTRUCTURE_VTCM_USE_UNKNOWN = 0x7fffffff +} QnnDspPerfInfrastructure_VtcmUsageFactor_t; + +/** + * @brief Provides performance infrastructure configuration + * options that are memory specific + */ +typedef struct { + QnnDspPerfInfrastructure_MemoryConfigOption_t config; + union { + QnnDspPerfInfrastructure_MemGrowSize_t memGrowSizeConfig; + QnnDspPerfInfrastructure_VtcmSize_t vtcmSizeInMB; + QnnDspPerfInfrastructure_VtcmUsageFactor_t vtcmUsageConfig; + }; +} QnnDspPerfInfrastructure_MemoryConfig_t; + +/// QnnDspPerfInfrastructure_MemoryConfig_t initializer macro +#define QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIG_INIT \ + { \ + QNN_DSP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + 0 /*memGrowSizeConfig*/ \ + } \ + } + +/** + * @brief Provides performance infrastructure configuration + * options that are thread specific + */ +typedef struct { + QnnDspPerfInfrastructure_ThreadConfigOption_t config; + union { + QnnDspPerfInfrastructure_HvxThreadNumber_t numHvxThreads; + }; +} QnnDspPerfInfrastructure_ThreadConfig_t; + +/// QnnDspPerfInfrastructure_ThreadConfig_t initializer macro +#define QNN_DSP_PERF_INFRASTRUCTURE_THREAD_CONFIG_INIT \ + { \ + QNN_DSP_PERF_INFRASTRUCTURE_THREAD_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + 0 /*numHvxThreads*/ \ + } \ + } + +//============================================================================= +// API Methods +//============================================================================= + +/** + * @brief This API allows client to create power configuration id that + * has to be used to set different performance modes. + * Power configuration id has to be destroyed by client when not needed. + * + * @param[out] powerConfigId Pointer to power configuration id to be created. + * + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if power configuration + * id is NULL + */ +typedef Qnn_ErrorHandle_t (*QnnDspPerfInfrastructure_CreatePowerConfigIdFn_t)( + uint32_t* powerConfigId); + +/** + * @brief This API allows client to destroy power configuration id. + * + * @param[in] powerConfigId A power configuration id to be destroyed. + * + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if power configuration + * id does not exist + */ +typedef Qnn_ErrorHandle_t (*QnnDspPerfInfrastructure_DestroyPowerConfigIdFn_t)( + uint32_t powerConfigId); + +/** + * @brief This API allows client to set up system power configuration that + * will enable different performance modes. This API uses + * HAP_power_dcvs_v3_payload struct to config HAP power parameters. + * Detailed HAP power parameters description please refer to Hexagon + * SDK HAP_power_dcvs_v3_payload documentation. + * + * @param[in] powerConfigId A power client id to associate calls to system + * power settings. A value of 0 implies NULL power client id + * and can override every other setting the user process. To + * enable power settings for multiple clients in the same + * process, use a non-zero power client id. + * + * + * @param[in] config Pointer to a NULL terminated array + * of config option for performance configuration. + * NULL is allowed and indicates no config options are provided. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if power configuration + * does not exist + */ +typedef Qnn_ErrorHandle_t (*QnnDspPerfInfrastructure_SetPowerConfigFn_t)( + uint32_t powerConfigId, const QnnDspPerfInfrastructure_PowerConfig_t** config); + +/** + * @brief This API allows clients to set up configuration associated with + * system memory + * + * @param[in] config Pointer to a NULL terminated array + * of config option for system memory configuration. + * NULL is allowed and indicates no config options are provided. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + */ +typedef Qnn_ErrorHandle_t (*QnnDspPerfInfrastructure_SetMemoryConfigFn_t)( + const QnnDspPerfInfrastructure_MemoryConfig_t** config); + +/** + * @brief This API allows clients to set up configuration for threads + * + * @param[in] config Pointer to a NULL terminated array + * of config option for thread configuration. + * NULL is allowed and indicates no config options are provided. + * + * @note This function should be called after QnnBackend_initialize and + * before Context and Graph calls + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED_CONFIG if invalid + * config or value passed + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if config is NULL + * \n QNN_DSP_PERF_INFRASTRUCTURE_ERROR_TRANSPORT if unable to set the + * settings in DSP + */ +typedef Qnn_ErrorHandle_t (*QnnDspPerfInfrastructure_SetThreadConfigFn_t)( + const QnnDspPerfInfrastructure_ThreadConfig_t** config); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // QNN_DSP_PERF_INFRASTRUCTURE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProfile.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProfile.h new file mode 100755 index 0000000000000..04c1897aa7e18 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProfile.h @@ -0,0 +1,244 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief QNN DSP Profile component API. + * + * Requires DSP backend to be initialized. + * Should be used with the QnnProfile API but has DSP backend + * specific definition for different QnnProfile data structures + * + */ + +#ifndef QNN_DSP_PROFILE_H +#define QNN_DSP_PROFILE_H + +#include "QnnProfile.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_HOST_RPC_TIME_MICROSEC 1002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the DSP processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary dsp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_DSP_RPC_TIME_MICROSEC 1003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to create the context on the + * accelerator when client invokes QnnContext_createFromBinary. + * The value returned is time in microseconds. + * + * @note context load binary accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_ACCEL_TIME_MICROSEC 1004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_HOST_RPC_TIME_MICROSEC 2001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the DSP processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize dsp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_DSP_RPC_TIME_MICROSEC 2002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to finalize the graph on the accelerator + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_ACCEL_TIME_MICROSEC 2003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_HOST_RPC_TIME_MICROSEC 3001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the DSP processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute dsp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_DSP_RPC_TIME_MICROSEC 3002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is number of processor cycles taken. + * + * @note graph execute accelerator time maybe available only on + * QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE. + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_CYCLE 3003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time taken in microseconds + * + * @note graph execute accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE / QNN_PROFILE_EVENTUNIT_MICROSEC + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_MICROSEC 3004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time taken for miscellaneous work i.e. time + * that cannot be attributed to a node but are still needed to + * execute the graph on the accelerator. This occurs when client invokes + * QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time taken in microseconds + * + * @note graph execute misc accelerator time is available only on + * QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_MISC_ACCEL_TIME_MICROSEC 3005 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time taken for a graph yield instance to + * release all its resources to the other graph. + * The value returned is time taken in microseconds. + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_RELEASE_TIME 3006 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time a graph spends waiting for a higher + * priority graph to finish execution. + * The value returned is time taken in microseconds + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_WAIT_TIME 3007 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time a graph spends re-acquiring resources + * and restoring vtcm. + * The value returned is time taken in microseconds + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_RESTORE_TIME 3008 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the number of times that a yield occured + * during execution + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_COUNT 3009 + +/** + * @brief QnnProfile_EventType_t definition for time a graph waits to get + * VTCM. This should be constant UNLESS we need another graph to yield. + * The value returned is time taken in microseconds. + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_VTCM_ACQUIRE_TIME 3010 + +/** + * @brief QnnProfile_EventType_t definition for time a graph waits to get + * HMX + HVX, and turn them all on. + * The value returned is time taken in microseconds. + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_RESOURCE_POWER_UP_TIME 3011 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_DEINIT_HOST_RPC_TIME_MICROSEC 4001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the DSP processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit dsp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_DEINIT_DSP_RPC_TIME_MICROSEC 4002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to deinit graph on the + * accelerator when client invokes QnnContext_free which in consequence + * deinit graph. The value returned is time in microseconds. + * + * @note graph deinit accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_DSP_PROFILE_EVENTTYPE_GRAPH_DEINIT_ACCEL_TIME_MICROSEC 4003 + +#ifdef __cplusplus +} +#endif + +#endif // QNN_DSP_PROFILE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProperty.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProperty.h new file mode 100755 index 0000000000000..39669338e35f8 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/QnnDspProperty.h @@ -0,0 +1,30 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef QNN_DSP_PROPERTY_H +#define QNN_DSP_PROPERTY_H + +#include "QnnProperty.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief Property key for determining whether a backend supports unsigned pd. + */ +#define QNN_PROPERTY_CUSTOM_DSP_UNSIGNED_PD_SUPPORT QNN_PROPERTY_GROUP_CUSTOM + 1 + +#ifdef __cplusplus +} +#endif + +#endif // QNN_DSP_PROPERTY_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoBase.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoBase.h new file mode 100755 index 0000000000000..942e5997ab5ff --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoBase.h @@ -0,0 +1,509 @@ +//============================================================================== +// +// Copyright (c) 2019-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_BASE_H +#define SNPE_UDO_BASE_H + +#include + +// Provide values to use for API version. +#define API_VERSION_MAJOR 1 +#define API_VERSION_MINOR 6 +#define API_VERSION_TEENY 0 + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +// Defines a bitmask of enum values. +typedef uint32_t SnpeUdo_Bitmask_t; +typedef SnpeUdo_Bitmask_t Udo_Bitmask_t; + +// A string of characters, rather than an array of bytes. +// Assumed to be UTF-8. +typedef char* SnpeUdo_String_t; +typedef SnpeUdo_String_t Udo_String_t; + +// The maximum allowable length of a SnpeUdo_String_t in bytes, +// including null terminator. SNPE will truncate strings longer +// than this. +#define SNPE_UDO_MAX_STRING_SIZE 1024 + +/** + * An enum which holds the various error types. + * The error types are divided to classes : + * 0 - 99 : generic errors + * 100 - 200 : errors related to configuration + * + */ +typedef enum +{ + /// No Error + SNPE_UDO_NO_ERROR = 0, UDO_NO_ERROR = 0, + /// Unsupported value for core type + SNPE_UDO_WRONG_CORE = 1, UDO_WRONG_CORE = 1, + /// Invalid attribute/argument passed into UDO API + SNPE_UDO_INVALID_ARGUMENT = 2, UDO_INVALID_ARGUMENT = 2, + /// Unsupported feature error + SNPE_UDO_UNSUPPORTED_FEATURE = 3, UDO_UNSUPPORTED_FEATURE = 3, + /// Error relating to memory allocation + SNPE_UDO_MEM_ALLOC_ERROR = 4, UDO_MEM_ALLOC_ERROR = 4, + /* Configuration Specific errors */ + /// No op with given attributes available in library + SNPE_UDO_WRONG_OPERATION = 100, UDO_WRONG_OPERATION = 100, + /// Unsupported value for core type in UDO configuration + SNPE_UDO_WRONG_CORE_TYPE = 101, UDO_WRONG_CORE_TYPE = 101, + /// Wrong number of params in UDO definition + SNPE_UDO_WRONG_NUM_OF_PARAMS = 102, UDO_WRONG_NUM_OF_PARAMS = 102, + /// Wrong number of dimensions for tensor(s) in UDO definition + SNPE_UDO_WRONG_NUM_OF_DIMENSIONS = 103, UDO_WRONG_NUM_OF_DIMENSIONS = 103, + /// Wrong number of input tensors in UDO definition + SNPE_UDO_WRONG_NUM_OF_INPUTS = 104, UDO_WRONG_NUM_OF_INPUTS = 104, + /// Wrong number of output tensors in UDO definition + SNPE_UDO_WRONG_NUM_OF_OUTPUTS = 105, UDO_WRONG_NUM_OF_OUTPUTS = 105, + SNPE_UDO_PROGRAM_CACHE_NOT_FOUND = 106, UDO_PROGRAM_CACHE_NOT_FOUND = 106, + SNPE_UDO_UNKNOWN_ERROR = 0xFFFFFFFF, UDO_UNKNOWN_ERROR = 0xFFFFFFFF +} SnpeUdo_ErrorType_t; + +typedef SnpeUdo_ErrorType_t Udo_ErrorType_t; + +/** + * An enum which holds the various data types. + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + * \n FIXED_XX types are targeted for data in tensors. + * \n UINT / INT types are targeted for scalar params + */ +typedef enum +{ + /// data type: 16-bit floating point + SNPE_UDO_DATATYPE_FLOAT_16 = 0x01, UDO_DATATYPE_FLOAT_16 = 0x01, + /// data type: 32-bit floating point + SNPE_UDO_DATATYPE_FLOAT_32 = 0x02, UDO_DATATYPE_FLOAT_32 = 0x02, + /// data type: 4-bit fixed point + SNPE_UDO_DATATYPE_FIXED_4 = 0x04, UDO_DATATYPE_FIXED_4 = 0x04, + /// data type: 8-bit fixed point + SNPE_UDO_DATATYPE_FIXED_8 = 0x08, UDO_DATATYPE_FIXED_8 = 0x08, + /// data type: 16-bit fixed point + SNPE_UDO_DATATYPE_FIXED_16 = 0x10, UDO_DATATYPE_FIXED_16 = 0x10, + /// data type: 32-bit fixed point + SNPE_UDO_DATATYPE_FIXED_32 = 0x20, UDO_DATATYPE_FIXED_32 = 0x20, + /// data type: 8-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_8 = 0x100, UDO_DATATYPE_UINT_8 = 0x100, + /// data type: 16-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_16 = 0x200, UDO_DATATYPE_UINT_16 = 0x200, + /// data type: 32-bit unsigned integer + SNPE_UDO_DATATYPE_UINT_32 = 0x400, UDO_DATATYPE_UINT_32 = 0x400, + /// data type: 8-bit signed integer + SNPE_UDO_DATATYPE_INT_8 = 0x1000, UDO_DATATYPE_INT_8 = 0x1000, + /// data type: 16-bit signed integer + SNPE_UDO_DATATYPE_INT_16 = 0x2000, UDO_DATATYPE_INT_16 = 0x2000, + /// data type: 32-bit signed integer + SNPE_UDO_DATATYPE_INT_32 = 0x4000, UDO_DATATYPE_INT_32 = 0x4000, + SNPE_UDO_DATATYPE_LAST = 0xFFFFFFFF, UDO_DATATYPE_LAST = 0xFFFFFFFF +} SnpeUdo_DataType_t; + +typedef SnpeUdo_DataType_t Udo_DataType_t; + +/** + * An enum which holds the various layouts. + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + */ +typedef enum +{ + /// data layout (4D): NHWC (batch-height-width-channel) + SNPE_UDO_LAYOUT_NHWC = 0x01, UDO_LAYOUT_NHWC = 0x01, + /// data layout (4D): NCHW (batch-channel-height-width) + SNPE_UDO_LAYOUT_NCHW = 0x02, UDO_LAYOUT_NCHW = 0x02, + /// data layout (5D): NDHWC (batch-dimension-height-width-channel) + SNPE_UDO_LAYOUT_NDHWC = 0x04, UDO_LAYOUT_NDHWC = 0x04, + SNPE_UDO_LAYOUT_GPU_OPTIMAL1 = 0x08, UDO_LAYOUT_GPU_OPTIMAL1 = 0x08, + SNPE_UDO_LAYOUT_GPU_OPTIMAL2 = 0x10, UDO_LAYOUT_GPU_OPTIMAL2 = 0x10, + SNPE_UDO_LAYOUT_DSP_OPTIMAL1 = 0x11, UDO_LAYOUT_DSP_OPTIMAL1 = 0x11, + SNPE_UDO_LAYOUT_DSP_OPTIMAL2 = 0x12, UDO_LAYOUT_DSP_OPTIMAL2 = 0x12, + // Indicates no data will be allocated for this tensor. + // Used to specify optional inputs/outputs positionally. + SNPE_UDO_LAYOUT_NULL = 0x13, UDO_LAYOUT_NULL = 0x13, + SNPE_UDO_LAYOUT_LAST = 0xFFFFFFFF, UDO_LAYOUT_LAST = 0xFFFFFFFF +} SnpeUdo_TensorLayout_t; + +typedef SnpeUdo_TensorLayout_t Udo_TensorLayout_t; + +/** + * An enum which holds the UDO library Core type . + * Designed to be used as single values or combined into a bitfield parameter + * (0x1, 0x2, 0x4, etc) + */ +typedef enum +{ + /// Library target IP Core is undefined + SNPE_UDO_CORETYPE_UNDEFINED = 0x00, UDO_CORETYPE_UNDEFINED = 0x00, + /// Library target IP Core is CPU + SNPE_UDO_CORETYPE_CPU = 0x01, UDO_CORETYPE_CPU = 0x01, + /// Library target IP Core is GPU + SNPE_UDO_CORETYPE_GPU = 0x02, UDO_CORETYPE_GPU = 0x02, + /// Library target IP Core is DSP + SNPE_UDO_CORETYPE_DSP = 0x04, UDO_CORETYPE_DSP = 0x04, + SNPE_UDO_CORETYPE_LAST = 0xFFFFFFFF, UDO_CORETYPE_LAST = 0xFFFFFFFF +} SnpeUdo_CoreType_t; + +typedef SnpeUdo_CoreType_t Udo_CoreType_t; + +/** + * An enum to specify the parameter type : Scalar or Tensor + */ +typedef enum +{ + /// UDO static param type: scalar + SNPE_UDO_PARAMTYPE_SCALAR = 0x00, UDO_PARAMTYPE_SCALAR = 0x00, + /// UDO static param type: string + SNPE_UDO_PARAMTYPE_STRING = 0x01, UDO_PARAMTYPE_STRING = 0x01, + /// UDO static param type: tensor + SNPE_UDO_PARAMTYPE_TENSOR = 0x02, UDO_PARAMTYPE_TENSOR = 0x02, + SNPE_UDO_PARAMTYPE_LAST = 0xFFFFFFFF, UDO_PARAMTYPE_LAST = 0xFFFFFFFF +} SnpeUdo_ParamType_t; + +typedef SnpeUdo_ParamType_t Udo_ParamType_t; + +/** + * An enum to specify quantization type + */ +typedef enum +{ + /// Tensor Quantization type: NONE. Signifies unquantized tensor data + SNPE_UDO_QUANTIZATION_NONE = 0x00, UDO_QUANTIZATION_NONE = 0x00, + /// Tensor Quantization type: Tensorflow-style + SNPE_UDO_QUANTIZATION_TF = 0x01, UDO_QUANTIZATION_TF = 0x01, + SNPE_UDO_QUANTIZATION_QMN = 0x02, UDO_QUANTIZATION_QMN = 0x02, + SNPE_UDO_QUANTIZATION_LAST = 0xFFFFFFFF, UDO_QUANTIZATION_LAST = 0xFFFFFFFF +} SnpeUdo_QuantizationType_t; + +typedef SnpeUdo_QuantizationType_t Udo_QuantizationType_t; + +/** + * @brief A struct which is used to provide a version number using 3 values : major, minor, teeny + * + */ +typedef struct +{ + /// version field: major - for backward-incompatible changes + uint32_t major; + /// version field: minor - for backward-compatible feature updates + uint32_t minor; + /// version field: teeny - for minor bug-fixes and clean-up + uint32_t teeny; +} SnpeUdo_Version_t; + +typedef SnpeUdo_Version_t Udo_Version_t; + +/** + * @brief A struct returned from version query, contains the Library version and API version + * + */ +typedef struct +{ + /// Version of UDO library. Controlled by users + SnpeUdo_Version_t libVersion; + /// Version of SNPE UDO API used in compiling library. Determined by SNPE + SnpeUdo_Version_t apiVersion; +} SnpeUdo_LibVersion_t; + +/** + * @brief A struct returned from version query, contains the package version + * + */ +typedef struct +{ + /// Version of UDO API used in package. + Udo_Version_t apiVersion; +} Udo_PkgVersion_t; + +/** + * @brief A union to hold the value of a generic type. Allows defining a parameter struct + * in a generic way, with a "value" location that holds the data regardless of the type. + * + */ +typedef union +{ + /// value type: float + float floatValue; + /// value type: unsigned 32-bit integer + uint32_t uint32Value; + /// value type: signed 32-bit integer + int32_t int32Value; + /// value type: unsigned 16-bit integer + uint16_t uint16Value; + /// value type: signed 16-bit integer + int16_t int16Value; + /// value type: unsigned 8-bit integer + uint8_t uint8Value; + /// value type: signed 8-bit integer + int8_t int8Value; +} SnpeUdo_Value_t; + +typedef SnpeUdo_Value_t Udo_Value_t; + +/** + * @brief A struct which defines a scalar parameter : name, data type, and union of values + * + */ +typedef struct +{ + /// The parameter data type : float, int, etc. + SnpeUdo_DataType_t dataType; + /// a union of specified type which holds the data + SnpeUdo_Value_t dataValue; +} SnpeUdo_ScalarParam_t; + +typedef SnpeUdo_ScalarParam_t Udo_ScalarParam_t; + +/** + * @brief A struct which defines the quantization parameters in case of Tensorflow style quantization + * + */ +typedef struct +{ + /// minimum value of the quantization range of data + float minValue; + /// maximum value of the quantization range of data + float maxValue; +} SnpeUdo_TFQuantize_t; + +typedef SnpeUdo_TFQuantize_t Udo_TFQuantize_t; + +/** + * @brief A struct which defines the quantization type, and union of supported quantization structs + * + */ +typedef struct +{ + /// quantization type (only TF-style currently supported) + SnpeUdo_QuantizationType_t quantizeType; + union + { + /// TF-style min-max quantization ranges + SnpeUdo_TFQuantize_t TFParams; + }; +} SnpeUdo_QuantizeParams_t; + +typedef SnpeUdo_QuantizeParams_t Udo_QuantizeParams_t; + +/** + * @brief A struct which defines the datatype associated with a specified core-type + * This should be used to denote the datatypes for a single tensor info, depending + * on the intended execution core. + * + */ +typedef struct +{ + /// The IP Core + SnpeUdo_CoreType_t coreType; + /// The associated datatype for this coreType + SnpeUdo_DataType_t dataType; +} SnpeUdo_PerCoreDatatype_t; + +typedef SnpeUdo_PerCoreDatatype_t Udo_PerCoreDatatype_t; + +/** + * @brief A struct which defines a tensor parameter : name, data type, layout, quantization, more. + * Also holds a pointer to the tensor data. + * + */ +typedef struct +{ + /// The maximum allowable dimensions of the tensor. The memory held in + /// _tensorData_ is guaranteed to be large enough for this. + uint32_t* maxDimensions; + /// The current dimensions of the tensor. An operation may modify the current + /// dimensions of its output, to indicate cases where the output has been + /// "resized". + /// Note that for static parameters, the current and max dimensions must + /// match. + uint32_t* currDimensions; + /// Quantization params applicable to the tensor. Currently only supports + /// Tensorflow quantization style. + SnpeUdo_QuantizeParams_t quantizeParams; + /// Number of dimensions to the tensor: 3D, 4D, etc. + uint32_t tensorRank; + /// The parameter data type: float, int, etc. + SnpeUdo_DataType_t dataType; + /// The tensor layout type: NCHW, NHWC, etc. + SnpeUdo_TensorLayout_t layout; + /// Opaque pointer to tensor data. User may be required to re-interpret the pointer + /// based on core-specific definitions. + void* tensorData; +} SnpeUdo_TensorParam_t; + +typedef SnpeUdo_TensorParam_t Udo_TensorParam_t; + +/** + * @brief struct which defines a UDO parameter - a union of scalar, tensor and string parameters + * + */ +typedef struct +{ + /// Type is scalar or tensor + SnpeUdo_ParamType_t paramType; + /// The param name, for example : "offset", "activation_type" + SnpeUdo_String_t paramName; + union + { + /// scalar param value + SnpeUdo_ScalarParam_t scalarParam; + /// tensor param value + SnpeUdo_TensorParam_t tensorParam; + /// string param value + SnpeUdo_String_t stringParam; + }; +} SnpeUdo_Param_t; + +typedef SnpeUdo_Param_t Udo_Param_t; + +/** + * @brief A struct which defines Operation information which is specific for IP core (CPU, GPU, DSP ...) + * + */ +typedef struct +{ + /// The IP Core + SnpeUdo_CoreType_t udoCoreType; + /// Bitmask, defines supported internal calculation types (like FLOAT_32, etc) + /// Based on SnpeUdo_DataType + SnpeUdo_Bitmask_t operationCalculationTypes; +} SnpeUdo_OpCoreInfo_t; + +typedef SnpeUdo_OpCoreInfo_t Udo_OpCoreInfo_t; + +/** + * @brief A struct which defines the common and core-specific Operation information + * + */ +typedef struct +{ + /// Operation type + SnpeUdo_String_t operationType; + /// A bitmask describing which IP Cores (CPU, GPU, DSP ...) support this operation + /// Translated based on SnpeUdo_CoreType + SnpeUdo_Bitmask_t supportedByCores; + /// Number of static parameters defined by the op + uint32_t numOfStaticParams; + /// Array of static parameters. Can be scalar or tensor params + SnpeUdo_Param_t* staticParams; + /// Number of input tensors this op receives + uint32_t numOfInputs; + /// Array of input tensor names to this operation + SnpeUdo_String_t* inputNames; + /// Number of output tensors this op receives + uint32_t numOfOutputs; + /// Array of output tensor names to this operation + SnpeUdo_String_t* outputNames; + /// Number of cores that the op can execute on + uint32_t numOfCoreInfo; + /// Array of per-core information entries + SnpeUdo_OpCoreInfo_t* opPerCoreInfo; +} SnpeUdo_OperationInfo_t; + +typedef SnpeUdo_OperationInfo_t Udo_OperationInfo_t; + +/** + * @brief A struct which provides the implementation library info : type, name + * + */ +typedef struct +{ + /// Defines the IP Core that this implementation library is targeting + SnpeUdo_CoreType_t udoCoreType; + /// library name. will be looked at in the standard library path + SnpeUdo_String_t libraryName; +} SnpeUdo_LibraryInfo_t; + +typedef SnpeUdo_LibraryInfo_t Udo_LibraryInfo_t; + +/** + * @brief A struct returned by the registration library and contains information on the UDO package : + * name, operations, libraries, etc. + * + */ +typedef struct +{ + /// A string containing the package name + SnpeUdo_String_t packageName; + /// A bitmask describing supported IP cores (CPU, GPU, DSP ...) + /// Translated based on SnpeUdo_CoreType + SnpeUdo_Bitmask_t supportedCoreTypes; + /// The number of implementation libraries in the package + uint32_t numOfImplementationLib; + /// Array of implementation libraries names/types + SnpeUdo_LibraryInfo_t* implementationLib; + /// A string containing all operation types separated by space + SnpeUdo_String_t operationsString; + /// Number of supported operations + uint32_t numOfOperations; + /// Array of Operation info structs. Each entry describes one + /// Operation (name, params, inputs, outputs) + SnpeUdo_OperationInfo_t* operationsInfo; +} SnpeUdo_RegInfo_t; + +typedef SnpeUdo_RegInfo_t Udo_RegInfo_t; + +/** +* @brief A struct returned by the implementation library and contains information on the +* specific library: name, IP Core, operations, etc. +* +*/ +typedef struct +{ + /// Defines the IP Core that this implementation library is targeting + SnpeUdo_CoreType_t udoCoreType; + /// A string containing the package name + SnpeUdo_String_t packageName; + /// A string containing all operation types separated by space + SnpeUdo_String_t operationsString; + /// Number of supported operations + uint32_t numOfOperations; +} SnpeUdo_ImpInfo_t; + +typedef SnpeUdo_ImpInfo_t Udo_ImpInfo_t; + +/** + * @brief This struct defines an operation. It is used for validation + * or creation of an operation. + * In case of using it for creation, the static params which are tensors + * contain pointers to the real data (weights, for example), and input/output + * tensors also include pointers to the buffers used. + */ +typedef struct +{ + /// The IP Core that the operation is defined for - CPU, GPU, DSP... + SnpeUdo_CoreType_t udoCoreType; + /// Operation type + SnpeUdo_String_t operationType; + /// The number of static parameters provided in the staticParams array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfStaticParams; + /// Array of static parameters + SnpeUdo_Param_t* staticParams; + /// The number of input parameters provided in inputs array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfInputs; + /// Array of input tensors, providing layout, data type, sizes, etc + /// When used to create an operation, also contains the initial location of the data + SnpeUdo_TensorParam_t* inputs; + /// The number of output parameters provided in inputs array. + /// this number has to match the number provided by the UDO Registration library information + uint32_t numOfOutputs; + /// Array of output tensors, providing layout, data type, sizes, etc + /// When used to create an operation, also contains the initial location of the data + SnpeUdo_TensorParam_t* outputs; +} SnpeUdo_OpDefinition_t; + +typedef SnpeUdo_OpDefinition_t Udo_OpDefinition_t; + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#endif //SNPE_UDO_BASE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoFlatten.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoFlatten.h new file mode 100755 index 0000000000000..84a8fe310908e --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoFlatten.h @@ -0,0 +1,78 @@ +//============================================================================== +// +// Copyright (c) 2019 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#include "DSP/Udo/UdoBase.h" + +#define HVX_ALIGNMENT 128 +#define DSP_STRUCT_ALIGNMENT 8 +#define DSP_ALIGN(X, ALIGNMENT) (((X) + ALIGNMENT - 1) & (~((ALIGNMENT)-1))) + +typedef struct dspStaticParamsMeta { + uint32_t size; + uint32_t numParams; +} dspStaticParamsMeta_t; + +typedef struct tensorParamInfo { + SnpeUdo_TensorLayout_t layout; + SnpeUdo_QuantizeParams_t quantizeInfo; + SnpeUdo_DataType_t dataType; + uint32_t paddingFor8byteAlignment; +} tensorParamInfo_t; + +typedef struct udoString { + uint32_t sizeStruct; // aligned + uint32_t lengthString; // does not include null character + // followed by a string +} udoString_t; // allocate mem for string for 8 byte alignment + +typedef struct dims { + uint32_t size; + uint32_t rank; + uint32_t ds; // rank # of max dimensions followed by rank # of current dimensions for tensors +} dims_t; + +typedef struct tensorData { + uint32_t structSize; + uint32_t dataSize; + // followed by actual tensor data +} tensorData_t; + +typedef struct dspStaticParamDescriptor { + uint32_t size; // including size of descriptor (including dims + data for tensors) (or including string for strings) + SnpeUdo_ParamType_t paramType; + union { // not used for string data + SnpeUdo_ScalarParam_t scalarInfo; + tensorParamInfo_t tensorInfo; + }; + udoString_t name; + // followed by char* + // in case of tensor, followed by dim_stride and tensor_data + // in case of string, followed by udo_string and char* +} dspStaticParamDescriptor_t; + +typedef struct paramSizes { + uint32_t descriptorSize; + uint32_t nameStructSize; + uint32_t dimsSize; + uint32_t dataStructSize; + uint32_t dataSize; + uint32_t stringDataStructSize; +} paramSizes_t; + +typedef struct dspStaticParams { + dspStaticParamsMeta_t meta; + dspStaticParamDescriptor_t paramDesc; +} dspStaticParams_t; + + +int +SnpeUdo_flattenStaticParams (SnpeUdo_Param_t** paramList, uint32_t numParams, uint32_t* flattenedSize, void** flattened); + +void +SnpeUdo_freeFlattenedStaticParams (void** flattened); + diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImpl.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImpl.h new file mode 100755 index 0000000000000..bcc767a3c4a0f --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImpl.h @@ -0,0 +1,343 @@ +//============================================================================== +// +// Copyright (c) 2019-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_IMPL_H +#define SNPE_UDO_IMPL_H + +#include + +#include "DSP/Udo/UdoShared.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +typedef struct _SnpeUdo_OpFactory_t* SnpeUdo_OpFactory_t; +typedef struct _SnpeUdo_Operation_t* SnpeUdo_Operation_t; + +typedef SnpeUdo_OpFactory_t Udo_OpFactory_t; +typedef SnpeUdo_Operation_t Udo_Operation_t; + +/** + * @brief Initialize the shared library's data structures. Calling any other + * library function before this one will result in error. + * + * @param[in] globalInfrastructure Global core-specific infrastructure to be + * used by operations created in this library. The definition and + * semantics of this object will be defined in the corresponding + * implementation header for the core type. + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_initImplLibrary(void* globalInfrastructure); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_InitImplLibraryFunction_t)(void*); + +/** + * @brief A function to query the API version of the UDO implementation library. + * The function populates a SnpeUdo_LibVersion_t struct, which contains a SnpeUdo_Version_t + * struct for API version and library version. + * + * @param[in, out] version A pointer to struct which contains major, minor, teeny information for + * library and api versions. + * + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_getImplVersion(SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_getImplVersion_t)(SnpeUdo_LibVersion_t** version); + +/** + * @brief Release the shared library's data structures, and invalidate any + * handles returned by the library. The behavior of any outstanding + * asynchronous calls made to this library when this function is called + * are undefined. All library functions (except SnpeUdo_initImplLibrary) will + * return an error after this function has been successfully called. + * + * It should be possible to call SnpeUdo_initImplLibrary after calling this + * function, and re-initialize the library. + * + * @return Error code + */ +SnpeUdo_ErrorType_t +SnpeUdo_terminateImplLibrary(void); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_TerminateImplLibraryFunction_t)(void); + + +/** + * @brief A function to query info on the UDO implementation library. + * The function populates a structure which contains information about + * operations that are part of this library + * + * @param[in, out] implementationInfo A pointer to struct which contains information + * on the operations + * + * @return error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_getImpInfo(SnpeUdo_ImpInfo_t** implementationInfo); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_GetImpInfoFunction_t)(SnpeUdo_ImpInfo_t** implementationInfo); + +typedef SnpeUdo_GetImpInfoFunction_t Udo_GetImpInfoFunction_t; + +/** + * @brief A function to create an operation factory. + * The function receives the operation type, and an array of static parameters, + * and returns operation factory handler + * + * @param[in] udoCoreType The Core type to create the operation on. An error will + * be returned if this does not match the core type of the library. + * + * @param[in] perFactoryInfrastructure CreateOpFactory infrastructure appropriate to this + * core type. The definition and semantics of this object will be defined + * in the corresponding implementation header for the core type. + * + * @param[in] operationType A string containing Operation type. for example "MY_CONV" + * + * @param[in] numOfStaticParams The number of static parameters. + * + * @param[in] staticParams Array of static parameters + * + * @param[in,out] opFactory Handler to Operation Factory, to be used when creating operations + * + * @return Error Code + */ +SnpeUdo_ErrorType_t +SnpeUdo_createOpFactory(SnpeUdo_CoreType_t udoCoreType, + void* perFactoryInfrastructure, + SnpeUdo_String_t operationType, + uint32_t numOfStaticParams, + SnpeUdo_Param_t* staticParams, + SnpeUdo_OpFactory_t* opFactory); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_CreateOpFactoryFunction_t)(SnpeUdo_CoreType_t, + void*, + SnpeUdo_String_t, + uint32_t, + SnpeUdo_Param_t*, + SnpeUdo_OpFactory_t*); + +typedef SnpeUdo_CreateOpFactoryFunction_t Udo_CreateOpFactoryFunction_t; + +/** + * @brief A function to release the resources allocated for an operation factory + * created by this library. + * + * @param[in] opFactory The operation factory to release. Upon success this handle will be invalidated. + * + * @return Error Code + */ +SnpeUdo_ErrorType_t +SnpeUdo_releaseOpFactory(SnpeUdo_OpFactory_t opFactory); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ReleaseOpFactoryFunction_t)(SnpeUdo_OpFactory_t); + +typedef SnpeUdo_ReleaseOpFactoryFunction_t Udo_ReleaseOpFactoryFunction_t; + +/** + * @brief A function to create an operation from the factory. + * The function receives array of inputs and array of outputs, and creates an operation + * instance, returning the operation instance handler. + * + * @param[in] opFactory OpFactory instance containing the parameters for this operation. + * + * @param[in] perOpInfrastructure Per-Op infrastructure for this operation. The definition + * and semantics of this object will be defined in the implementation header + * appropriate to this core type. + * + * @param[in] numOfInputs The number of input tensors this operation will receive. + * + * @param[in] inputs Array of input tensors, providing both the sizes and initial + * location of the data. + * + * @param[in] numOfOutputs Number of output tensors this operation will produce. + * + * @param[in] outputs Array of output tensors, providing both the sizes and + * initial location of the data. + * + * @param[in,out] operation Handle for newly created operation instance. + * + * @return Error Code + */ +SnpeUdo_ErrorType_t +SnpeUdo_createOperation(SnpeUdo_OpFactory_t opFactory, + void* perOpInfrastructure, + uint32_t numOfInputs, + SnpeUdo_TensorParam_t* inputs, + uint32_t numOfOutputs, + SnpeUdo_TensorParam_t* outputs, + SnpeUdo_Operation_t* operation); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_CreateOperationFunction_t)(SnpeUdo_OpFactory_t, + void*, + uint32_t, + SnpeUdo_TensorParam_t*, + uint32_t, + SnpeUdo_TensorParam_t*, + SnpeUdo_Operation_t*); + +typedef SnpeUdo_CreateOperationFunction_t Udo_CreateOperationFunction_t; + +/** + * @brief A pointer to notification function. + * + * The notification function supports the non-blocking (e.g. asynchronous) execution use-case. + * In case an "executeUdoOp" function is called with "blocking" set to zero, and a + * notify function, this function will be called by the implementation library at the + * end of execution. The implementation library will pass the notify function the ID + * that was provided to it when "executeUdoOp" was called. + * + * @param[in] ID 32-bit value, that was provided to executeUdoOp by the calling entity. + * Can be used to track the notifications, in case of multiple execute calls issued. + * + * @return Error code + * + */ +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ExternalNotify_t)(const uint32_t ID); + +typedef SnpeUdo_ExternalNotify_t Udo_ExternalNotify_t; + +/** + * @brief Operation execution function. + * + * Calling this function will run the operation on set of inputs, generating a set of outputs. + * The call can be blocking (synchronous) or non-blocking (asynchronous). To support the + * non-blocking mode, the calling entity can pass an ID and a notification function. + * At the end of the execution this notification function would be called, passing it the ID. + * NOTE: Asynchronous execution mode not supported in this release. + * + * @param[in] operation handle to the operation on which execute is invoked + * @param[in] blocking flag to indicate execution mode. + * If set, execution is blocking, + * e.g SnpeUdo_executeOp call does not return until execution is done. + * If not set, SnpeUdo_executeOp returns immediately, and the + * library will call the notification function (if set) when execution is done. + * + * @param[in] ID 32-bit number that can be used by the calling entity to track execution + * in case of non-blocking execution. + * For example, it can be a sequence number, increased by one on each call. + * + * @param[in] notifyFunc Pointer to notification function. if the pointer is set, and execution is + * non-blocking, the library will call this function at end of execution, + * passing the number provided as ID + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_executeOp(SnpeUdo_Operation_t operation, + bool blocking, + const uint32_t ID, + SnpeUdo_ExternalNotify_t notifyFunc); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ExecuteOpFunction_t)(SnpeUdo_Operation_t, + bool, + const uint32_t, + SnpeUdo_ExternalNotify_t); + +typedef SnpeUdo_ExecuteOpFunction_t Udo_ExecuteOpFunction_t; + +/** + * @brief A function to setting the inputs & outputs. part of SnpeUdo_Operation struct, + * returned from creation of a new operation instance. + * Not supported in this release. + * + * This function allows the calling entity to change some of the inputs and outputs + * between calls to execute. + * Note that the change is limited to changing the pointer to the tensor data only. + * Any other change may be rejected by the implementation library, causing + * immediate invalidation of the operation instance + * + * @param[in] operation Operation on which IO tensors are set + * + * @param[in] inputs array of tensor parameters. The calling entity may provide a subset of the + * operation inputs, providing only those that it wants to change. + * + * @param[in] outputs array of tensor parameters. The calling entity may provide a subset of the + * operation outputs, providing only those that it wants to change. + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_setOpIO(SnpeUdo_Operation_t operation, + SnpeUdo_TensorParam_t* inputs, + SnpeUdo_TensorParam_t* outputs); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_SetOpIOFunction_t)(SnpeUdo_Operation_t, + SnpeUdo_TensorParam_t*, + SnpeUdo_TensorParam_t*); + +typedef SnpeUdo_SetOpIOFunction_t Udo_SetOpIOFunction_t; + +/** + * @brief A function to return execution times. + * + * This function can be called to query the operation execution times on the IP core + * on which the operation is run. The time is provided in micro-seconds + * + * @param[in] operation Handle to operation whose execution time is being profiled + * + * @param[in,out] executionTime pointer to a uint32 value.This function writes the operation + * execution time in usec into this value. + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_profileOp(SnpeUdo_Operation_t operation, uint32_t *executionTime); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ProfileOpFunction_t)(SnpeUdo_Operation_t, uint32_t*); + +typedef SnpeUdo_ProfileOpFunction_t Udo_ProfileOpFunction_t; + +/** + * @brief A function to release the operation instance + * \n When it is called, the implementation library needs to release all resources + * allocated for this operation instance. + * \n Note that all function pointers which are part of SnpeUdo_Operation become + * invalid once releaseUdoOp call returns. + * + * @param[in] operation Handle to operation to be released + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_releaseOp(SnpeUdo_Operation_t operation); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_ReleaseOpFunction_t)(SnpeUdo_Operation_t); + +typedef SnpeUdo_ReleaseOpFunction_t Udo_ReleaseOpFunction_t; + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //SNPE_UDO_IMPL_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImplDsp.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImplDsp.h new file mode 100755 index 0000000000000..522c6050a402d --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoImplDsp.h @@ -0,0 +1,199 @@ +//============================================================================== +// +// Copyright (c) 2019-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +// Header to be used by a DSP Hexnn UDO Implementation library + +#ifndef SNPE_UDO_IMPL_DSP_H +#define SNPE_UDO_IMPL_DSP_H +#include +#include "DSP/Udo/UdoImpl.h" + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * @brief A function to validate that a set of params is supported by an operation + * This function is HexNN specific, use case is when registration library is not in use. + * Optional function. + * + * @param[in] operationType Operation type + * @param[in] numOfStaticParams Number of static params defined by the op + * @param[in] staticParams Array of static params to the op + * @return Error code, indicating if the operation can be created on this set of configuration or not. + * + */ + +SnpeUdo_ErrorType_t +SnpeUdo_validateOperation (SnpeUdo_String_t operationType, + uint32_t numOfStaticParams, + const SnpeUdo_Param_t* staticParams); + +typedef SnpeUdo_ErrorType_t (*SnpeUdo_ValidateOperationFunction_t) (SnpeUdo_String_t, + uint32_t, + const SnpeUdo_Param_t*); + +typedef SnpeUdo_ValidateOperationFunction_t Udo_ValidateOperationFunction_t; + +// enum used for indicating input/outout tensor data layouts on DSP, plain vs d32 +typedef enum { + SNPE_UDO_DSP_TENSOR_LAYOUT_PLAIN = 0x00, UDO_DSP_TENSOR_LAYOUT_PLAIN = 0x00, + SNPE_UDO_DSP_TENSOR_LAYOUT_D32 = 0x01, UDO_DSP_TENSOR_LAYOUT_D32 = 0x01 +} SnpeUdo_HexNNTensorLayout_t; + +typedef SnpeUdo_HexNNTensorLayout_t Udo_HexNNTensorLayout_t; + +/** + * @brief A function to query numbers of inputs and outputs, + * quantization type of each input and each output as arrays, + * and data layout (plain vs d32) of each input and each output as arrays + * of an operation. + * inputsQuantTypes and inputsLayouts should point to arrays of size numOfInputs + * outputsQuantTypes and outputsLayouts should point to arrays of size numOfOutputs + * + * Note: inputsLayouts and inputsLayouts can point to NULL, in this case, it is + * assumed all inputs and/or outputs have plain data layouts, i.e. no D32 + * + * @param[in] operationType Operation type + * @param[in] numOfStaticParams Number of static params defined by the op + * @param[in] staticParams Array of static params to the op + * @param[in,out] numOfInputs Number of input tensors to the op + * @param[in,out] inputsQuantTypes Array of Quantization info for each input tensor + * @param[in,out] inputsLayouts Array of layout type for each input tensor + * @param[in,out] numOfOutputs Number of output tensors to the op + * @param[in,out] outputsQuantTypes Array of Quantization info for each output tensor + * @param[in,out] outputsLayouts Array of layout type for each output tensor + * @return error code, indicating status of query + */ + +SnpeUdo_ErrorType_t +SnpeUdo_queryOperation (SnpeUdo_String_t operationType, + uint32_t numOfStaticParams, + const SnpeUdo_Param_t* staticParams, + uint32_t* numOfInputs, + SnpeUdo_QuantizationType_t** inputsQuantTypes, + SnpeUdo_HexNNTensorLayout_t** inputsLayouts, + uint32_t* numOfOutputs, + SnpeUdo_QuantizationType_t** outputsQuantTypes, + SnpeUdo_HexNNTensorLayout_t** outputsLayouts); + +typedef SnpeUdo_ErrorType_t (*SnpeUdo_QueryOperationFunction_t) (SnpeUdo_String_t, + uint32_t, + const SnpeUdo_Param_t*, + uint32_t*, + SnpeUdo_QuantizationType_t**, + SnpeUdo_HexNNTensorLayout_t**, + uint32_t*, + SnpeUdo_QuantizationType_t**, + SnpeUdo_HexNNTensorLayout_t**); + +typedef SnpeUdo_QueryOperationFunction_t Udo_QueryOperationFunction_t; + +// Global infrastructure functions supported by Hexagon-NN v2 +typedef void (*workerThread_t) (void* perOpInfrastructure, void* userData); +typedef int (*udoSetOutputTensorSize_t) (void* perOpInfrastructure, uint32_t outIdx, uint32_t size); +typedef int (*udoGetInputD32Paddings_t) (void* perOpInfrastructure, uint32_t inIdx, + uint32_t* heightPadBefore, uint32_t* heightPadAfter, + uint32_t* widthPadBefore, uint32_t* widthPadAfter, + uint32_t* depthPadBefore, uint32_t* depthPadAfter); +typedef int (*udoSetOutputD32ShapeSizePaddings_t) (void* perOpInfrastructure, uint32_t outIdx, + uint32_t batch, + uint32_t height, uint32_t heightPadBefore, uint32_t heightPadAfter, + uint32_t width, uint32_t widthPadBefore, uint32_t widthPadAfter, + uint32_t depth, uint32_t depthPadBefore, uint32_t depthPadAfter, + SnpeUdo_DataType_t dataType); +typedef void* (*udoMemalign_t) (size_t n, size_t size); +typedef void* (*udoMalloc_t) (size_t size); +typedef void* (*udoCalloc_t) (size_t n, size_t size); +typedef void (*udoFree_t) (void* ptr); +typedef uint32_t (*udoGetVtcmSize_t) (void* perOpInfrastructure); +typedef void* (*udoGetVtcmPtr_t) (void* perOpInfrastructure); +typedef uint32_t (*udoVtcmIsReal_t) (void* perOpInfrastructure); +typedef void (*udoRunWorkerThreads_t) (void* perOpInfrastructure, uint32_t nThreads, workerThread_t w, void* userData); + +typedef struct hexNNv2GlobalInfra { + udoSetOutputTensorSize_t udoSetOutputTensorSize; + udoGetInputD32Paddings_t udoGetInputD32Paddings; + udoSetOutputD32ShapeSizePaddings_t udoSetOutputD32ShapeSizePaddings; + udoMemalign_t udoMemalign; + udoMalloc_t udoMalloc; + udoCalloc_t udoCalloc; + udoFree_t udoFree; + udoGetVtcmSize_t udoGetVtcmSize; + udoGetVtcmPtr_t udoGetVtcmPtr; + udoVtcmIsReal_t udoVtcmIsReal; + udoRunWorkerThreads_t udoRunWorkerThreads; +} SnpeUdo_HexNNv2GlobalInfra_t; + +typedef SnpeUdo_HexNNv2GlobalInfra_t Udo_HexNNv2GlobalInfra_t; + +// hexnn types +typedef enum hexnnInfraType { + UDO_INFRA_HEXNN_V2, + UDO_INFRA_HEXNN_V3 // reserved, do not use +} SnpeUdo_HexNNInfraType_t; + +typedef SnpeUdo_HexNNInfraType_t Udo_HexNNInfraType_t; + +typedef struct { + Udo_CreateOpFactoryFunction_t create_op_factory; + Udo_CreateOperationFunction_t create_operation; + Udo_ExecuteOpFunction_t execute_op; + Udo_ReleaseOpFunction_t release_op; + Udo_ReleaseOpFactoryFunction_t release_op_factory; + Udo_ValidateOperationFunction_t validate_op; + Udo_QueryOperationFunction_t query_op; +} udo_func_package_t; + +/** + * @brief Infrastructures needed by a developer of DSP Hexnn UDO Implementation library. + * + * The framework/runtime which loads the Hexnn UDO implementation library provides + * this infrastructure to the loaded library by calling "SnpeUdo_initImplLibrary" + * function, and passing it (cast to void*). The Hexnn UDO library is expected + * to cast it back to this structure. + * + */ +typedef struct dspGlobalInfrastructure { + SnpeUdo_Version_t dspInfraVersion; // api version + SnpeUdo_HexNNInfraType_t infraType; + SnpeUdo_HexNNv2GlobalInfra_t hexNNv2Infra; +} SnpeUdo_DspGlobalInfrastructure_t; + +typedef SnpeUdo_DspGlobalInfrastructure_t Udo_DspGlobalInfrastructure_t; + +/** + * hexnn v2 per op factory infrastructure + * + * The framework/runtime passes per op factory infrastructure as a void pointer + * to HexNN UDO implementation library by calling function "SnpeUdo_createOpFactory". + * UDO implementation library is expected to cast it back to this following struct. + * + */ +typedef struct hexnnv2OpFactoryInfra { + unsigned long graphId; +} SnpeUdo_HexNNv2OpFactoryInfra_t; + +typedef SnpeUdo_HexNNv2OpFactoryInfra_t Udo_HexNNv2OpFactoryInfra_t; + +/** + * hexnn v2 per operation infrastructure + * + * The framework/runtime passes per operation infrastructure as a void pointer + * to HexNN UDO implementation library by calling function "SnpeUdo_createOperation". + * UDO implementation library is expected to cast it to the following type and save it. + * + * This is needed to be passed back into some functions from global infrastructure. + * + */ +typedef void* SnpeUdo_HexNNv2OpInfra_t; + +typedef SnpeUdo_HexNNv2OpInfra_t Udo_HexNNv2OpInfra_t; + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#endif // SNPE_UDO_IMPL_DSP_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoShared.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoShared.h new file mode 100755 index 0000000000000..8c17c1d5b35f1 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/DSP/Udo/UdoShared.h @@ -0,0 +1,48 @@ +//============================================================================== +// +// Copyright (c) 2019-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef SNPE_UDO_SHARED_H +#define SNPE_UDO_SHARED_H + +#include "DSP/Udo/UdoBase.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup c_plus_plus_apis C++ +@{ */ + +/** + * @brief A function to return the various versions as they relate to the UDO + * The function returns a struct containing the the following: + * libVersion: the version of the implementation library compiled for the UDO. Set by user + * apiVersion: the version of the UDO API used in compiling the implementation library. + * Set by SNPE + * + * @param[in, out] version A pointer to Version struct of type SnpeUdo_LibVersion_t + * + * @return Error code + * + */ +SnpeUdo_ErrorType_t +SnpeUdo_getVersion (SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_ErrorType_t +(*SnpeUdo_GetVersionFunction_t) (SnpeUdo_LibVersion_t** version); + +typedef SnpeUdo_GetVersionFunction_t Udo_GetVersionFunction_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +/** @} */ /* end_addtogroup c_plus_plus_apis C++ */ + +#endif // SNPE_UDO_SHARED_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuBackend.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuBackend.h new file mode 100755 index 0000000000000..d7050c875f6db --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuBackend.h @@ -0,0 +1,71 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines the QNN GPU specialization of the QnnBackend.h interface. + */ + +#ifndef QNN_GPU_BACKEND_H +#define QNN_GPU_BACKEND_H + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "QnnBackend.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief This enum defines QNN GPU custom Backend config options. +*/ +typedef enum { + /// If non-zero, tuning mode will be enabled + QNN_GPU_BACKEND_CONFIG_OPTION_ENABLE_TUNING_MODE = 0, + /// The Performance cache directory. Must be non-null + QNN_GPU_BACKEND_CONFIG_OPTION_PERFORMANCE_CACHE_DIR = 1, + /// If non-zero, the performance cache will be ignored when initializing + QNN_GPU_BACKEND_CONFIG_OPTION_INVALIDATE_PERFORMANCE_CACHE = 2, + /// Unused, present to ensure 32 bits. + QNN_GPU_BACKEND_CONFIG_OPTION_UNDEFINED = 0x7FFFFFFF, +} QnnGpuBackend_ConfigOption_t; + +/** + * @brief A struct which defines the QNN GPU Backend custom configuration options. + * Objects of this type are to be referenced through QnnBackend_CustomConfig_t. + */ +typedef struct { + QnnGpuBackend_ConfigOption_t option; + union UNNAMED { + uint8_t enableTuningMode; + const char* performanceCacheDir; + uint8_t invalidatePerformanceCache; + }; +} QnnGpuBackend_CustomConfig_t; + +// clang-format off +/// QnnGpuBackend_CustomConfig_t initializer macro +#define QNN_GPU_BACKEND_CUSTOM_CONFIG_INIT \ + { \ + QNN_GPU_BACKEND_CONFIG_OPTION_UNDEFINED, /*option*/ \ + { \ + false /*enableTuningMode*/ \ + } \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuCommon.h new file mode 100755 index 0000000000000..8fd9c18afb46b --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuCommon.h @@ -0,0 +1,49 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines common QNN GPU macros. + */ + +#ifndef QNN_GPU_COMMON_H +#define QNN_GPU_COMMON_H + +#include "QnnCommon.h" + +/// GPU Backend identifier +#define QNN_BACKEND_ID_GPU 4 + +/// GPU interface provider +#define QNN_GPU_INTERFACE_PROVIDER_NAME "GPU_QTI_AISW" + +// GPU API Version values +#define QNN_GPU_API_VERSION_MAJOR 3 +#define QNN_GPU_API_VERSION_MINOR 7 +#define QNN_GPU_API_VERSION_PATCH 0 + +// clang-format off + +/// Macro to set Qnn_ApiVersion_t for GPU backend +#define QNN_GPU_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_GPU_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_GPU_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_GPU_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +#endif // QNN_GPU_COMMON_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuContext.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuContext.h new file mode 100755 index 0000000000000..42599e4280971 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuContext.h @@ -0,0 +1,78 @@ +//============================================================================== +// +// Copyright (c) 2021-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines the QNN GPU specialization of the QnnContext.h interface. + */ + +#ifndef QNN_GPU_CONTEXT_H +#define QNN_GPU_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This enum defines QNN GPU custom context config options. + */ +typedef enum { + /// Sets performance hint options via QnnGpuContext_PerfHint_t + QNN_GPU_CONTEXT_CONFIG_OPTION_PERF_HINT = 0, + /// If non-zero, OpenGL buffers will be used + QNN_GPU_CONTEXT_CONFIG_OPTION_USE_GL_BUFFERS = 1, + /// The kernel disk cache directory. Must be non-null + QNN_GPU_CONTEXT_CONFIG_OPTION_KERNEL_REPO_DIR = 2, + /// If non-zero, the kernel disk cache will be ignored when initializing + QNN_GPU_CONTEXT_CONFIG_OPTION_INVALIDATE_KERNEL_REPO = 3, + /// Unused, present to ensure 32 bits. + QNN_GPU_CONTEXT_CONFIG_OPTION_UNDEFINED = 0x7FFFFFFF +} QnnGpuContext_ConfigOption_t; + +/** + * @brief An enum which defines the different GPU performance hint options. + */ +typedef enum { + /// Sets the GPU performance hint to high performance, this is the default + QNN_GPU_CONTEXT_PERF_HINT_HIGH = 0, + /// Sets the GPU performance hint to normal performance + QNN_GPU_CONTEXT_PERF_HINT_NORMAL = 1, + /// Sets the GPU performance hint to low performance + QNN_GPU_CONTEXT_PERF_HINT_LOW = 2 +} QnnGpuContext_PerfHint_t; + +/** + * @brief A struct which defines the QNN GPU context custom configuration options. + * Objects of this type are to be referenced through QnnContext_CustomConfig_t. + */ +typedef struct { + QnnGpuContext_ConfigOption_t option; + union UNNAMED { + QnnGpuContext_PerfHint_t perfHint; + uint8_t useGLBuffers; + const char* kernelRepoDir; + uint8_t invalidateKernelRepo; + }; +} QnnGpuContext_CustomConfig_t; + +// clang-format off +/// QnnGpuContext_CustomConfig_t initializer macro +#define QNN_GPU_CONTEXT_CUSTOM_CONFIG_INIT \ + { \ + QNN_GPU_CONTEXT_CONFIG_OPTION_UNDEFINED, /*option*/ \ + { \ + QNN_GPU_CONTEXT_PERF_HINT_HIGH /*perfHint*/ \ + } \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuGraph.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuGraph.h new file mode 100755 index 0000000000000..e0652d44883ef --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuGraph.h @@ -0,0 +1,72 @@ +//============================================================================== +// +// Copyright (c) 2020-2021 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines the QNN GPU specialization of the QnnGraph.h interface. + */ + +#ifndef QNN_GPU_GRAPH_H +#define QNN_GPU_GRAPH_H + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "QnnGraph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief An enum which defines the different tensor optimization options. A + * tensor may be optimized to the specified QnnGpu_Precision_t when it + * is a graph tensor that is not a graph input or a graph output and + * does not connect two operations from different op packages. + */ +typedef enum { + /// Sets the precision mode to floating point 32-bit (FP32) + QNN_GPU_PRECISION_FP32 = 0, + /// Sets the precision mode to floating point 16-bit (FP16) + QNN_GPU_PRECISION_FP16 = 1, + /// Sets the precision mode to FP16 for storage and FP32 for calculations + QNN_GPU_PRECISION_HYBRID = 2, + /// Uses the tensor data type provided by the user (default) + QNN_GPU_PRECISION_USER_PROVIDED = 3, +} QnnGpu_Precision_t; + +/** + * @brief A struct which defines the QNN GPU graph custom configuration options. + * Objects of this type are to be referenced through QnnGraph_CustomConfig_t. + */ +typedef struct { + QnnGpu_Precision_t precision; + uint8_t disableMemoryOptimizations; + uint8_t disableNodeOptimizations; + uint8_t disableQueueRecording; +} QnnGpuGraph_CustomConfig_t; + +// clang-format off +/// QnnGpuGraph_CustomConfig_t initializer macro +#define QNN_GPU_GRAPH_CUSTOM_CONFIG_INIT \ + { \ + QNN_GPU_PRECISION_USER_PROVIDED, /*precision*/ \ + 0u, /*disableMemoryOptimizations*/ \ + 0u, /*disableNodeOptimizations*/ \ + 0u /*disableQueueRecording*/ \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuMem.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuMem.h new file mode 100755 index 0000000000000..1c6cd5c3e032a --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuMem.h @@ -0,0 +1,52 @@ +//============================================================================== +// +// Copyright (c) 2024 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines the QNN GPU specialization of the QnnMem.h interface. + */ + +#ifndef QNN_GPU_MEM_H +#define QNN_GPU_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* QnnGpuMem_Buffer_t; + +/** + * @brief This enum defines QNN GPU memory type + */ +typedef enum { QNN_GPU_MEM_OPENCL = 0, QNN_GPU_MEM_UNDEFINED = 0x7FFFFFF } QnnGpu_MemType_t; + +/** + * @brief A struct which defines the QNN GPU memory preallocated by the client. + * Objects of this type are to be referenced through Qnn_MemInfoCustom_t. + */ +typedef struct { + QnnGpu_MemType_t memType; + union { + QnnGpuMem_Buffer_t buffer; + }; +} QnnGpu_MemInfoCustom_t; + +// clang-format off +/// QnnGpu_MemInfoCustom_t initializer macro +#define QNN_GPU_MEMINFO_CUSTOM_INIT \ + { \ + QNN_GPU_MEM_UNDEFINED, /*memType*/ \ + NULL /* buffer*/ \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuOpPackage.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuOpPackage.h new file mode 100755 index 0000000000000..5413f50ba2267 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GPU/QnnGpuOpPackage.h @@ -0,0 +1,682 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief A header which defines the QNN GPU specialization of the QnnOpPackage.h interface. + */ + +#ifndef QNN_GPU_OP_PACKAGE_H +#define QNN_GPU_OP_PACKAGE_H + +#ifdef __cplusplus +#include +#else +#include +#endif + +#include "GPU/QnnGpuCommon.h" +#include "GPU/QnnGpuGraph.h" +#include "QnnOpPackage.h" +#include "QnnTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// QnnOpPackage_GlobalInfrastructure_t specialization. +//============================================================================= + +/** + * @brief A struct which is used to communicate device constant properties + */ +typedef struct { + /// GPU device version string + char deviceVersion[128]; + /// GPU driver interface version {major, minor} + uint32_t interfaceVersion[2]; + /// GPU Adreno(TM) tier string + char tierName[8]; + /// GPU driver version {product, major, minor, patch} + uint32_t compilerVersion[4]; + /// GPU device max work group size + size_t maxWorkGroupSize; + /// GPU device image 2D max width + size_t image2dMaxWidth; + /// GPU device image 2D max height + size_t image2dMaxHeight; + /// GPU device max memory allocation size + size_t maxBufferAllocSize; + /// GPU device addr alignment in bits + uint32_t baseAddrAlignment; + /// GPU device image 2D Array max width + size_t image2dArrayMaxWidth; + /// GPU device image 2D Array max height + size_t image2dArrayMaxHeight; + /// GPU device image 2D Array max depth + size_t image2dArrayMaxDepth; +} QnnGpu_DeviceProperties_t; + +/** + * @brief A QNN GPU struct specializing QnnOpPackage_GlobalInfrastructure_t + */ +typedef struct _QnnOpPackage_GlobalInfrastructure_t { + /// GPU backend version (as returned by QnnBackend_getApiVersion()) + const Qnn_ApiVersion_t* sdkApiVersion; + /// GPU device properties + const QnnGpu_DeviceProperties_t* deviceProperties; + /// Null terminated path to the OpenCL driver used by the backend + const char* driverPath; +} QnnGpuOpPackage_GlobalInfrastructure_t; + +//============================================================================= +// QnnOpPackage_PackageInfo_t specialization. +//============================================================================= + +/** + * @brief A struct having op package specific information + */ +typedef struct _QnnOpPackage_PackageInfo_t { + /// Null terminated hash key string of all kernel sources + const char* kernelRepoHash; +} QnnGpuOpPackage_PackageInfo_t; + +//============================================================================= +// QnnOpPackage_Optimization_t specialization. +//============================================================================= + +/** + * @brief An enum to specify the QNN GPU optimization type + * + */ +typedef enum { + /// Undefined option only used for QNN_GPU_OP_PACKAGE_OPTIMIZATION_INIT + QNN_GPU_OPTIMIZATION_TYPE_UNDEFINED = 0, + /// Super node optimization + QNN_GPU_OPTIMIZATION_TYPE_SUPER_NODE = 2, +} QnnGpuOpPackage_OptimizationType_t; + +/** + * @brief A struct representing a super node connection constraint. + */ +typedef struct { + /// Producer node corresponding to QnnGpuOpPackage_SuperNodeOptimization_t::operations + uint32_t producer; + /// Output tensor index corresponding to the producer node + uint32_t producerOutputIndex; + /// Consumer node corresponding to QnnGpuOpPackage_SuperNodeOptimization_t::operations + uint32_t consumer; + /// Output tensor index corresponding to the consumer node + uint32_t consumerInputIndex; +} QnnGpuOpPackage_SuperNodeConnectionConstraint_t; + +/** + * @brief An enum to specify the source of a tensor in an op def for a tensor constraint. + * + */ +typedef enum { + /// Tensor is an op def output + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_SOURCE_OUTPUT = 1, + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_SOURCE_INPUT = 2, +} QnnGpuOpPackage_TensorConstraintSource_t; + +/** + * @brief An enum to specify the tensor constraint type. + * + */ +typedef enum { + /// Add a Qnn_DataType_t to the whitelist of allowable types. + /// If no data type constraint is present for a tensor, all data types are allowed. + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_CONSTRAINT_DATA_TYPE = 1, + /// Tensor must match it's rank + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_CONSTRAINT_RANK = 2, + /// Tensor must match one of it's dimensions + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_CONSTRAINT_DIMENSION = 3, + /// Add a Qnn_TensorType_t to the whitelist of allowable tensor types. + /// If no tensor type constraint is present for a tensor, all types are allowed. + QNN_GPU_OPTIMIZATION_SUPER_NODE_TENSOR_CONSTRAINT_TENSOR_TYPE = 4, +} QnnGpuOpPackage_TensorConstraintType_t; + +/** + * @brief A struct representing a tensor constraint. + */ +typedef struct { + /// Operation corresponding to QnnGpuOpPackage_SuperNodeOptimization_t::operations + uint32_t operationIndex; + /// Source of the tensor in the Qnn_OpConfig_t + QnnGpuOpPackage_TensorConstraintSource_t source; + union { + /// Tensor index in the Qnn_OpConfig_t, used only for inputs and outputs + uint32_t index; + /// Tensor parameter name in the Qnn_OpConfig_t, used only for parameters + const char* name; + }; + /// Type of tensor constraint + QnnGpuOpPackage_TensorConstraintType_t type; + union { + /// Tensor data type for Qnn_DataType_t constraints + Qnn_DataType_t dataType; + /// Tensor type for Qnn_TensorType_t constraints + Qnn_TensorType_t tensorType; + /// Tensor rank for rank constraints + uint32_t rank; + struct { + /// Tensor dimension index for dimension constraints + uint32_t index; + /// Tensor dimension size for dimension constraints + uint32_t size; + } dimension; + }; +} QnnGpuOpPackage_TensorConstraint_t; + +typedef struct { + /// Null-terminated array of comma separated lists of operations used for matching super node ops. + /// An asterisk (*) may be used to represent any operation type. + const char** operations; + /// Null-terminated array of pointers to super node connection constraints + QnnGpuOpPackage_SuperNodeConnectionConstraint_t** connectionConstraints; + /// Null-terminated array of pointers to super node tensor constraints + QnnGpuOpPackage_TensorConstraint_t** tensorConstraints; +} QnnGpuOpPackage_SuperNodeOptimization_t; + +// clang-format off +/// QnnGpuOpPackage_SuperNodeOptimization_t initializer macro +#define QNN_GPU_OP_PACKAGE_SUPER_NODE_OPTIMIZATION_INIT \ + { \ + NULL, /*operations*/ \ + NULL, /*connectionConstraints*/ \ + NULL, /*tensorConstraints*/ \ + } +// clang-format on + +/** + * @brief A struct representing a QNN GPU optimization. + */ +typedef struct _QnnOpPackage_Optimization_t { + /// Type of optimization + QnnGpuOpPackage_OptimizationType_t type; + /// Op package assigned name of the optimization + const char* name; + union { + /// Super node optimization, used when type is QNN_GPU_OPTIMIZATION_TYPE_SUPER_NODE + const QnnGpuOpPackage_SuperNodeOptimization_t* superNode; + }; +} QnnGpuOpPackage_Optimization_t; + +/// QnnGpuOpPackage_Optimization_t initializer macro +#define QNN_GPU_OP_PACKAGE_OPTIMIZATION_INIT \ + { \ + QNN_GPU_OPTIMIZATION_TYPE_UNDEFINED, NULL, { NULL } \ + } + +//============================================================================= +// QnnOpPackage_GraphInfrastructure_t specialization. +//============================================================================= + +/** + * @brief A QNN GPU struct specializing QnnOpPackage_GraphInfrastructure_t + */ +typedef struct _QnnOpPackage_GraphInfrastructure_t { + /// GPU precision mode, user-supplied hint used for optimal kernel selection + QnnGpu_Precision_t precisionMode; +} QnnGpuOpPackage_GraphInfrastructure_t; + +//============================================================================= +// QNN GPU Memory Object +//============================================================================= + +/** + * @brief An enum to specify the QNN GPU memory object type + * + */ +typedef enum { + /// Host memory, only used for Qnn_Param_t tensors + QNN_GPU_MEM_OBJ_TYPE_HOST = 0, + /// GPU driver buffer memory object + QNN_GPU_MEM_OBJ_TYPE_BUFFER = 1, + /// GPU driver image 2D memory object + QNN_GPU_MEM_OBJ_TYPE_IMAGE2D = 2, + /// GPU driver image 2D array memory object + QNN_GPU_MEM_OBJ_TYPE_IMAGE2D_ARRAY = 3, + /// Aggregation of GPU driver image 2D memory objects + QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D = 4, + /// Aggregation of GPU driver image 2D array memory objects + QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D_ARRAY = 5, + /// Memory type is unclaimed and can be specified by the op package via the \n + /// QnnGpu_OutputClaim_t struct + QNN_GPU_MEM_OBJ_TYPE_UNCLAIMED = 6, +} QnnGpu_MemoryObjectType_t; + +/** + * @brief An enum to specify the QNN GPU memory layout + * + */ +typedef enum { + /// HWC layout + QNN_GPU_MEM_LAYOUT_HWC = 0, + /// HCW layout + QNN_GPU_MEM_LAYOUT_HCW = 1, + /// CHW layout + QNN_GPU_MEM_LAYOUT_CHW = 2, + /// Undefined + QNN_GPU_MEM_LAYOUT_UNDEFINED = 0x7FFFFFFF, +} QnnGpu_MemoryLayout_t; + +/** + * @brief A struct to specify blockSize for weight Tensor and tensorId for weight Param tensor + */ +typedef struct { + // Block Quantization, block Sizes + uint32_t* bqBlockSize; + /// Tensor Id for Quantization encodings + uint32_t bqEncodingTensorId; +} QnnGpu_BlockEncodingInfo_t; + +// clang-format off +/// QnnGpu_MemoryObject_t initializer macro +#define QNN_GPU_BLOCK_ENCODING_INFO_INIT \ + { \ + NULL, /*bqBlockSize*/ \ + 0u /*bqEncodingTensorId*/ \ + } +// clang-format on + +/** + * @brief A QNN GPU struct specifying a memory object + * This struct is used with the following kernel argument types: + * - QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READ + * - QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READWRITE + * - QNN_GPU_KERNEL_ARG_TYPE_OP_OUTPUT_WRITE + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READ + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READWRITE + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_WRITE + */ +typedef struct { + /// Type of memory object + QnnGpu_MemoryObjectType_t type; + /// Data type of the memory object + Qnn_DataType_t dataType; + /// Memory object dimensions \n + /// Size is numDimensions. Uses the following type dependent format: \n + /// QNN_GPU_MEM_OBJ_TYPE_BUFFER -> {numElements} \n + /// QNN_GPU_MEM_OBJ_TYPE_IMAGE2D -> {height,width} \n + /// QNN_GPU_MEM_OBJ_TYPE_IMAGE2D_ARRAY -> {height,width,array_size} \n + /// QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D -> {num_batches,height,width} \n + /// QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D_ARRAY -> {num_batches,height,width,array_size} + uint32_t* dimensions; + /// Memory object offsets \n + /// Size is numDimensions. \n + /// Indicates where the data store starts in the memory object. \n + uint32_t* offsets; + /// Number of dimensions in memory object \n + /// Size is numDimensions. Has the following type dependent size: \n + /// QNN_GPU_MEM_OBJ_TYPE_BUFFER -> 1 \n + /// QNN_GPU_MEM_OBJ_TYPE_IMAGE2D -> 2 \n + /// QNN_GPU_MEM_OBJ_TYPE_IMAGE2D_ARRAY -> 3 \n + /// QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D -> 3 \n + /// QNN_GPU_MEM_OBJ_TYPE_AGGREGATED_IMAGE2D_ARRAY -> 4 + uint32_t numDimensions; + /// Memory object layout \n + /// Op package specific layout identifier \n + /// Default is QNN_GPU_MEM_LAYOUT_UNDEFINED if not already specified by a prior operation + QnnGpu_MemoryLayout_t layout; + /// Block Quantization Tensor Information + QnnGpu_BlockEncodingInfo_t blockEncodingInfo; +} QnnGpu_MemoryObject_t; + +// clang-format off +/// QnnGpu_MemoryObject_t initializer macro +#define QNN_GPU_MEMORY_OBJECT_INIT \ + { \ + QNN_GPU_MEM_OBJ_TYPE_UNCLAIMED, /*type*/ \ + QNN_DATATYPE_UNDEFINED, /*dataType*/ \ + NULL, /*dimensions*/ \ + NULL, /*offsets*/ \ + 0u, /*numDimensions*/ \ + QNN_GPU_MEM_LAYOUT_UNDEFINED, /*layout*/ \ + QNN_GPU_BLOCK_ENCODING_INFO_INIT /*blockEncodingInfo*/ \ + } +// clang-format on + +//============================================================================= +// QnnOpPackage_Node_t specialization. +//============================================================================= + +/** + * @brief A QNN GPU struct specifying a storage tensor + */ +typedef struct { + /// Tensor ID + uint32_t id; + /// Tensor's associated memory object + const QnnGpu_MemoryObject_t* memoryObject; +} QnnGpu_TensorStorageType_t; + +// clang-format off +/// QnnGpu_TensorStorageType_t initializer macro +#define QNN_GPU_TENSOR_STORAGE_TYPE_INIT \ + { \ + 0u, /*id*/ \ + NULL /*memoryObject*/ \ + } +// clang-format on + +/** + * @brief A QNN GPU struct specializing QnnOpPackage_Node_t + */ +typedef struct _QnnOpPackage_Node_t { + /// Optimization index, see QnnOpPackage_Info_t, ignore when only one op config provided + uint32_t optimization; + /// Null-terminated array of operation config pointers + /// Only one pointer provided when no optimizations performed + const Qnn_OpConfig_t** configs; + /// Null-terminated array of tensor storage type pointers called out in the config + const QnnGpu_TensorStorageType_t** storageTypes; + /// Kernel variant index, if set then used by OpPackage to determine kernel selection + int32_t kernelVariant; +} QnnGpuOpPackage_Node_t; + +//============================================================================= +// QnnOpPackage_OpImpl_t specialization. +//============================================================================= + +/** + * @brief A QNN GPU struct specifying an output tensor claim. Using the principle + * of least work, operations must output a memory object type that is most + * convenient for itself. Only QNN_TENSOR_TYPE_NATIVE tensor types may + * be claimed. + */ +typedef struct { + /// Index into the Qnn_OpConfig_t provided in QnnGpuOpPackage_Node_t + uint32_t opConfigIndex; + /// Index into the operation outputs to identify the tensor + uint32_t outputIndex; + /// Specification of the claimed memory object + const QnnGpu_MemoryObject_t* memoryObject; +} QnnGpu_OutputClaim_t; + +// clang-format off +/// QnnGpu_OutputClaim_t initializer macro +#define QNN_GPU_OUTPUT_CLAIM_INIT \ + { \ + 0u, /*opConfigIndex*/ \ + 0u, /*outputIndex*/ \ + NULL /*memoryObject*/ \ + } +// clang-format on + +/** + * @brief An enum to specify the kernel argument type. + * + */ +typedef enum { + /// Operation input tensor used as kernel input + QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READ = 0, + /// Operation input tensor used as kernel output + QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READWRITE = 1, + /// Operation output tensor used as kernel output + QNN_GPU_KERNEL_ARG_TYPE_OP_OUTPUT_WRITE = 2, + /// Operation internal tensor used as kernel input + QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READ = 3, + /// Operation internal tensor used as kernel input/output + QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READWRITE = 4, + /// Operation internal tensor used as kernel output + QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_WRITE = 5, + /// Plain old data kernel argument + QNN_GPU_KERNEL_ARG_TYPE_DATA = 6, + /// Local memory kernel argument + QNN_GPU_KERNEL_ARG_TYPE_LOCAL = 7, + /// Null pointer kernel argument + QNN_GPU_KERNEL_ARG_TYPE_NULL_PTR = 8, + /// Operation tensor parameter used as kernel input + QNN_GPU_KERNEL_ARG_TYPE_OP_TENSOR_PARAM = 9, +} QnnGpu_KernelArgType_t; + +/** + * @brief A QNN GPU struct specifying a kernel argument corresponding to a tensor. + * This struct is used with the following kernel argument types: + * - QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READ + * - QNN_GPU_KERNEL_ARG_TYPE_OP_INPUT_READWRITE + * - QNN_GPU_KERNEL_ARG_TYPE_OP_OUTPUT_WRITE + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READ + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_READWRITE + * - QNN_GPU_KERNEL_ARG_TYPE_INTERNAL_WRITE + */ +typedef struct { + /// Index into the Qnn_OpConfig_t provided in QnnGpuOpPackage_Node_t, ignored for INTERNAL types + uint32_t opConfigIndex; + /// Index into the operation input ot output list or the internal tensor list + uint32_t tensorIndex; + /// Batch element index for aggregated tensor types + uint32_t element; +} QnnGpu_TensorKernelArg_t; + +// clang-format off +/// QnnGpu_TensorKernelArg_t initializer macro +#define QNN_GPU_TENSOR_KERNEL_ARG_INIT \ + { \ + 0u, /*opConfigIndex*/ \ + 0u, /*tensorIndex*/ \ + 0u /*element*/ \ + } +// clang-format on + +/** + * @brief An enum to specify the kernel data argument type. + * + */ +typedef enum { + QNN_GPU_KERNEL_ARG_CL_TYPE_CHAR = 0, + QNN_GPU_KERNEL_ARG_CL_TYPE_UCHAR = 1, + QNN_GPU_KERNEL_ARG_CL_TYPE_SHORT = 2, + QNN_GPU_KERNEL_ARG_CL_TYPE_USHORT = 3, + QNN_GPU_KERNEL_ARG_CL_TYPE_INT = 4, + QNN_GPU_KERNEL_ARG_CL_TYPE_UINT = 5, + QNN_GPU_KERNEL_ARG_CL_TYPE_LONG = 6, + QNN_GPU_KERNEL_ARG_CL_TYPE_ULONG = 7, + QNN_GPU_KERNEL_ARG_CL_TYPE_FLOAT = 8, + QNN_GPU_KERNEL_ARG_CL_TYPE_DOUBLE = 9, +} QnnGpu_DataKernelArgType_t; + +/** + * @brief A QNN GPU struct specifying a kernel argument corresponding to a plain old data. + * This struct is used only with the QNN_GPU_KERNEL_ARG_TYPE_DATA arg type. + */ +typedef struct { + /// Data type of the data + QnnGpu_DataKernelArgType_t type; + union { + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_CHAR + int8_t qnnChar; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_UCHAR + uint8_t qnnUChar; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_SHORT + int16_t qnnShort; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_USHORT + uint16_t qnnUShort; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_INT + int32_t qnnInt; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_UINT + uint32_t qnnUInt; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_LONG + int64_t qnnLong; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_ULONG + uint64_t qnnULong; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_FLOAT + float qnnFloat; + /// Used with QNN_GPU_KERNEL_ARG_CL_TYPE_DOUBLE + double qnnDouble; + }; +} QnnGpu_DataKernelArg_t; + +/// QnnGpu_DataKernelArg_t initializer macro +#define QNN_GPU_DATA_KERNEL_ARG_INIT \ + { \ + QNN_GPU_KERNEL_ARG_CL_TYPE_CHAR, /*type*/ \ + { \ + 0 /*qnnChar*/ \ + } \ + } + +/** + * @brief A QNN GPU struct specifying a kernel argument corresponding to a local memory type. + * This struct is used only with the QNN_GPU_KERNEL_ARG_TYPE_LOCAL arg type. + */ +typedef struct { + /// Size of the memory requested in bytes + uint32_t size; +} QnnGpu_LocalKernelArg_t; + +/// QnnGpu_LocalKernelArg_t initializer macro +#define QNN_GPU_LOCAL_KERNEL_ARG_INIT \ + { 0u /*size*/ } + +/** + * @brief A QNN GPU struct specifying a kernel argument. + * Note that the QNN_GPU_KERNEL_ARG_TYPE_NULL_PTR type does not have an entry in + * the union. + */ +typedef struct { + /// Type of kernel argument + QnnGpu_KernelArgType_t type; + union { + /// Tensor type argument + QnnGpu_TensorKernelArg_t tensor; + /// Plain old data argument + QnnGpu_DataKernelArg_t data; + /// Local memory argument + QnnGpu_LocalKernelArg_t local; + }; +} QnnGpu_KernelArg_t; + +/// QnnGpu_KernelArg_t initializer macro +#define QNN_GPU_KERNEL_ARG_INIT \ + { \ + QNN_GPU_KERNEL_ARG_TYPE_NULL_PTR, /*type*/ \ + { \ + QNN_GPU_TENSOR_KERNEL_ARG_INIT /*tensor*/ \ + } \ + } + +/** + * @brief An enum to specify the kernel source type. + * + */ +typedef enum { + QNN_GPU_KERNEL_SOURCE_TYPE_TEXT = 0, + QNN_GPU_KERNEL_SOURCE_TYPE_BINARY = 1, +} QnnGpu_KernelSourceType_t; + +/** + * @brief This enum defines QNN GPU kernel tuning options. + */ +typedef enum { + /// local work size tuning + QNN_GPU_KERNEL_TUNING_LOCAL_WORK_SIZE = 0, + QNN_GPU_KERNEL_TUNING_UNDEFINED = 0x7FFFFFFF +} QnnGpu_KernelTuningOption_t; + +/** + * @brief This struct provides local-work-size tuning configuration. + */ +typedef struct { + uint32_t minValue[3]; + uint32_t maxValue[3]; + uint32_t stepSize[3]; +} QnnGpu_KernelLocalWorkSizeTuning_t; + +/** + * @brief This struct provides QNN GPU kernel tuning configuration. + */ +typedef struct { + QnnGpu_KernelTuningOption_t option; + union UNNAMED { + QnnGpu_KernelLocalWorkSizeTuning_t lws; + }; +} QnnGpu_KernelTuningConfig_t; + +/** + * @brief A QNN GPU struct specifying a kernel. + */ +typedef struct { + /// Kernel source code or binary + const void* kernelSource; + /// Length of kernel source/binary in bytes + size_t sourceLength; + /// Type of kernel source + QnnGpu_KernelSourceType_t sourceType; + /// Null terminated build options string used for kernel compilation + const char* buildOptions; + /// Rank of the globalWorkSizes + size_t globalWorkDim; + /// Global work sizes used by enqueuing the kernel + size_t globalWorkSizes[3]; + /// Rank of the localWorkSizes + size_t localWorkDim; + /// Local work sizes used by enqueuing the kernel + size_t localWorkSizes[3]; + /// Null-terminated array of kernel arguments in the order they appear in the kernel function + QnnGpu_KernelArg_t** args; + /// Null terminated name of the kernel + const char* name; + /// If non-zero, kernel will be enqueued during execute even if it is static + uint32_t isDynamic; + /// Null-terminated array to provide kernel tuning configurations. + QnnGpu_KernelTuningConfig_t** tuningConfigs; + /// Reserved field, must be null + void* reserved; +} QnnGpu_Kernel_t; + +// clang-format off +/// QnnGpu_Kernel_t initializer macro +#define QNN_GPU_KERNEL_INIT \ + { \ + NULL, /*kernelSource*/ \ + 0u, /*sourceLength*/ \ + QNN_GPU_KERNEL_SOURCE_TYPE_TEXT, /*sourceType*/ \ + NULL, /*buildOptions*/ \ + 0u, /*globalWorkDim*/ \ + {0u}, /*globalWorkSizes*/ \ + 0u, /*localWorkDim*/ \ + {0u}, /*localWorkSizes*/ \ + NULL, /*args*/ \ + NULL, /*name*/ \ + 0u, /*isDynamic*/ \ + NULL, /*tuningConfigs*/ \ + NULL /*reserved*/ \ + } +// clang-format on + +/** + * @brief A QNN GPU struct specifying an operation. + */ +typedef struct _QnnOpPackage_OpImpl_t { + /// Null-terminated array of output claims + QnnGpu_OutputClaim_t** outputClaims; + /// Null-terminated array of tensor requests + QnnGpu_MemoryObject_t** memoryObjects; + /// Null-terminated array of kernels + QnnGpu_Kernel_t** kernels; +} QnnGpu_Operation_t; + +// clang-format off +/// QnnGpu_Operation_t initializer macro +#define QNN_GPU_OPERATION_INIT \ + { \ + NULL, /*outputClaims*/ \ + NULL, /*memoryObjects*/ \ + NULL, /*kernels*/ \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GenAiTransformer/QnnGenAiTransformerCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GenAiTransformer/QnnGenAiTransformerCommon.h new file mode 100755 index 0000000000000..3adb43819b8b3 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/GenAiTransformer/QnnGenAiTransformerCommon.h @@ -0,0 +1,50 @@ +//============================================================================= +// +// Copyright (c) 2024 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN GenAiTransformer Common components + * + * This file defines versioning and other identification details + * and supplements QnnCommon.h for GenAiTransformer backend + */ + +#ifndef QNN_GENAI_TRANSFORMER_COMMON_H +#define QNN_GENAI_TRANSFORMER_COMMON_H + +#include "QnnCommon.h" + +/// GenAiTransformer Backend identifier +#define QNN_BACKEND_ID_GENAI_TRANSFORMER 14 + +/// GenAiTransformer interface provider +#define QNN_GENAI_TRANSFORMER_INTERFACE_PROVIDER_NAME "GENAI_TRANSFORMER_QTI_AISW" + +// GenAiTransformer API Version values +#define QNN_GENAI_TRANSFORMER_API_VERSION_MAJOR 1 +#define QNN_GENAI_TRANSFORMER_API_VERSION_MINOR 0 +#define QNN_GENAI_TRANSFORMER_API_VERSION_PATCH 0 + +// clang-format off +/// Macro to set Qnn_ApiVersion_t for GENAI_TRANSFORMER backend +#define QNN_GENAI_TRANSFORMER_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_GENAI_TRANSFORMER_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_GENAI_TRANSFORMER_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_GENAI_TRANSFORMER_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +#endif // QNN_GENAI_TRANSFORMER_COMMON_H \ No newline at end of file diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaBackend.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaBackend.h new file mode 100755 index 0000000000000..e756b8042ec09 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaBackend.h @@ -0,0 +1,76 @@ +//============================================================================= +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTA component Backend API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnBackend.h for HTA backend + */ + +#ifndef QNN_HTA_BACKEND_H +#define QNN_HTA_BACKEND_H + +#include "QnnBackend.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +/* @brief Enum describing the set of features supported by HTA backend. + This is used as a bitmask, so assign unique bits to each entries. +*/ +typedef enum { + /// The accelerator will always attempt to fold relu activation + /// into the immediate preceding convolution operation. This optimization + /// is correct when quantization ranges for convolution are equal or + /// subset of the Relu operation. For graphs, where this cannot be + /// guranteed, the client should set this flag + QNN_HTA_FOLD_RELU_ACTIVATION_INTO_CONV_OFF = 1 << 0, + /// UNKNOWN enum event that must not be used + QNN_HTA_BACKEND_FEATURES_UNKNOWN = 0x7fffffff +} QnnHtaBackend_Features_t; + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +// clang-format off + +/** + * @brief Structure describing the set of configurations supported by the backend. + * Objects of this type are to be referenced through QnnBackend_CustomConfig_t. + */ +typedef struct { + /// field to save the features that are passed + /// via QnnHtaBackend_Features_t + uint32_t bitmaskFeatures; +} QnnHtaBackend_CustomConfig_t ; + +/// QnnHtaBackend_CustomConfig_t initializer macro +#define QNN_HTA_BACKEND_CUSTOM_CONFIG_INIT \ + { 0 /*bitmaskFeatures*/ } + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaCommon.h new file mode 100755 index 0000000000000..1eb8e1f0a99a4 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaCommon.h @@ -0,0 +1,62 @@ +//============================================================================= +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTA Common components + * + * This file defines versioning and other identification details + * and supplements QnnCommon.h for HTA backend + */ + +#ifndef QNN_HTA_COMMON_H +#define QNN_HTA_COMMON_H + +#include "QnnCommon.h" + +/// HTA Backend identifier +#define QNN_BACKEND_ID_HTA 7 + +/// HTA interface provider +#define QNN_HTA_INTERFACE_PROVIDER_NAME "HTA_QTI_AISW" + +// HTA API Version values + +#define QNN_HTA_API_VERSION_MAJOR 2 +#define QNN_HTA_API_VERSION_MINOR 0 +#define QNN_HTA_API_VERSION_PATCH 0 + +// clang-format off + +/// Macro to set Qnn_ApiVersion_t for HTA backend +#define QNN_HTA_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_HTA_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_HTA_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_HTA_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +// HTA Binary Version values +#define QNN_HTA_BINARY_VERSION_MAJOR 2 +#define QNN_HTA_BINARY_VERSION_MINOR 0 +#define QNN_HTA_BINARY_VERSION_PATCH 0 + +// HTA Context blob Version values +#define QNN_HTA_CONTEXT_BLOB_VERSION_MAJOR 1 +#define QNN_HTA_CONTEXT_BLOB_VERSION_MINOR 1 +#define QNN_HTA_CONTEXT_BLOB_VERSION_PATCH 0 + +#endif // QNN_HTA_COMMON_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaDevice.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaDevice.h new file mode 100755 index 0000000000000..d31f5232e21f3 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaDevice.h @@ -0,0 +1,41 @@ +//============================================================================= +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTA component Device API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnDevice.h for HTA backend + */ +#ifndef QNN_HTA_DEVICE_H +#define QNN_HTA_DEVICE_H + +#include "QnnDevice.h" +#include "QnnHtaPerfInfrastructure.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _QnnDevice_Infrastructure_t { + QnnHtaPerfInfrastructure_SetPowerConfigFn_t setPowerConfig; +} QnnHtaDevice_Infrastructure_t; + +// clang-format off +/// QnnHtaDevice_Infrastructure_t initializer macro +#define QNN_HTA_DEVICE_INFRASTRUCTURE_INIT \ + { \ + NULL, /*setPowerConfig*/ \ + } +// clang-format on + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif \ No newline at end of file diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaGraph.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaGraph.h new file mode 100755 index 0000000000000..0abbb9bc5114d --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaGraph.h @@ -0,0 +1,123 @@ +//============================================================================= +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTA component Graph API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnGraph.h for HTA backend + */ + +#ifndef QNN_HTA_GRAPH_H +#define QNN_HTA_GRAPH_H + +#include "QnnGraph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief This enum provides different HTA graph optimization + * options that can be used to finalize the graph + * for optimum performance + */ +typedef enum QnnHtaGraph_OptimizationType { + QNN_HTA_GRAPH_OPTIMIZATION_TYPE_SCHEDULE_THRESHOLD = 1, + QNN_HTA_GRAPH_OPTIMIZATION_TYPE_FINALIZE_RETRIES = 2, + QNN_HTA_GRAPH_OPTIMIZATION_TYPE_UNKNOWN = 0x7fffffff +} QnnHtaGraph_OptimizationType_t; + +/* @brief Struct describing the set of optimization type + * and the value associated with the optimization + */ +typedef struct QnnHtaGraph_OptimizationOption { + QnnHtaGraph_OptimizationType_t type; + float floatValue; +} QnnHtaGraph_OptimizationOption_t; + +// clang-format off +/// QnnHtaGraph_OptimizationOption_t initializer macro +#define QNN_HTA_GRAPH_OPTIMIZATION_OPTION_INIT \ + { \ + QNN_HTA_GRAPH_OPTIMIZATION_TYPE_UNKNOWN, /*type*/ \ + 0.0f /*floatValue*/ \ + } +// clang-format on + +/** + * @brief This enum provides different HTA graph configuration + * options associated with QnnGraph + */ +typedef enum QnnHtaGraph_ConfigOption { + QNN_HTA_GRAPH_CONFIG_OPTION_OPTIMIZATION = 1, + QNN_HTA_GRAPH_CONFIG_OPTION_PRIORITY = 2, + QNN_HTA_GRAPH_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnHtaGraph_ConfigOption_t; + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +// clang-format off + +/** + * @brief Structure describing the set of configurations supported by graph. + * Objects of this type are to be referenced through QnnGraph_CustomConfig_t. + * + * The struct has two fields - option and a union of corresponding config values + * Based on the option corresponding item in the union can be used to specify + * config + * Below is the Map between QnnHtaGraph_ConfigOption_t and config value + * + * \verbatim embed:rst:leading-asterisk + * +----+------------------------------------------+------------------------------------+ + * | # | Config Option | Configuration Struct/value | + * +====+==========================================+====================================+ + * | 1 | QNN_HTA_GRAPH_CONFIG_OPTION_OPTIMIZATION | QnnHtaGraph_OptimizationOption_t | + * +----+------------------------------------------+------------------------------------+ + * | 2 | QNN_HTA_GRAPH_CONFIG_OPTION_PRIORITY | Qnn_Priority_t | + * +----+------------------------------------------+------------------------------------+ + * \endverbatim + */ +typedef struct { + QnnHtaGraph_ConfigOption_t option; + union { + QnnHtaGraph_OptimizationOption_t optimizationOption; + Qnn_Priority_t priority; + }; +} QnnHtaGraph_CustomConfig_t ; + + +/// QnnHtaGraph_CustomConfig_t initalizer macro +#define QNN_HTA_GRAPH_CUSTOM_CONFIG_INIT \ + { \ + QNN_HTA_GRAPH_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + QNN_HTA_GRAPH_OPTIMIZATION_OPTION_INIT /*optimizationOption*/ \ + } \ + } + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaPerfInfrastructure.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaPerfInfrastructure.h new file mode 100755 index 0000000000000..4f6e0c22c274b --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaPerfInfrastructure.h @@ -0,0 +1,134 @@ +//============================================================================== +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** @file + * @brief QNN HTA component Performance Infrastructure API + * + * Provides interface to the client to control performance and system + * settings of the QNN HTA Accelerator + */ + +#ifndef QNN_HTA_PERF_INFRASTRUCTURE_H +#define QNN_HTA_PERF_INFRASTRUCTURE_H + +#include "QnnCommon.h" +#include "QnnTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief QNN HTA PerfInfrastructure API result / error codes. + * + */ +typedef enum { + QNN_HTA_PERF_INFRASTRUCTURE_MIN_ERROR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE, + //////////////////////////////////////////////////////////////////////// + + QNN_HTA_PERF_INFRASTRUCTURE_NO_ERROR = QNN_SUCCESS, + QNN_HTA_PERF_INFRASTRUCTURE_ERROR_INVALID_HANDLE_PTR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 0, + QNN_HTA_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 1, + QNN_HTA_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED_CONFIG = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 2, + QNN_HTA_PERF_INFRASTRUCTURE_ERROR_TRANSPORT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 3, + + //////////////////////////////////////////////////////////////////////// + QNN_HTA_PERF_INFRASTRUCTURE_MAX_ERROR = QNN_MAX_ERROR_PERF_INFRASTRUCTURE +} QnnHtaPerfInfrastructure_Error_t; + +/** + * @brief This enum defines all the possible performance + * options in Hta Performance Infrastructure that + * relate to setting up of power levels + */ +typedef enum { + /// config enum implies the usage of powerModeConfig struct. If not provided + /// will be used as type identificator + QNN_HTA_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_POWER_MODE = 1, + /// UNKNOWN config option which must not be used + QNN_HTA_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnHtaPerfInfrastructure_PowerConfigOption_t; + +/** + * @brief This enum defines all the possible power mode + * that a client can set + */ +typedef enum { + /// default mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_DEFAULT = 0, + /// low power saver mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_LOW_POWER_SAVER = 1, + /// power saver mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER = 2, + /// high power saver mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_HIGH_POWER_SAVER = 3, + /// balanced mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_BALANCED = 4, + /// high performance mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_HIGH_PERFORMANCE = 5, + /// burst mode + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_BURST = 6, + /// UNKNOWN value that must not be used by client + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_UNKNOWN = 0x7fffffff +} QnnHtaPerfInfrastructure_PowerMode_t; + +/** + * @brief This struct provides performance infrastructure configuration + * associated with setting up of power levels + */ +typedef struct { + QnnHtaPerfInfrastructure_PowerConfigOption_t config; + // Organize as union for future expand flexibility defined by PowerConfigOption_t + union { + QnnHtaPerfInfrastructure_PowerMode_t powerModeConfig; + }; +} QnnHtaPerfInfrastructure_PowerConfig_t; + +/// QnnHtaPerfInfrastructure_PowerConfig_t initializer macro +#define QNN_HTA_PERF_INFRASTRUCTURE_POWER_CONFIG_INIT \ + { \ + QNN_HTA_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + QNN_HTA_PERF_INFRASTRUCTURE_POWERMODE_UNKNOWN /*powerModeConfig*/ \ + } \ + } + +//============================================================================= +// API Methods +//============================================================================= + +/** + * @brief This API allows client to set up system power configuration that + * will enable different performance modes. + * + * @param[in] clientId A power client id to associate calls to system + * power settings. A value of 0 implies NULL power client id + * and can override every other setting the user process. To + * enable power settings for multiple clients in the same + * process, use a non-zero power client id. + * + * + * @param[in] config Pointer to a NULL terminated array + * of config option for performance configuration. + * NULL is allowed and indicates no config options are provided. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + */ +typedef Qnn_ErrorHandle_t (*QnnHtaPerfInfrastructure_SetPowerConfigFn_t)( + uint32_t clientId, const QnnHtaPerfInfrastructure_PowerConfig_t** config); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // QNN_HTA_PERF_INFRASTRUCTURE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaProfile.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaProfile.h new file mode 100755 index 0000000000000..f069dbbedf6b7 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTA/QnnHtaProfile.h @@ -0,0 +1,199 @@ +//============================================================================== +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief QNN HTA Profile component API. + * + * Requires HTA backend to be initialized. + * Should be used with the QnnProfile API but has HTA backend + * specific definition for different QnnProfile data structures + * + */ + +#ifndef QNN_HTA_PROFILE_H +#define QNN_HTA_PROFILE_H + +#include "QnnProfile.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary host time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_HOST_TIME_MICROSEC 1002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTA processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary HTA time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_HTA_TIME_MICROSEC 1003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to create the context on the + * accelerator when client invokes QnnContext_createFromBinary. + * The value returned is time in microseconds. + * + * @note context load binary accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_ACCEL_TIME_MICROSEC 1004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize host time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_FINALIZE_HOST_TIME_MICROSEC 2001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTA processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize HTA time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_FINALIZE_HTA_TIME_MICROSEC 2002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to finalize the graph on the accelerator + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_FINALIZE_ACCEL_TIME_MICROSEC 2003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute host time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_EXECUTE_HOST_TIME_MICROSEC 3001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTA processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute HTA time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_EXECUTE_HTA_TIME_MICROSEC 3002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is number of processor cycles taken. + * + * @note graph execute accelerator time maybe available only on + * QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE. + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_CYCLE 3003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time taken in microseconds + * + * @note graph execute accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE / QNN_PROFILE_EVENTUNIT_MICROSEC. + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_MICROSEC 3004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time taken for miscellaneous work i.e. time + * that cannot be attributed to a node but are still needed to + * execute the graph on the accelerator. This occurs when client invokes + * QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time taken in microseconds + * + * @note graph execute misc accelerator time is available only on + * QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_EXECUTE_MISC_ACCEL_TIME_MICROSEC 3005 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit host time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_DEINIT_HOST_TIME_MICROSEC 4001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTA processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit HTA time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_DEINIT_HTA_TIME_MICROSEC 4002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to deinit graph on the + * accelerator when client invokes QnnContext_free which in consequence + * deinit graph. The value returned is time in microseconds. + * + * @note graph deinit accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTA_PROFILE_EVENTTYPE_GRAPH_DEINIT_ACCEL_TIME_MICROSEC 4003 + +#ifdef __cplusplus +} +#endif + +#endif // QNN_HTA_PROFILE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpCommon.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpCommon.h new file mode 100755 index 0000000000000..8b1d458a04b8e --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpCommon.h @@ -0,0 +1,98 @@ +//============================================================================= +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTP Common components + * + * This file defines versioning and other identification details + * and supplements QnnCommon.h for HTP backend + */ + +#ifndef QNN_HTP_COMMON_H +#define QNN_HTP_COMMON_H + +#include "QnnCommon.h" + +/// HTP Backend identifier +#define QNN_BACKEND_ID_HTP 6 + +/// HTP interface provider +#define QNN_HTP_INTERFACE_PROVIDER_NAME "HTP_QTI_AISW" + +// HTP API Version values +#define QNN_HTP_API_VERSION_MAJOR 5 +#define QNN_HTP_API_VERSION_MINOR 34 +#define QNN_HTP_API_VERSION_PATCH 0 + +// clang-format off + +/// Macro to set Qnn_ApiVersion_t for HTP backend +#define QNN_HTP_API_VERSION_INIT \ + { \ + { \ + QNN_API_VERSION_MAJOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_MINOR, /*coreApiVersion.major*/ \ + QNN_API_VERSION_PATCH /*coreApiVersion.major*/ \ + }, \ + { \ + QNN_HTP_API_VERSION_MAJOR, /*backendApiVersion.major*/ \ + QNN_HTP_API_VERSION_MINOR, /*backendApiVersion.minor*/ \ + QNN_HTP_API_VERSION_PATCH /*backendApiVersion.patch*/ \ + } \ + } + +// clang-format on + +// DSP Context blob Version values +#define QNN_HTP_CONTEXT_BLOB_VERSION_MAJOR 3 +#define QNN_HTP_CONTEXT_BLOB_VERSION_MINOR 2 +#define QNN_HTP_CONTEXT_BLOB_VERSION_PATCH 3 + +/* ==== CDSP Security Library Versioning ==== */ +/* ==== This information is only intended for OEMs ==== */ + +/* Security versioning for DSP libraries is supported V73 onwards */ +#define QNN_HTP_NATIVE_LIB_SECURITY_VERSIONING_MIN_ARCH 73 + +/* Here we will define CDSP library versions for different targets + * Version is increased whenever there is a security fix from CDSP + * The versioning will start from 1.0.0 for each new target + * */ + +/* V73 Security Issues: + * List of security issues fixed for V73 and the fixed version + * */ +#define QNN_HTP_V73_NATIVE_LIB_SECURITY_VERSION_MAJOR 1 +#define QNN_HTP_V73_NATIVE_LIB_SECURITY_VERSION_MINOR 0 +#define QNN_HTP_V73_NATIVE_LIB_SECURITY_VERSION_PATCH 0 + +/* V75 Security Issues: + * List of security issues fixed for V75 and the fixed version + * */ +// HTP Native library version values for V75 +#define QNN_HTP_V75_NATIVE_LIB_SECURITY_VERSION_MAJOR 1 +#define QNN_HTP_V75_NATIVE_LIB_SECURITY_VERSION_MINOR 0 +#define QNN_HTP_V75_NATIVE_LIB_SECURITY_VERSION_PATCH 0 + +/* V79 Security Issues: + * List of security issues fixed for V79 and the fixed version + * */ +// HTP Native library version values for V79 +#define QNN_HTP_V79_NATIVE_LIB_SECURITY_VERSION_MAJOR 1 +#define QNN_HTP_V79_NATIVE_LIB_SECURITY_VERSION_MINOR 0 +#define QNN_HTP_V79_NATIVE_LIB_SECURITY_VERSION_PATCH 0 + +/* V81 Security Issues: + * List of security issues fixed for V81 and the fixed version + * */ +// HTP Native library version values for V81 +#define QNN_HTP_V81_NATIVE_LIB_SECURITY_VERSION_MAJOR 1 +#define QNN_HTP_V81_NATIVE_LIB_SECURITY_VERSION_MINOR 0 +#define QNN_HTP_V81_NATIVE_LIB_SECURITY_VERSION_PATCH 0 + +#endif // QNN_HTP_COMMON_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpContext.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpContext.h new file mode 100755 index 0000000000000..8266817e2dc41 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpContext.h @@ -0,0 +1,164 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc.s +// +//============================================================================== + +/** + * @file + * @brief QNN HTP component Context API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnContext.h for HTP backend + */ + +#ifndef QNN_HTP_CONTEXT_H +#define QNN_HTP_CONTEXT_H + +#include "QnnContext.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief This enum provides different HTP context configuration + * options associated with QnnContext + */ +typedef enum { + QNN_HTP_CONTEXT_CONFIG_OPTION_WEIGHT_SHARING_ENABLED = 1, + QNN_HTP_CONTEXT_CONFIG_OPTION_REGISTER_MULTI_CONTEXTS = 2, + QNN_HTP_CONTEXT_CONFIG_OPTION_FILE_READ_MEMORY_BUDGET = 3, + QNN_HTP_CONTEXT_CONFIG_OPTION_DSP_MEMORY_PROFILING_ENABLED = 4, + QNN_HTP_CONTEXT_CONFIG_OPTION_SHARE_RESOURCES = 5, + QNN_HTP_CONTEXT_CONFIG_OPTION_IO_MEM_ESTIMATION = 6, + QNN_HTP_CONTEXT_CONFIG_OPTION_PREPARE_ONLY = 7, + QNN_HTP_CONTEXT_CONFIG_OPTION_INIT_ACCELERATION = 8, + QNN_HTP_CONTEXT_CONFIG_OPTION_SKIP_VALIDATION_ON_BINARY_SECTION = 9, + QNN_HTP_CONTEXT_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnHtpContext_ConfigOption_t; + +typedef struct { + // Handle referring to the first context associated to a group. When a new + // group is to be registered, the following value must be 0. + Qnn_ContextHandle_t firstGroupHandle; + // Max spill-fill buffer to be allocated for the group of context in bytes. + // The value that is passed during the registration of the first context to + // a group is taken. Subsequent configuration of this value is disregarded. + uint64_t maxSpillFillBuffer; +} QnnHtpContext_GroupRegistration_t; + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +// clang-format off + +/** + * @brief Structure describing the set of configurations supported by context. + * Objects of this type are to be referenced through QnnContext_CustomConfig_t. + * + * The struct has two fields - option and a union of config values + * Based on the option corresponding item in the union can be used to specify + * config. + * + * Below is the Map between QnnHtpContext_CustomConfig_t and config value + * + * \verbatim embed:rst:leading-asterisk + * +----+---------------------------------------------------------------------+---------------------------------------+ + * | # | Config Option | Configuration Struct/value | + * +====+=====================================================================+=======================================+ + * | 1 | QNN_HTP_CONTEXT_CONFIG_OPTION_WEIGHT_SHARING_ENABLED | bool | + * +====+=====================================================================+=======================================+ + * | 2 | QNN_HTP_CONTEXT_CONFIG_OPTION_REGISTER_MULTI_CONTEXTS | QnnHtpContext_GroupRegistration_t | + * +====+=====================================================================+=======================================+ + * | 3 | QNN_HTP_CONTEXT_CONFIG_OPTION_FILE_READ_MEMORY_BUDGET | uint64_t | + * +====+=====================================================================+=======================================+ + * | 4 | QNN_HTP_CONTEXT_CONFIG_OPTION_DSP_MEMORY_PROFILING_ENABLED | bool | + * +====+=====================================================================+=======================================+ + * | 5 | QNN_HTP_CONTEXT_CONFIG_OPTION_SHARE_RESOURCES | bool | + * +----+---------------------------------------------------------------------+---------------------------------------+ + * | 6 | QNN_HTP_CONTEXT_CONFIG_OPTION_IO_MEM_ESTIMATION | bool | + * +----+---------------------------------------------------------------------+---------------------------------------+ + * | 7 | QNN_HTP_CONTEXT_CONFIG_OPTION_PREPARE_ONLY | bool | + * +----+---------------------------------------------------------------------+---------------------------------------+ + * | 8 | QNN_HTP_CONTEXT_CONFIG_OPTION_INIT_ACCELERATION | bool | + * +----+---------------------------------------------------------------------+---------------------------------------+ + * | 9 | QNN_HTP_CONTEXT_CONFIG_OPTION_SKIP_VALIDATION_ON_BINARY_SECTION | bool | + * +----+---------------------------------------------------------------------+---------------------------------------+ + * \endverbatim + */ +typedef struct QnnHtpContext_CustomConfig { + QnnHtpContext_ConfigOption_t option; + union UNNAMED { + // This field sets the weight sharing which is by default false + bool weightSharingEnabled; + QnnHtpContext_GroupRegistration_t groupRegistration; + // - Init time may be impacted depending the value set below + // - Value should be grather than 0 and less than or equal to the file size + // - If set to 0, the feature is not utilized + // - If set to greater than file size, min(fileSize, fileReadMemoryBudgetInMb) is used + // - As an example, if value 2 is passed, it would translate to (2 * 1024 * 1024) bytes + uint64_t fileReadMemoryBudgetInMb; + bool dspMemoryProfilingEnabled; + // This field enables resource sharing across different contexts, enhancing RAM and virtual + // address(VA) space utialization. When this flag is activated, graphs are expected to execute + // sequentially. Note that this configuration option is only supported when using the + // QnnContext_createFromBinaryListAsync API. + bool shareResources; + // This field enables I/O memory estimation during QnnContext_createFromBinary API when multiple + // PDs are available. When enabled, it estimates the total size of the I/O tensors required by + // the context to ensure sufficient space on the PD before deserialization. This feature helps + // with memory registration failures in large models. + // Note that enabling this feature increases peak RAM usage during context initialization phase + // in QnnContext_createFromBinary, but sustained RAM remains unaffected. + bool ioMemEstimation; + // This field enables model preparation without mapping its content on the DSP side. It is + // useful when a model needs to be prepared on the device but executed through a serialized + // binary method. This prevents extra mapping onto the DSP VA space. Set this flag only when + // creating the context. + bool isPrepareOnly; + // This field enables initialization acceleration, which is disabled by default. + // If set to true, the DSP will utilize all hardware threads to accelerate deserialization. + // It is not recommended to execute graphs simultaneously, as this will significantly degrade + // performance. + // Note that this feature may not be effective for small graphs with a few number of ops. + bool initAcceleration; + // This field enables crc32 check skip in Lora super adapter apply, which is disabled by default. + // If set to true, crc32 check for non-base adapter in super adapter apply use case will be + // skipped to improve time cost. + // Note that base adapter in super adaper never do crc32 check, therefore, their apply time cost + // won't improve by turning this config option on. + bool skipValidationOnBinarySection; + }; +} QnnHtpContext_CustomConfig_t; + +/// QnnHtpContext_CustomConfig_t initializer macro +#define QNN_HTP_CONTEXT_CUSTOM_CONFIG_INIT \ + { \ + QNN_HTP_CONTEXT_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + false /*weightsharing*/\ + } \ + } + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpDevice.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpDevice.h new file mode 100755 index 0000000000000..e70c23577264b --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpDevice.h @@ -0,0 +1,178 @@ +//============================================================================= +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** @file + * @brief QNN HTP Device components + * + * This file defines structures and supplements QnnDevice.h for QNN HTP device + */ + +#pragma once + +#include "QnnCommon.h" +#include "QnnDevice.h" +#include "QnnHtpPerfInfrastructure.h" +#include "QnnTypes.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This is used to represent the HTP hardware architecture + * Since QnnDevice only supports V68 or newer, using legacy ARCH will result in error + */ +typedef enum { + QNN_HTP_DEVICE_ARCH_NONE = 0, + QNN_HTP_DEVICE_ARCH_V68 = 68, + QNN_HTP_DEVICE_ARCH_V69 = 69, + QNN_HTP_DEVICE_ARCH_V73 = 73, + QNN_HTP_DEVICE_ARCH_V75 = 75, + QNN_HTP_DEVICE_ARCH_V79 = 79, + QNN_HTP_DEVICE_ARCH_V81 = 81, + QNN_HTP_DEVICE_ARCH_UNKNOWN = 0x7fffffff +} QnnHtpDevice_Arch_t; + +/** + * data struture to configure a device to set the minimum HTP Arch + * the driver will use ops that compatible to this HTP Arch + */ +typedef struct { + uint32_t deviceId; + QnnHtpDevice_Arch_t arch; +} QnnHtpDevice_Minimum_Arch_t; + +/** + * data struture to configure a device to running in Signed/unsigned Domain. + */ +typedef struct { + uint32_t deviceId; + bool useSignedProcessDomain; +} QnnHtpDevice_UseSignedProcessDomain_t; + +typedef void* QnnHtpDevice_UseCustomSetting_t; + +/** + * enum to list what custom configure is available. + */ +typedef enum { + QNN_HTP_DEVICE_CONFIG_OPTION_SOC = 0, + QNN_HTP_DEVICE_CONFIG_OPTION_ARCH = 1, + QNN_HTP_DEVICE_CONFIG_OPTION_SIGNEDPD = 2, + QNN_HTP_DEVICE_CONFIG_OPTION_CUSTOM = 3, + QNN_HTP_DEVICE_CONFIG_OPTION_RESERVED = 0x7fff0000, + QNN_HTP_DEVICE_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnHtpDevice_ConfigOption_t; + +/** + * Data structure for custom configure. + */ +typedef struct { + QnnHtpDevice_ConfigOption_t option; + union UNNAMED { + // This field set the SoC Model + uint32_t socModel; + // This field update the minimum HTP arch + QnnHtpDevice_Minimum_Arch_t arch; + // This structure is used for enable/disable Signed/unsigned PD + QnnHtpDevice_UseSignedProcessDomain_t useSignedProcessDomain; + // This structure is used for enable Custom setting + QnnHtpDevice_UseCustomSetting_t useCustomSetting; + // Reserved for internal purposes + void* reserved; + }; +} QnnHtpDevice_CustomConfig_t; + +// For deviceType in QnnDevice_HardwareDeviceInfoV1_t +typedef enum { + QNN_HTP_DEVICE_TYPE_ON_CHIP = 0, // HTP cores are inside SoC + QNN_HTP_DEVICE_TYPE_UNKNOWN = 0x7fffffff +} QnnHtpDevice_DeviceType_t; + +/** + * @brief QNN HTP Device core type + * This enumeration provides information about the core type inside the SOC. + * + * For online operation, the caller should retrieve this information from + * `QnnDevice_getPlatformInfo`. For offline operation, the caller needs to create a + * `QnnDevice_CoreInfo_t` with the correct core type, and then use it to create the + * `QnnDevice_PlatformInfo_t`. + */ +typedef enum { + QNN_HTP_CORE_TYPE_NSP = 0, + QNN_HTP_CORE_TYPE_HPASS = 1, + + // supported coreType are < QNN_CORE_TYPE_MAX + QNN_HTP_CORE_TYPE_MAX, + QNN_HTP_CORE_TYPE_UNKNOWN = 0x7fffffff +} QnnHtpDevice_CoreType_t; + +/** + * This structure provides info about the NSP device inside SoC + * For online operation, caller should get these info from QnnDevice_getPlatformInfo + * For offline operation, caller need to create this structure and filling the correct information + * for QnnDevice_create + */ +typedef struct { + size_t vtcmSize; // The VTCM for this device in Mega Byte + // user could not request VTCM size exceed this value + uint32_t socModel; // An enum value defined in Qnn Header that represent SoC model + bool signedPdSupport; // This field is true if the device supports Signed PD + bool dlbcSupport; // This field is true if the device supports DLBC + QnnHtpDevice_Arch_t arch; // This field shows the Architecture of this device +} QnnHtpDevice_OnChipDeviceInfoExtension_t; + +/** + * This structure is being used in QnnDevice_HardwareDeviceInfoV1_t + * QnnDevice_getPlatformInfo use this structure to list the supported device features/info + */ +typedef struct _QnnDevice_DeviceInfoExtension_t { + QnnHtpDevice_DeviceType_t devType; + union UNNAMED { + QnnHtpDevice_OnChipDeviceInfoExtension_t onChipDevice; + }; +} QnnHtpDevice_DeviceInfoExtension_t; + +/** + * @brief QNN HTP Device PerfInfrastructure specialization structure. + * Objects of this type are to be referenced through QnnDevice_getInfrastructure. + * + * Contains function pointers for each interface method for + * Htp PerfInfrastructure. + */ +typedef struct { + QnnHtpPerfInfrastructure_CreatePowerConfigIdFn_t createPowerConfigId; + QnnHtpPerfInfrastructure_DestroyPowerConfigIdFn_t destroyPowerConfigId; + QnnHtpPerfInfrastructure_SetPowerConfigFn_t setPowerConfig; + QnnHtpPerfInfrastructure_SetMemoryConfigFn_t setMemoryConfig; +} QnnHtpDevice_PerfInfrastructure_t; + +/// QnnHtpDevice_PerfInfrastructure_t initializer macro +#define QNN_HTP_DEVICE_PERF_INFRASTRUCTURE_INIT \ + { \ + NULL, /*createPowerConfigId*/ \ + NULL, /*destroyPowerConfigId*/ \ + NULL, /*setPowerConfig*/ \ + NULL /*setMemoryConfig*/ \ + } + +typedef enum { + QNN_HTP_DEVICE_INFRASTRUCTURE_TYPE_PERF = 0, + QNN_HTP_DEVICE_INFRASTRUCTURE_TYPE_UNKNOWN = 0x7fffffff +} QnnHtpDevice_InfrastructureType_t; + +typedef struct _QnnDevice_Infrastructure_t { + QnnHtpDevice_InfrastructureType_t infraType; + union UNNAMED { + QnnHtpDevice_PerfInfrastructure_t perfInfra; + }; +} QnnHtpDevice_Infrastructure_t; + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpGraph.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpGraph.h new file mode 100755 index 0000000000000..f7e49e9fb8bc3 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpGraph.h @@ -0,0 +1,299 @@ +//============================================================================= +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================= + +/** + * @file + * @brief QNN HTP component Graph API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnGraph.h for HTP backend + */ + +#ifndef QNN_HTP_GRAPH_H +#define QNN_HTP_GRAPH_H + +#include "QnnGraph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief QnnHtpGraph config value macro. Represents to use the maximum + * available number of the resource. + * + * Currently only applicable for QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE. + */ +#define QNN_HTP_GRAPH_CONFIG_OPTION_MAX 0 + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief This enum provides different HTP graph optimization + * options that can be used to finalize the graph + * for optimum performance. + */ +typedef enum { + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_SCHEDULE_THRESHOLD = 1, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_RETRIES = 2, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_OPTIMIZATION_FLAG = 3, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC = 4, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC_WEIGHTS = 5, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_SPARSE_WEIGHTS_COMPRESSION = 6, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_SLC_ALLOCATOR = 7, + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_UNKNOWN = 0x7fffffff +} QnnHtpGraph_OptimizationType_t; + +// clang-format off + +/** + * @brief Struct describing the set of optimization types + * and the values associated with each optimization type. + * + * Below is the Map between QnnHtpGraph_OptimizationType_t and allowable values: + * + * \verbatim embed:rst:leading-asterisk + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | # | OptimizationType option | Allowable values | + * +====+====================================================================+=====================================================================+ + * | 1 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_SCHEDULE_THRESHOLD | Reserved | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 2 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_RETRIES | Reserved | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 3 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_FINALIZE_OPTIMIZATION_FLAG | Defines the optimization strategy used by the HTP backend | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 4 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC | Reserved | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 5 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_DLBC_WEIGHTS | Enables DLBC weights compression | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 6 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_SPARSE_WEIGHTS_COMPRESSION | Enables Weight Sparsity Compression | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * | 7 | QNN_HTP_GRAPH_OPTIMIZATION_TYPE_ENABLE_SLC_ALLOCATOR | Enables System Level Cache Allocator usage | + * +----+--------------------------------------------------------------------+---------------------------------------------------------------------+ + * \endverbatim + */ +typedef struct { + QnnHtpGraph_OptimizationType_t type; + float floatValue; +} QnnHtpGraph_OptimizationOption_t; + +/** + * @brief This struct encapsulates all the VTCM configurations for parallel graph execution. + * + * @code + * |<-- (1) 8MB Total Hardware VTCM -->| + * |<-- (2) 7MB Addressable -->| + * +------+------+------+------+------+------+------+------+ + * | CV | | | | | | | | + * +------+------+------+------+------+------+------+------+ + * |<-- (4) Graph A -->|<-- (4) Graph B -->| + * + * A |> 0 MB (3) Graph Offset + * B |-------------------> 3 MB + * @endcode + */ +typedef struct { + /// (4) above, the amount of VTCM used by a graph + uint32_t sizeInBytes; + /// (3) above, where in the addressable region to start VTCM. + /// Note: (3) + (4) <= (2) + uint32_t offsetInBytes; + /// (2) Addressable portion of VTCM. + /// Set to less than hardware size so Graph(s) can coexist with other VTCM clients. + uint32_t sizeTotalInBytes; + + // For ABI compatibility in the future. + // Set to 0 for now. + uint32_t reserved[3]; +} QnnHtpGraph_VtcmConfig_t; + +/** + * @brief This enum defines whether graph concurrency (i.e. multiple graphs running concurrently) + * is possible, and how to behave when circumstances for concurrency aren't possible. + */ +typedef enum { + /// This graph will not be able to run concurrently with other graphs. + QNN_HTP_GRAPH_CONCURRENCY_OPTION_NONE = 0, + QNN_HTP_GRAPH_CONCURRENCY_OPTION_DEFAULT = QNN_HTP_GRAPH_CONCURRENCY_OPTION_NONE, + /// Graph will try to run concurrently, sharing all resources on the DSP (VTCM, HMX, HVX, etc). + QNN_HTP_GRAPH_CONCURRENCY_OPTION_ALL_SHARED = 1, + // Unused, present to ensure 32 bits. + QNN_HTP_GRAPH_CONCURRENCY_OPTION_UNKNOWN = 0x7fffffff +} QnnHtpGraph_ConcurrencyOption_t; + +/** + * @brief This struct encapsulates all the configurations for parallel graph execution. + */ +typedef struct { + QnnHtpGraph_ConcurrencyOption_t concurrency; + QnnHtpGraph_VtcmConfig_t vtcmConfig; + + // For ABI compatibility in the future. + // Set to 0 for now. + uint32_t reserved[4]; +} QnnHtpGraph_ParallelGraphExecutionConfig_t; +/// The settings in this struct is only applicable +/// for DSP architectures >= V81. +/// Use on other SOCs will return an error. +/// +/// Values will be defaulted to their SOC's TURBO frequency +/// (SOC as identified by Qnn_DeviceHandle_t). +/// +/// On automotive SDKs HMX OP Bounding will be enabled by default. +/// +/// On non-automotive SDKs using this setting will enable +/// HMX OP Bounding. It is off by default. +typedef struct QnnHtp_HmxBoundingInfo { + /// Target HMX freq in Hz. + /// Can be derived from sysMonApp (HexagonSDK) or QProfiler. + float targetHmxFreqHz; + /// Target DSP Core freq in Hz. + /// Can be derived from sysMonApp (HexagonSDK) or QProfiler. + float targetDspCoreFreq; +} QnnHtp_HmxBoundingInfo_t; + +/// QnnHtpGraph_OptimizationOption_t initializer macro +#define QNN_HTP_GRAPH_OPTIMIZATION_OPTION_INIT \ + { \ + QNN_HTP_GRAPH_OPTIMIZATION_TYPE_UNKNOWN, /*type*/ \ + 0.0f /*floatValue*/ \ + } +// clang-format on + +/** + * @brief This enum provides different HTP graph configuration + * options associated with QnnGraph + */ +typedef enum { + QNN_HTP_GRAPH_CONFIG_OPTION_OPTIMIZATION = 1, + QNN_HTP_GRAPH_CONFIG_OPTION_PRECISION = 2, + QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE_IN_MB = 3, + QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE = QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE_IN_MB, + QNN_HTP_GRAPH_CONFIG_OPTION_FOLD_RELU_ACTIVATION_INTO_CONV_OFF = 4, + QNN_HTP_GRAPH_CONFIG_OPTION_SHORT_DEPTH_CONV_ON_HMX_OFF = 5, + QNN_HTP_GRAPH_CONFIG_OPTION_NUM_HVX_THREADS = 6, + QNN_HTP_GRAPH_CONFIG_OPTION_FINALIZE_CONFIG = 7, + QNN_HTP_GRAPH_CONFIG_OPTION_NUM_CORES = 8, + QNN_HTP_GRAPH_CONFIG_OPTION_PARALLEL_GRAPH_EXECUTION_CONFIG = 9, + QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE_IN_BYTES = 10, + QNN_HTP_GRAPH_CONFIG_OPTION_HMX_BOUNDING = 11, + QNN_HTP_GRAPH_CONFIG_OPTION_WEIGHTS_PACKING = 12, + QNN_HTP_GRAPH_CONFIG_OPTION_ASSUME_SAME_QUANT = 13, + QNN_HTP_GRAPH_CONFIG_OPTION_RESERVED = 0x7fff0000, + QNN_HTP_GRAPH_CONFIG_OPTION_UNKNOWN = 0x7fffffff +} QnnHtpGraph_ConfigOption_t; + +//============================================================================= +// Public Functions +//============================================================================= + +//------------------------------------------------------------------------------ +// Implementation Definition +//------------------------------------------------------------------------------ + +/** + * @brief A struct for different config parameters in a key value format. + */ +typedef struct { + const char* key; + Qnn_Scalar_t value; +} QnnHtpGraph_FinalizeConfig_t; + +/** + * @brief Structure describing the set of configurations supported by graph. + * Objects of this type are to be referenced through QnnGraph_CustomConfig_t. + * + * The struct has two fields - option and a union of corresponding config values + * Based on the option corresponding item in the union can be used to specify + * config. + * + * Below is the Map between QnnHtpGraph_ConfigOption_t and config value + * + * \verbatim embed:rst:leading-asterisk + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | # | Config Option | Configuration Struct/value | + * +====+=====================================================================================+================================================+ + * | 1 | QNN_HTP_GRAPH_CONFIG_OPTION_OPTIMIZATION | QnnHtpGraph_OptimizationOption_t + * | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 2 | QNN_HTP_GRAPH_CONFIG_OPTION_PRECISION | Qnn_Precision_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 3 | + * QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE_IN_MB/QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE | uint32_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 4 | QNN_HTP_GRAPH_CONFIG_OPTION_FOLD_RELU_ACTIVATION_INTO_CONV_OFF | bool | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 5 | QNN_HTP_GRAPH_CONFIG_OPTION_SHORT_DEPTH_CONV_ON_HMX_OFF | bool | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 6 | QNN_HTP_GRAPH_CONFIG_OPTION_NUM_HVX_THREADS | uint32_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 7 | QNN_HTP_GRAPH_CONFIG_OPTION_FINALIZE_CONFIG | QnnHtpGraph_FinalizeConfig_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 8 | QNN_HTP_GRAPH_CONFIG_OPTION_NUM_CORES | uint32_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 9 | QNN_HTP_GRAPH_CONFIG_OPTION_PARALLEL_GRAPH_EXECUTION_CONFIG | + * QnnHtpGraph_ParallelGraphExecutionConfig_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 10 | QNN_HTP_GRAPH_CONFIG_OPTION_VTCM_SIZE_IN_BYTES | uint32_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 11 | QNN_HTP_GRAPH_CONFIG_OPTION_HMX_BOUNDING | uint32_t | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 12 | QNN_HTP_GRAPH_CONFIG_OPTION_WEIGHTS_PACKING | bool | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * | 13 | QNN_HTP_GRAPH_CONFIG_OPTION_ASSUME_SAME_QUANT | bool | + * +----+-------------------------------------------------------------------------------------+------------------------------------------------+ + * +-------------------------+----------------------------------------------------------------+------------------------------------------------+ + * | 0x7fff0000 - 0x7ffffffe | QNN_HTP_GRAPH_CONFIG_OPTION_RESERVED | These are + * reserved for internal purposes | + * +-------------------------+----------------------------------------------------------------+------------------------------------------------+ + * \endverbatim + * + * NOTE: Option #6 (i.e. QNN_HTP_GRAPH_CONFIG_OPTION_NUM_HVX_THREADS), can only be + * set prior to the first execution of the graph. Proceeding executions will not use + * the updated value if user does change it after the first execution. + */ +typedef struct { + QnnHtpGraph_ConfigOption_t option; + union { + QnnHtpGraph_OptimizationOption_t optimizationOption; + Qnn_Precision_t precision; + uint32_t vtcmSizeInMB; + bool foldReluActivationIntoConvOff; + bool shortDepthConvOnHmxOff; + uint64_t numHvxThreads; + void* reserved; + QnnHtpGraph_FinalizeConfig_t finalizeConfig; + uint32_t numCores; + QnnHtpGraph_ParallelGraphExecutionConfig_t parallelGraphExecutionConfig; + uint32_t vtcmSizeInBytes; + QnnHtp_HmxBoundingInfo_t hmxBoundingInfo; + bool weightsPacking; + bool assumeSameQuant; + }; +} QnnHtpGraph_CustomConfig_t; + +// clang-format on +/// QnnHtpGraph_CustomConfig_t initializer macro +#define QNN_HTP_GRAPH_CUSTOM_CONFIG_INIT \ + { \ + QNN_HTP_GRAPH_CONFIG_OPTION_UNKNOWN, /*option*/ \ + { \ + QNN_HTP_GRAPH_OPTIMIZATION_OPTION_INIT /*optimizationOption*/ \ + } \ + } + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpMem.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpMem.h new file mode 100755 index 0000000000000..adc9ef2c52504 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpMem.h @@ -0,0 +1,85 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef QNN_HTP_MEMORY_INFRASTRUCTURE_2_H +#define QNN_HTP_MEMORY_INFRASTRUCTURE_2_H + +#include "QnnCommon.h" + +/** + * @file + * @brief QNN HTP Memory Infrastructure component API. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// VTCM +//============================================================================= + +// clang-format off + +/** + * @brief Raw memory address that exists ONLY on the QURT + * side. + */ +typedef uint32_t QnnHtpMem_QurtAddress_t; + +/** + * @brief Configuration for custom shared buffer memory type + * This shared buffer is a contiguous chunk of memory identified + * by a single file descriptor which will be used by multiple tensors + * based on the offset provided + * Each QnnMem_register call with different offset will return a + * unique memory handle + */ +typedef struct { + // File descriptor for memory, must be set to QNN_MEM_INVALID_FD if not applicable + int32_t fd; + // Offset to be used in contiguous shared buffer + uint64_t offset; +} QnnHtpMem_SharedBufferConfig_t; + +// clang-format off + +/** + * @brief QNN Memory Type + */ +typedef enum { + QNN_HTP_MEM_QURT = 0, + QNN_HTP_MEM_SHARED_BUFFER = 1, + QNN_HTP_MEM_UNDEFINED = 0x7FFFFFFF +} QnnHtpMem_Type_t; + +// clang-format off + +/** + * @brief descriptor used for the QNN API + */ +typedef struct { + // Memory type identified by QnnHtpMem_Type_t + QnnHtpMem_Type_t type; + // Total size of the buffer + // For memory type QURT, it would be size of a tensor + // For memory type SHARED BUFFER, it would be the total size of the buffer + uint64_t size; + + union { + QnnHtpMem_QurtAddress_t qurtAddress; + QnnHtpMem_SharedBufferConfig_t sharedBufferConfig; + }; +} QnnMemHtp_Descriptor_t; + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpPerfInfrastructure.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpPerfInfrastructure.h new file mode 100755 index 0000000000000..f92317ac94bf2 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpPerfInfrastructure.h @@ -0,0 +1,511 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** @file + * @brief QNN HTP component Performance Infrastructure API + * + * Provides interface to the client to control performance and system + * settings of the QNN HTP Accelerator + */ + +#ifndef QNN_HTP_PERF_INFRASTRUCTURE_H +#define QNN_HTP_PERF_INFRASTRUCTURE_H + +#include "QnnCommon.h" +#include "QnnTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// max rpc polling time allowed - 9999 us +#define QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIG_MAX_RPC_POLLING_TIME 9999 + +//============================================================================= +// Data Types +//============================================================================= + +/** + * @brief QNN HTP PerfInfrastructure API result / error codes. + * + */ +typedef enum { + QNN_HTP_PERF_INFRASTRUCTURE_MIN_ERROR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE, + //////////////////////////////////////////////////////////////////////// + + QNN_HTP_PERF_INFRASTRUCTURE_NO_ERROR = QNN_SUCCESS, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_HANDLE_PTR = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 0, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 1, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED_CONFIG = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 2, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_TRANSPORT = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 3, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_UNSUPPORTED = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 4, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_MEM_ALLOC = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 5, + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_FAILED = QNN_MIN_ERROR_PERF_INFRASTRUCTURE + 6, + + //////////////////////////////////////////////////////////////////////// + QNN_HTP_PERF_INFRASTRUCTURE_MAX_ERROR = QNN_MAX_ERROR_PERF_INFRASTRUCTURE, + /// UNDEFINED value that must not be used by client + QNN_HTP_PERF_INFRASTRUCTURE_ERROR_UNDEFINED = 0x7fffffff +} QnnHtpPerfInfrastructure_Error_t; + +/** + * @brief Allows client to consider (non-zero value) DCVS enable/disable + * and option parameters, otherwise (zero value) + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SetDcvsEnable_t; + +/** + * @brief Allows client to start (non-zero value) or stop (zero value) + * participating in DCVS + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_DcvsEnable_t; + +/** + * @brief Allows client to consider (non-zero value) latency parameter, + * otherwise (zero value) + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SetSleepLatency_t; + +/** + * @brief Allows client to set up the sleep latency in microseconds + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SleepLatency_t; + +/** + * @brief Allows client to consider (non-zero value) sleep disable + * parameter, otherwise (zero value) + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SetSleepDisable_t; + +/** + * @brief Allows client to disable sleep or low power modes. + * Pass a non-zero value to disable sleep in HTP + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SleepDisable_t; + +/** + * @brief Allows client to consider (non-zero value) bus clock + * params, otherwise (zero value) + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SetBusParams_t; + +/** + * @brief Allows client consider (non-zero value) core clock + * params, otherwise (zero value) + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_SetCoreParams_t; + +/** + * @brief Allows client to set up the RPC control latency in microseconds + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_RpcControlLatency_t; + +/** + * @brief Allows client to set up the RPC polling time in microseconds + */ +typedef uint32_t QnnHtpPerfInfrastructure_RpcPollingTime_t; + +/** + * @brief Allows client to set up the adaptive polling time in microseconds + */ +typedef uint32_t QnnHtpPerfInfrastructure_AdaptivePollingTime_t; + +/** + * @brief Allows client to set up the HMX timeout interval in microseconds + */ +typedef uint32_t QnnHtpPerfInfrastructure_HmxTimeoutIntervalUs_t; + +/** + * @brief sets the minimum size by which user heap should grow + * when heap is exhausted. This API is expected to be + * called only once per backend and has a process wide impact + * + * Grow size provided in bytes and defaults to 16MB + */ +typedef uint32_t QnnHtpPerfInfrastructure_MemGrowSize_t; + +/** + * @brief Allows client to set default values for HMX frequency. + * If enabled 1 HMX vote will scale with DCVS Corner if 0 HMX vote + * needs to be specified manually. + * + */ +typedef uint32_t QnnHtpPerfInfrastructure_HmxDefault_Vote_t; + +/** + * @brief Perf modes to specify clock frequency level within + * target voltage corner currently applies only for HMX config. + */ +typedef enum { + // To select max frequency at target voltage corner. + QNN_HTP_PERF_INFRASTRUCTURE_CLK_PERF_HIGH = 0, + // To select min frequency at target voltage corner. + QNN_HTP_PERF_INFRASTRUCTURE_CLK_PERF_LOW, + /// UNKNOWN value that must not be used by client + QNN_HTP_PERF_INFRASTRUCTURE_CLK_PERF_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_ClkPerfMode_t; + +/** + * @brief These are the different voltage corners that can + * be requested by the client to influence the voting scheme + * for DCVS + * + */ +typedef enum { + /// Maps to HAP_DCVS_VCORNER_DISABLE. + /// Disable setting up voltage corner + DCVS_VOLTAGE_CORNER_DISABLE = 0x10, + /// Maps to HAP_DCVS_VCORNER_SVS2. + /// Set voltage corner to minimum value supported on platform + DCVS_VOLTAGE_VCORNER_MIN_VOLTAGE_CORNER = 0x20, + /// Maps to HAP_DCVS_VCORNER_SVS2. + /// Set voltage corner to SVS2 value for the platform + DCVS_VOLTAGE_VCORNER_SVS2 = 0x30, + /// Maps to HAP_DCVS_VCORNER_SVS. + /// Set voltage corner to SVS value for the platform + DCVS_VOLTAGE_VCORNER_SVS = 0x40, + /// Maps to HAP_DCVS_VCORNER_SVS_PLUS. + /// Set voltage corner to SVS_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_SVS_PLUS = 0x50, + /// Maps to HAP_DCVS_VCORNER_NOM. + /// Set voltage corner to NOMINAL value for the platform + DCVS_VOLTAGE_VCORNER_NOM = 0x60, + /// Maps to HAP_DCVS_VCORNER_NOM_PLUS. + /// Set voltage corner to NOMINAL_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_NOM_PLUS = 0x70, + /// Maps to HAP_DCVS_VCORNER_TURBO. + /// Set voltage corner to TURBO value for the platform + DCVS_VOLTAGE_VCORNER_TURBO = 0x80, + /// Maps to HAP_DCVS_VCORNER_TURBO_PLUS. + /// Set voltage corner to TURBO_PLUS value for the platform + DCVS_VOLTAGE_VCORNER_TURBO_PLUS = 0x90, + /// Maps to HAP_DCVS_VCORNER_TURBO_L2. + /// Set voltage corner to TURBO_L2 value for the platform + DCVS_VOLTAGE_VCORNER_TURBO_L2 = 0x92, + /// Maps to HAP_DCVS_VCORNER_TURBO_L3. + /// Set voltage corner to TURBO_L3 value for the platform + DCVS_VOLTAGE_VCORNER_TURBO_L3 = 0x93, + /// Maps to HAP_DCVS_VCORNER_MAX. + /// Set voltage corner to maximum value supported on the platform + DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER = 0xA0, + /// UNKNOWN value that must not be used by client + DCVS_VOLTAGE_VCORNER_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_VoltageCorner_t; + +/** + * @brief These are the expanded voltage corners that can + * be requested by the client to influence the voting scheme + * for DCVS + * + */ +typedef enum { + /// Maps to HAP_DCVS_EXP_VCORNER_DISABLE. + /// Disable setting up voltage corner + DCVS_EXP_VCORNER_DISABLE = 0, + /// Maps to HAP_DCVS_EXP_VCORNER_MIN. + /// Set voltage corner to minimum value supported on platform + DCVS_EXP_VCORNER_MIN = 0x100, + /// Maps to HAP_DCVS_EXP_VCORNER_LOW_SVS_D2. + /// Set voltage corner to LOWSVS_D2 value for the platform + DCVS_EXP_VCORNER_LOW_SVS_D2 = 0x134, + /// Maps to HAP_DCVS_EXP_VCORNER_LOW_SVS_D1. + /// Set voltage corner to LOWSVS_D1 value for the platform + DCVS_EXP_VCORNER_LOW_SVS_D1 = 0x138, + /// Maps to HAP_DCVS_EXP_VCORNER_LOW_SVS. + /// Set voltage corner to LOWSVS value for the platform + DCVS_EXP_VCORNER_LOW_SVS = 0x140, + /// Maps to HAP_DCVS_EXP_VCORNER_SVS. + /// Set voltage corner to SVS value for the platform + DCVS_EXP_VCORNER_SVS = 0x180, + /// Maps to HAP_DCVS_EXP_VCORNER_SVS_L1. + /// Set voltage corner to SVS_L1 value for the platform + DCVS_EXP_VCORNER_SVS_L1 = 0x1C0, + /// Maps to HAP_DCVS_EXP_VCORNER_NOM. + /// Set voltage corner to NOM value for the platform + DCVS_EXP_VCORNER_NOM = 0x200, + /// Maps to HAP_DCVS_EXP_VCORNER_NOM_L1. + /// Set voltage corner to NOM_L1 value for the platform + DCVS_EXP_VCORNER_NOM_L1 = 0x240, + /// Maps to HAP_DCVS_EXP_VCORNER_TUR. + /// Set voltage corner to TURBO value for the platform + DCVS_EXP_VCORNER_TUR = 0x280, + /// Maps to HAP_DCVS_EXP_VCORNER_TUR_L1. + /// Set voltage corner to TURBO_L1 value for the platform + DCVS_EXP_VCORNER_TUR_L1 = 0x2A0, + /// Maps to HAP_DCVS_EXP_VCORNER_TUR_L2. + /// Set voltage corner to TURBO_L2 value for the platform + DCVS_EXP_VCORNER_TUR_L2 = 0x2B0, + /// Maps to HAP_DCVS_EXP_VCORNER_TUR_L3. + /// Set voltage corner to TURBO_L3 value for the platform + DCVS_EXP_VCORNER_TUR_L3 = 0x2C0, + /// Maps to HAP_DCVS_EXP_VCORNER_MAX. + /// Selects the maximum voltage corner defined for the chipset + DCVS_EXP_VCORNER_MAX = 0xFFFF, + /// UNKNOWN value that must not be used by client + DCVS_EXP_VCORNER_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_ExpVoltageCorner_t; + +/** + * @brief This enum defines all the possible power mode + * that a client can set to influence DCVS mode + */ +typedef enum { + /// Maps to HAP_DCVS_V2_ADJUST_UP_DOWN. + /// Allows for DCVS to adjust up and down + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_ADJUST_UP_DOWN = 0x1, + /// Maps to HAP_DCVS_V2_ADJUST_ONLY_UP. + /// Allows for DCVS to adjust up only + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_ADJUST_ONLY_UP = 0x2, + /// Maps to HAP_DCVS_V2_POWER_SAVER_MODE. + /// Higher thresholds for power efficiency + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER_MODE = 0x4, + /// Maps to HAP_DCVS_V2_POWER_SAVER_AGGRESSIVE_MODE. + /// Higher thresholds for power efficiency with faster ramp down + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER_AGGRESSIVE_MODE = 0x8, + /// Maps to HAP_DCVS_V2_PERFORMANCE_MODE. + /// Lower thresholds for maximum performance + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_PERFORMANCE_MODE = 0x10, + /// Maps to HAP_DCVS_V2_DUTY_CYCLE_MODE. + /// The below value applies only for HVX clients: + /// - For streaming class clients: + /// - detects periodicity based on HVX usage + /// - lowers clocks in the no HVX activity region of each period. + /// - For compute class clients: + /// - Lowers clocks on no HVX activity detects and brings clocks up on detecting HVX activity + /// again. + /// - Latency involved in bringing up the clock will be at max 1 to 2 ms. + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_DUTY_CYCLE_MODE = 0x20, + /// UNKNOWN value that must not be used by client + QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_PowerMode_t; + +/** + * @brief This struct provides performance infrastructure configuration + * associated with setting up of DcvsV3 which allows to select + * bus and core operating corners separately + */ +typedef struct { + uint32_t contextId; + QnnHtpPerfInfrastructure_SetDcvsEnable_t setDcvsEnable; + QnnHtpPerfInfrastructure_DcvsEnable_t dcvsEnable; + QnnHtpPerfInfrastructure_PowerMode_t powerMode; + QnnHtpPerfInfrastructure_SetSleepLatency_t setSleepLatency; + QnnHtpPerfInfrastructure_SleepLatency_t sleepLatency; + QnnHtpPerfInfrastructure_SetSleepDisable_t setSleepDisable; + QnnHtpPerfInfrastructure_SleepDisable_t sleepDisable; + QnnHtpPerfInfrastructure_SetBusParams_t setBusParams; + QnnHtpPerfInfrastructure_VoltageCorner_t busVoltageCornerMin; + QnnHtpPerfInfrastructure_VoltageCorner_t busVoltageCornerTarget; + QnnHtpPerfInfrastructure_VoltageCorner_t busVoltageCornerMax; + QnnHtpPerfInfrastructure_SetCoreParams_t setCoreParams; + QnnHtpPerfInfrastructure_VoltageCorner_t coreVoltageCornerMin; + QnnHtpPerfInfrastructure_VoltageCorner_t coreVoltageCornerTarget; + QnnHtpPerfInfrastructure_VoltageCorner_t coreVoltageCornerMax; +} QnnHtpPerfInfrastructure_DcvsV3_t; + +/** + * @brief This struct provides performance infrastructure configuration + * associated with setting up of hmxv2 which allows to select + * hmx corner separately. If hmxPickDefault is 1 all voltage corner + * params will be ignored. Ensure to use same contextID as used for + * DCVS vote. + */ +typedef struct { + QnnHtpPerfInfrastructure_HmxDefault_Vote_t hmxPickDefault; + QnnHtpPerfInfrastructure_ExpVoltageCorner_t hmxVoltageCornerMin; + QnnHtpPerfInfrastructure_ExpVoltageCorner_t hmxVoltageCornerTarget; + QnnHtpPerfInfrastructure_ExpVoltageCorner_t hmxVoltageCornerMax; + QnnHtpPerfInfrastructure_ClkPerfMode_t hmxPerfMode; +} QnnHtpPerfInfrastructure_HmxV2_t; + +/** + * @brief This enum defines all the possible performance + * options in Htp Performance Infrastructure that + * relate to setting up of power levels + */ +typedef enum { + /// config enum implies the usage of Dcvs v3 + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_V3 = 1, + /// config enum implies the usage of rpcControlLatencyConfig struct + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_CONTROL_LATENCY = 2, + /// config enum implies the usage of rpcPollingTimeConfig struct + /// this config is only supported on V69 and later + /// if enabled, this config is applied to entire process + /// max allowed is QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIG_MAX_RPC_POLLING_TIME us + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_POLLING_TIME = 3, + /// config HMX timeout interval in us. The HMX is turned off after the set interval + /// time if no interaction with it after an inference is finished. + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_HMX_TIMEOUT_INTERVAL_US = 4, + /// config HMX V2 voting parameters only on supported chips + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_HMX_V2 = 5, + /// config enum implies the usage of adaptivePollingTime struct + /// this config can only be enabled in the RPC polling mode + /// if enabled, this config is applied to the entire process + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_ADAPTIVE_POLLING_TIME = 6, + /// UNKNOWN config option which must not be used + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_PowerConfigOption_t; + +/** + * @brief This struct provides performance infrastructure configuration + * associated with setting up of power levels + */ +typedef struct { + QnnHtpPerfInfrastructure_PowerConfigOption_t option; + union UNNAMED { + QnnHtpPerfInfrastructure_DcvsV3_t dcvsV3Config; + QnnHtpPerfInfrastructure_RpcControlLatency_t rpcControlLatencyConfig; + QnnHtpPerfInfrastructure_RpcPollingTime_t rpcPollingTimeConfig; + QnnHtpPerfInfrastructure_HmxTimeoutIntervalUs_t hmxTimeoutIntervalUsConfig; + QnnHtpPerfInfrastructure_HmxV2_t hmxV2Config; + QnnHtpPerfInfrastructure_AdaptivePollingTime_t adaptivePollingTimeConfig; + }; +} QnnHtpPerfInfrastructure_PowerConfig_t; + +/// QnnHtpPerfInfrastructure_PowerConfig_t initializer macro +#define QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIG_INIT \ + { \ + QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + 0 /*dcvsV3Config*/ \ + } \ + } + +/** + * @brief This enum defines all the possible performance + * options in Htp Performance Infrastructure that + * relate to system memory settings + */ +typedef enum { + /// sets memory grow size + QNN_HTP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_GROW_SIZE = 1, + /// UNKNOWN config option that must not be used + QNN_HTP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_UNKNOWN = 0x7fffffff +} QnnHtpPerfInfrastructure_MemoryConfigOption_t; + +/** + * @brief Provides performance infrastructure configuration + * options that are memory specific + */ +typedef struct { + QnnHtpPerfInfrastructure_MemoryConfigOption_t option; + union UNNAMED { + QnnHtpPerfInfrastructure_MemGrowSize_t memGrowSizeConfig; + }; +} QnnHtpPerfInfrastructure_MemoryConfig_t; + +/// QnnHtpPerfInfrastructure_MemoryConfig_t initializer macro +#define QNN_HTP_PERF_INFRASTRUCTURE_MEMORY_CONFIG_INIT \ + { \ + QNN_HTP_PERF_INFRASTRUCTURE_MEMORY_CONFIGOPTION_UNKNOWN, /*config*/ \ + { \ + 0 /*memGrowSizeConfig*/ \ + } \ + } + +//============================================================================= +// API Methods +//============================================================================= + +/** + * @brief This API allows client to create power configuration id that + * has to be used to set different performance modes. + * Power configuration id has to be destroyed by client when not needed. + * + * @param[in] deviceId Hardware Device on which this config id needs to be created. + * + * @param[in] coreId Core/NSP on which this config id needs to be created. + * + * @param[out] powerConfigId Pointer to power configuration id to be created. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if deviceId/coreId + * or power configuration id is NULL + */ +typedef Qnn_ErrorHandle_t (*QnnHtpPerfInfrastructure_CreatePowerConfigIdFn_t)( + uint32_t deviceId, uint32_t coreId, uint32_t* powerConfigId); + +/** + * @brief This API allows client to destroy power configuration id. + * + * @param[in] powerConfigId A power configuration id to be destroyed. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if power configuration + * id does not exist + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION: SSR occurence (successful recovery) + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION_FATAL: SSR occurence (unsuccessful recovery) + */ +typedef Qnn_ErrorHandle_t (*QnnHtpPerfInfrastructure_DestroyPowerConfigIdFn_t)( + uint32_t powerConfigId); + +/** + * @brief This API allows client to set up system power configuration that + * will enable different performance modes. This API uses + * HAP_power_dcvs_v3_payload struct to config HAP power parameters. + * Detailed HAP power parameters description please refer to Hexagon + * SDK HAP_power_dcvs_v3_payload documentation. + * + * @param[in] powerConfigId A power client id to associate calls to system + * power settings. A value of 0 implies NULL power client id + * and can override every other setting the user process. To + * enable power settings for multiple clients in the same + * process, use a non-zero power client id. + * + * @param[in] config Pointer to a NULL terminated array + * of config option for performance configuration. + * NULL is allowed and indicates no config options are provided. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if power configuration + * does not exist + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION: SSR occurence (successful recovery) + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION_FATAL: SSR occurence (unsuccessful recovery) + */ +typedef Qnn_ErrorHandle_t (*QnnHtpPerfInfrastructure_SetPowerConfigFn_t)( + uint32_t powerConfigId, const QnnHtpPerfInfrastructure_PowerConfig_t** config); + +/** + * @brief This API allows clients to set up configuration associated with + * system memory on a specific device + * + * @param[in] deviceId Hardware Device on which this config needs to be applied. + * + * @param[in] coreId Core/NSP on which this config needs to be applied. + * + * @param[in] config Pointer to a NULL terminated array + * of config option for system memory configuration. + * NULL is allowed and indicates no config options are provided. + * + * @return Error code + * \n QNN_SUCCESS: No error encountered + * \n QNN_HTP_PERF_INFRASTRUCTURE_ERROR_INVALID_INPUT if deviceId/coreId + * or memory configuration does not exist + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION: SSR occurence (successful recovery) + * \n QNN_COMMON_ERROR_SYSTEM_COMMUNICATION_FATAL: SSR occurence (unsuccessful recovery) + */ +typedef Qnn_ErrorHandle_t (*QnnHtpPerfInfrastructure_SetMemoryConfigFn_t)( + uint32_t deviceId, uint32_t coreId, const QnnHtpPerfInfrastructure_MemoryConfig_t** config); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // QNN_HTP_PERF_INFRASTRUCTURE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProfile.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProfile.h new file mode 100755 index 0000000000000..92381d17b0440 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProfile.h @@ -0,0 +1,567 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief QNN HTP Profile component API. + * + * Requires HTP backend to be initialized. + * Should be used with the QnnProfile API but has HTP backend + * specific definition for different QnnProfile data structures + * + */ + +#ifndef QNN_HTP_PROFILE_H +#define QNN_HTP_PROFILE_H + +#include "QnnProfile.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_HOST_RPC_TIME_MICROSEC 1002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTP processor + * when client invokes QnnContext_createFromBinary. The value + * returned is time in microseconds. + * + * @note context load binary htp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_HTP_RPC_TIME_MICROSEC 1003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to create the context on the + * accelerator when client invokes QnnContext_createFromBinary. + * The value returned is time in microseconds. + * + * @note context load binary accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_CONTEXT_LOAD_BIN_ACCEL_TIME_MICROSEC 1004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_HOST_RPC_TIME_MICROSEC 2001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTP processor + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize htp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_HTP_RPC_TIME_MICROSEC 2002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to finalize the graph on the accelerator + * when client invokes QnnGraph_finalize. + * The value returned is time in microseconds. + * + * @note graph finalize accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_ACCEL_TIME_MICROSEC 2003 + +/* Graph Performance Estimate Support + * + **/ +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to Performance Estimates for the graph + * when client invokes QnnGraph_finalize. + * This is just a dummy event which will print only the heading + * with no value or unit. + * @note HTP Performance Estimates maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE 2004 + +/** + * @brief QnnProfile_EventType_t definition to get perf mode at which + * the perf estimates are collected during QnnGraph_finalize. + * The value returned is the perf mode in string with no unit. + * + * @note Perf mode maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_MODE 2005 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to simulated execution cycles during + * QnnGraph_finalize. + * The value returned is number of cycles. + * + * @note Simulated execution cycles maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_SIM_EXEC_CYCLES 2006 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to a lower estimate of simulated execution + * cycles during QnnGraph_finalize. + * The value returned is number of cycles. + * + * @note Simulated execution cycles lower estimate maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_SIM_EXEC_LOWER_CYCLES 2007 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to a upper estimate of simulated execution + * cycles during QnnGraph_finalize. + * The value returned is number of cycles. + * + * @note Simulated execution cycles upper estimate maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_SIM_EXEC_UPPER_CYCLES 2008 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to DDR information for each HTP during + * QnnGraph_finalize. + * This is just a dummy event which will print only the heading + * with no value or unit. + * + * @note DDR Information for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_BANDWIDTH_STATS 2009 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the HTP ID on chip during QnnGraph_finalize. + * The value returned is the HTP ID with no unit. + * + * @note HTP ID's maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_BANDWIDTH_STATS_HTP_ID 2010 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the Graph defined inputs or the total reads + * (in bytes) from DDR for graph input related tensors (weights, + * bias, activations) which do not have predecessors. + * The value returned is the num of blocks in bytes. + * + * @note Graph defined inputs for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_INPUT_FILL 2011 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total reads (in bytes) from DDR for + * compiler generated fill operators which have predecessors and + * successors and originate on the same HTP. + * The value returned is the num of blocks in bytes. + * + * @note Intermediate Fill Information for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_INTERMEDIATE_FILL 2012 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total writes (in bytes) from DDR for + * compiler generated fill operators which have predecessors and + * successors and originate on the same HTP. + * The value returned is the num of blocks in bytes. + * + * @note Intermediate Spill Information for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_INTERMEDIATE_SPILL 2013 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total reads (in bytes) from DDR for + * fills which were generated by a different HTP core and do not + * have a predecessor, but have a successor. + * The value returned is the num of blocks in bytes. + * + * @note Inter HTP Fill Information for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_INTER_HTP_FILL 2014 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total writes (in bytes) from DDR for + * fills which were generated by a different HTP core and do not + * have a successor, but have a predecessor. + * The value returned is the num of blocks in bytes. + * + * @note Inter HTP Spill Information for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_INTER_HTP_SPILL 2015 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total writes (in bytes) to DDR for + * graph output related tensors which do not have successors. + * The value returned is the num of blocks in bytes. + * + * @note Graph output related tensors for each HTP maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_OUTPUT_SPILL 2016 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the total number of missing ops which do + * not have any cost associated with them while getting the graph + * performance estimates. + * The value returned is the num of missing ops with no unit. + * + * @note Number of missing cost ops maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_MISSING_COST_OPS 2017 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the op ids of the missing ops which do + * not have any cost associated with them while getting the graph + * performance estimates. + * The value returned is the opname along with the op id (decimal + * format) of the ops which does not have any costs associated + * with them. + * + * @note Opname and Op ids of missing cost ops are available only with + * QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_FINALIZE_PERF_ESTIMATE_MISSING_COST_OPID 2018 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_HOST_RPC_TIME_MICROSEC 3001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTP processor + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time in microseconds. + * + * @note graph execute htp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_HTP_RPC_TIME_MICROSEC 3002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is number of processor cycles taken. + * + * @note graph execute accelerator time maybe available only on + * QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE. + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_CYCLE 3003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value indicates execute including wait/resource acquisition + * time on the accelerator, if applicable in multi-threaded scenarios. + * The value returned is time taken in microseconds + * + * @note graph execute accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE / QNN_PROFILE_EVENTUNIT_MICROSEC + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_TIME_MICROSEC 3004 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time taken for miscellaneous work i.e. time + * that cannot be attributed to a node but are still needed to + * execute the graph on the accelerator. This occurs when client invokes + * QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is time taken in microseconds + * + * @note graph execute misc accelerator time is available only on + * QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_MISC_ACCEL_TIME_MICROSEC 3005 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time taken for a graph yield instance to + * release all its resources to the other graph. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_RELEASE_TIME 3006 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time a graph spends waiting for a higher + * priority graph to finish execution. + * The value returned is time taken in microseconds + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_WAIT_TIME 3007 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to time a graph spends re-acquiring resources + * and restoring vtcm. + * The value returned is time taken in microseconds + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_INSTANCE_RESTORE_TIME 3008 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the number of times that a yield occured + * during execution + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_YIELD_COUNT 3009 + +/** + * @brief QnnProfile_EventType_t definition for time a graph waits to get + * VTCM. This should be constant UNLESS we need another graph to yield. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_VTCM_ACQUIRE_TIME 3010 + +/** + * @brief QnnProfile_EventType_t definition for time a graph waits to get + * HMX + HVX, and turn them all on. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_RESOURCE_POWER_UP_TIME 3011 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value indicates execute excluding wait/resource acquisition + * time on the accelerator, if applicable in multi-threaded scenarios. + * The value returned is time taken in microseconds + * + * @note graph execute accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + * + * @note When QNN_PROFILE_LEVEL_DETAILED is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE / QNN_PROFILE_EVENTUNIT_MICROSEC + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_ACCEL_EXCL_WAIT_TIME_MICROSEC 3012 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the ARM processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit host rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_DEINIT_HOST_RPC_TIME_MICROSEC 4001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the remote procedure call on the HTP processor + * when client invokes QnnContext_free which in consequence deinit graph. + * The value returned is time in microseconds. + * + * @note graph deinit htp rpc time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_DEINIT_HTP_RPC_TIME_MICROSEC 4002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to the time taken to deinit graph on the + * accelerator when client invokes QnnContext_free which in consequence + * deinit graph. The value returned is time in microseconds. + * + * @note graph deinit accelerator time maybe available on both + * QNN_PROFILE_LEVEL_BASIC and QNN_PROFILE_LEVEL_DETAILED levels + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_DEINIT_ACCEL_TIME_MICROSEC 4003 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents the amount of time an op spends + * waiting for execution on the main thread since the last op on the main + * thread due to scheduling and can be interpreted appropriately in + * conjunction with the unit. + * + * @note node wait information is available on QNN_HTP_PROFILE_LEVEL_LINTING level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_WAIT 5001 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents the amount of time at least one + * background op is running during the execution of an op on the main thread + * and can be interpreted appropriately in conjunction with the unit. + * + * @note node overlap information is available on QNN_HTP_PROFILE_LEVEL_LINTING level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_OVERLAP 5002 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents the amount of time at least one + * background op that is not being waited upon to finish is running during + * the wait period of an op on the main thread and can be interpreted + * appropriately in conjunction with the unit. + * + * @note node wait overlap information is available on QNN_HTP_PROFILE_LEVEL_LINTING + * level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_WAIT_OVERLAP 5003 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents a bitmask denoting the resources + * an op uses. + * + * @note node specific information is available on QNN_HTP_PROFILE_LEVEL_LINTING level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_RESOURCEMASK 5004 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents the ID of an op running in parallel to + * an op running on the main thread or on HMX. + * + * @note node specific information is available on QNN_HTP_PROFILE_LEVEL_LINTING level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_CRITICAL_BG_OP_ID 5005 + +/** + * @brief QnnProfile_EventType_t definition to get data related to execution of + * an operation. This value represents the ID of an op running on threads other + * than the main or the HMX thread when the main and the HMX threads are not + * executing any op. + * + * @note node specific information is available on QNN_HTP_PROFILE_LEVEL_LINTING level + */ +#define QNN_HTP_PROFILE_EVENTTYPE_NODE_WAIT_BG_OP_ID 5006 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to execute the graph's critical path on the accelerator + * when client invokes QnnGraph_execute or QnnGraph_executeAsync. + * The value returned is number of processor cycles taken. + * + * @note graph execute accelerator time maybe available only on + * QNN_HTP_PROFILE_LEVEL_LINTING levels + * + * @note When QNN_HTP_PROFILE_LEVEL_LINTING is used, this event can have + * multiple sub-events of type QNN_PROFILE_EVENTTYPE_NODE. + * There will be a sub-event for each node that was added to the graph + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_EXECUTE_CRITICAL_ACCEL_TIME_CYCLE 6001 + +/** + * @brief Linting QnnProfile_Level_t definition that allows collecting in-depth + * performance metrics for each op in the graph including main thread + * execution time and time spent on parallel background ops. + */ +#define QNN_HTP_PROFILE_LEVEL_LINTING 7001 + +/** + * @brief QnnProfile_EventType_t definition to get number of HVX threads + * configured by a graph. Different graphs can have a different + * value. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_NUMBER_OF_HVX_THREADS 8001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to applying binary section for updatable tensors + * when client invokes QnnContext_ApplyBinarySection. + * It refers to the total time the entire API takes. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_APPLY_BINARY_SECTION_QNN 9001 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to applying binary section for updatable tensors + * when client invokes QnnContext_ApplyBinarySection. + * It refers to the time of callTransport. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_APPLY_BINARY_SECTION_RPC 9002 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to applying binary section for updatable tensors + * when client invokes QnnContext_ApplyBinarySection. + * It refers to the remote procedure call on the HTP processor. + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_APPLY_BINARY_SECTION_QNN_ACC 9003 + +/** + * @brief QnnProfile_EventType_t definition to get profile information + * that corresponds to applying binary section for updatable tensors + * when client invokes QnnContext_ApplyBinarySection. + * It refers to the Hexnn call + * The value returned is time taken in microseconds. + */ +#define QNN_HTP_PROFILE_EVENTTYPE_GRAPH_APPLY_BINARY_SECTION_ACC 9004 + + + +#ifdef __cplusplus +} +#endif + +#endif // QNN_HTP_PROFILE_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProperty.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProperty.h new file mode 100755 index 0000000000000..51440061dc611 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpProperty.h @@ -0,0 +1,30 @@ +//============================================================================== +// +// Copyright (c) 2022 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef QNN_HTP_PROPERTY_H +#define QNN_HTP_PROPERTY_H + +#include "QnnProperty.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +/** + * @brief Property key for determining whether a backend supports unsigned pd. + */ +#define QNN_PROPERTY_CUSTOM_HTP_UNSIGNED_PD_SUPPORT QNN_PROPERTY_GROUP_CUSTOM + 1 + +#ifdef __cplusplus +} +#endif + +#endif // QNN_HTP_PROPERTY_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpSystemContext.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpSystemContext.h new file mode 100755 index 0000000000000..dcfedcb3f6450 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/QnnHtpSystemContext.h @@ -0,0 +1,119 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/** + * @file + * @brief QNN HTP component System Context API. + * + * The interfaces in this file work with the top level QNN + * API and supplements QnnSystemContext.h for HTP backend + */ + +#ifndef QNN_HTP_SYSTEM_CONTEXT_H +#define QNN_HTP_SYSTEM_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================= +// Macros +//============================================================================= +typedef enum { + // Following version with hwInfoBlobVersion as: + // - Major 0, Minor: 0, Patch: 1 + QNN_SYSTEM_CONTEXT_HTP_HW_INFO_BLOB_VERSION_V1 = 0x01, + // Unused, present to ensure 32 bits. + QNN_SYSTEM_CONTEXT_HTP_HW_INFO_BLOB_UNDEFINED = 0x7FFFFFFF +} QnnHtpSystemContext_HwInfoBlobVersion_t; + +// This struct is gets populated within a binary blob as part of hwInfoBlob in +// QnnSystemContext_BinaryInfoV#_t struct in QnnSystemContext.h +typedef struct QnnHtpSystemContext_HwBlobInfoV1 { + // This value represents the index of the list of graphs registered + // to this context as specified in QnnSystemContext_GraphInfo_t* + uint32_t graphListIndex; + // Stores the spill-fill buffer size used by each of the graphs + uint64_t spillFillBufferSize; +} QnnHtpSystemContext_HwBlobInfoV1_t; + +typedef struct { + QnnHtpSystemContext_HwInfoBlobVersion_t version; + union UNNAMED { + QnnHtpSystemContext_HwBlobInfoV1_t contextBinaryHwInfoBlobV1_t; + }; +} QnnHtpSystemContext_HwBlobInfo_t; + +typedef enum { + // Following version with GraphInfoBlobVersion as: + // - Major 0, Minor: 0, Patch: 1 + QNN_SYSTEM_CONTEXT_HTP_GRAPH_INFO_BLOB_VERSION_V1 = 0x01, + // Unused, present to ensure 32 bits. + QNN_SYSTEM_CONTEXT_HTP_GRAPH_INFO_BLOB_UNDEFINED = 0x7FFFFFFF +} QnnHtpSystemContext_GraphInfoBlobVersion_t; + +// This struct is gets populated within a binary blob as part of GraphInfoBlob in +// QnnSystemContext_BinaryInfoV#_t struct in QnnSystemContext.h +typedef struct { + // Stores the spill-fill buffer size used by each of the graphs + uint64_t spillFillBufferSize; + // HTP vtcm size (MB) + uint32_t vtcmSize; + // Optimization level + uint32_t optimizationLevel; + // Htp Dlbc + uint8_t htpDlbc; + // Number of HVX Threads to reserve; + uint64_t numHvxThreads; +} QnnHtpSystemContext_GraphBlobInfoV1_t; + +typedef struct { + QnnHtpSystemContext_GraphInfoBlobVersion_t version; + union UNNAMED { + QnnHtpSystemContext_GraphBlobInfoV1_t contextBinaryGraphBlobInfoV1; + }; +} QnnHtpSystemContext_GraphBlobInfo_t; + +typedef enum { + // Following version with ContextInfoBlobVersion as: + // - Major 0, Minor: 0, Patch: 1 + QNN_SYSTEM_CONTEXT_HTP_CONTEXT_INFO_BLOB_VERSION_V1 = 0x01, + // Unused, present to ensure 32 bits. + QNN_SYSTEM_CONTEXT_HTP_CONTEXT_INFO_BLOB_UNDEFINED = 0x7FFFFFFF +} QnnHtpSystemContext_ContextInfoBlobVersion_t; + +typedef struct{ + /// An integer representation of SocUtility::DspArch + uint32_t dspArch; +} QnnHtpSystemContext_ContextBlobInfoV1_t; + +typedef struct { + QnnHtpSystemContext_ContextInfoBlobVersion_t version; + union UNNAMED { + QnnHtpSystemContext_ContextBlobInfoV1_t contextBinaryContextBlobInfoV1; + }; +} QnnHtpSystemContext_ContextBlobInfo_t; + +//============================================================================= +// Data Types +//============================================================================= + +//============================================================================= +// Public Functions +//============================================================================= + +//============================================================================= +// Implementation Definition +//============================================================================= + +// clang-format on +#ifdef __cplusplus +} // extern "C" +#endif + +#endif \ No newline at end of file diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/afuncs.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/afuncs.h new file mode 100755 index 0000000000000..28b5685f29750 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/afuncs.h @@ -0,0 +1,338 @@ +//============================================================================== +// +// Copyright (c) 2018, 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef AFUNCS_H +#define AFUNCS_H 1 + +#include +#include +#include "dtype.h" +#ifndef __hexagon__ +#include // for memcpy etc +#endif +// #include "asm_define.h" +#include "builtin_intrinsics.h" +#include "macros_attribute.h" + +struct tile_data { + uint8_t **addr; + uint32_t offset_t_col; + uint32_t offset_t_row; + uint32_t width; + uint32_t height; + uint32_t depth; +}; + +// Define order: .addr, .offset_t_col, .offset_t_row, .width, .height, .depth +#define TILEDATA(adrtab, next_tab_col, next_tab_row, h, w, d) \ + { \ + (uint8_t **)(adrtab), static_cast(next_tab_col), static_cast(next_tab_row), \ + static_cast(w), static_cast(h), static_cast(d) \ + } + +/*=======================================*/ +/* Auxiliary functions */ +/*=======================================*/ +#if defined(__hexagon__) +inline int32_t max_i32(int32_t a, int32_t b) +{ + return Q6_R_max_RR(a, b); +} +inline int32_t min_i32(int32_t a, int32_t b) +{ + return Q6_R_min_RR(a, b); +} +inline uint32_t max_u32(uint32_t a, uint32_t b) +{ + return Q6_R_maxu_RR(a, b); +} +inline uint32_t min_u32(uint32_t a, uint32_t b) +{ + return Q6_R_minu_RR(a, b); +} +#else +inline int32_t max_i32(int32_t a, int32_t b) +{ + return (a < b) ? b : a; +} +inline int32_t min_i32(int32_t a, int32_t b) +{ + return (a < b) ? a : b; +} +inline uint32_t max_u32(uint32_t a, uint32_t b) +{ + return (a < b) ? b : a; +} +inline uint32_t min_u32(uint32_t a, uint32_t b) +{ + return (a < b) ? a : b; +} +#endif + +[[maybe_unused]] inline ALWAYSINLINE int64_t roundf_i64(float val) +{ + // add 0.5 (with same sign as val) and then conversion to int truncates toward 0. + // values exactly halfway will round away from 0 (like roundf). + + return (int64_t)(val + copysignf(0.5f, val)); +} + +[[maybe_unused]] inline ALWAYSINLINE NN_INT32_T roundf_i32(float val) +{ + // add 0.5 (with same sign as val) and then conversion to int truncates toward 0. + // values exactly halfway will round away from 0 (like roundf). + + return (int)(val + copysignf(0.5f, val)); +} +// same thing for rounding to unsigned range; -ve inputs will give 0. +// +[[maybe_unused]] inline ALWAYSINLINE uint32_t roundf_u32(float val) +{ + // add 0.5f and then convert to uint (trunc towards 0; -ve values are clipped to 0). +#ifdef __hexagon__ + // use intrinsic since conv of -ve float to unsigned is 'undefined behaviour' in C. + return Q6_R_convert_sf2uw_R_chop(val + 0.5f); +#else + return (val < 0.5f) ? 0 : (uint32_t)(val + 0.5f); +#endif +} + +[[maybe_unused]] inline ALWAYSINLINE NN_INT32_T roundd_i32(double val) +{ + // add 0.5 (with same sign as val) and then conversion to int truncates toward 0. + // values exactly halfway will round away from 0 (like round). + + return (int)(val + copysign(0.5, val)); +} + +[[maybe_unused]] inline ALWAYSINLINE NN_INT32_T saturate_u8(NN_INT32_T val) +{ +#ifdef __hexagon__ + return Q6_R_satub_R(val); +#else + return (val < 0) ? 0 : ((val > 255) ? 255 : val); +#endif +} + +[[maybe_unused]] inline ALWAYSINLINE NN_INT32_T saturate_u16(NN_INT32_T val) +{ +#ifdef __hexagon__ + return Q6_R_satuh_R(val); +#else + return (val < 0) ? 0 : ((val > 65535) ? 65535 : val); +#endif +} + +[[maybe_unused]] static inline ALWAYSINLINE NN_INT32_T saturate_i16(NN_INT32_T val) +{ +#ifdef __hexagon__ + return Q6_R_sath_R(val); +#else + return (val < -32768) ? -32768 : ((val > 32767) ? 32767 : val); +#endif +} + +/** + * @brief low-cost frexpf (but only the exponent result); + * Generates only a few instructions on hexagon. + * + * Input must not be inf,nan, zero, or denormal. + * + * returns: + * -1 if abs(x) is in range 0.25 ... 0.249999 + * 0 if abs(x) is in range 0.5 ... 0.99999 + * 1 if abs(x) is in range 1.0 .. 1.9999 + * etc + * + * If the value -126 is returned, x is a zero or denormal; + * 129 is returned for inf or NaN. for other cases the value is the same + * as what frexpf (in math.h) generates for the exponent. + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr int flt_getexp(float x) +{ + union { + float f; + uint32_t u32; + } const uu = {x}; + return ((uu.u32 >> 23u) & 0xFFu) - 126; +} +/** + * @brief low-cost frexpf (but only the 'fraction' result); + * Generates only a few instructions on hexagon. + * + * Input must not be inf,nan, zero, or denormal. + * + * returns a value in the range [0.5, 1.0) (or in (-1.0,-0.5] when x < 0) + * such that x = flt_getmant(x) * powf2(2.0, flt_getexp(x)) + * + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr float flt_getmant(float x) +{ + union { + float f; + uint32_t u32; + } uu = {x}; + uu.u32 = (uu.u32 & 0x807fffffu) | (uint32_t(126) << 23u); // force exponent = 126 + return uu.f; +} + +/** + * @brief returns the mantissa of x, as a 24-bit number + * in the range 0x800000 .. 0xFFFFFF + * + * Input must not be inf,nan, zero, or denormal. + * + * Sign is discarded. same as powf(2,24) * flt_getmant(fabsf(x)). + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr int32_t flt_getfrac(float x) +{ + union { + float f; + uint32_t u32; + } const uu = {x}; + int32_t const m = (uu.u32 & 0x007fffffu) | (uint32_t(1) << 23u); + return m; +} + +// +// This 'normalizes' a float to 0.5 .. 0.9999 (sign is retained) +// Same result as the return value from frexpf, without using a function call +// Results are not valid if x is 0, denormal, or inf/nan +// +[[maybe_unused]] inline ALWAYSINLINE float flt_getfrac_norm(float x) +{ + union { + float f; + uint32_t u32; + } uu = {x}; + uu.u32 = (uu.u32 & 0x807fffffu) | (uint32_t(126) << 23u); // force exponent = 126 + return uu.f; +} +/** + * @brief low-cost 2.0*n for integer n. + * Same as powf(2.0f, iexpo) without a function call; + * + * Constraint: iexpo must be in range -126..127 + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr float flt_power2(uint32_t const iexpo) +{ + uint32_t const a = (iexpo + 127) & 0xFFu; + union { + uint32_t u32; + float f; + } const uu = {a << 23u}; + return uu.f; +} +/** + * @brief low-cost ldexpf + * Same as ldexpf(val, iexpo) without a function call; + * + * Constraint: iexpo must be in range -126..127 + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr float flt_ldexp(float val, int iexpo) +{ + return val * flt_power2(iexpo); +} +/** + * @brief low-cost 2.0*n for integer n. + * Same as pow(2.0d, iexpo) without a function call; + * + * Constraint: iexpo must be in range -1022..1023 + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr double double_power2(uint32_t const iexpo) +{ + uint64_t const a = (iexpo + 1023) & 0x7FFu; + union { + uint64_t u64; + double d; + } const uu = {a << 52u}; + return uu.d; +} +/** + * @brief low-cost ldexpf + * Same as ldexp(val, iexpo) without a function call; + * + * Constraint: iexpo must be in range -1022..1023 + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr double double_ldexp(double val, int iexpo) +{ + return val * double_power2(iexpo); +} + +/** + * @brief returns the exponent and mantissa of x, as a n-bit number + * + * Constraint: iexpo must be in range -126..127 + * Input must not be negative, inf,nan, zero, or denormal. + */ +template inline constexpr std::pair get_scalefactor(float x) +{ + union { + float f; + uint32_t u32; + } const uu = {x}; + + uint32_t inval = uu.u32; + uint32_t const mask = hnnx::safe_lshift(1, MBITS) - 1; + inval = hnnx::safe_rshift(inval + hnnx::safe_lshift(1, (24 - MBITS - 1)), + (24 - MBITS)); // possibly overflows into exponent, but that's OK. + uint32_t const m = ((inval & mask) | hnnx::safe_lshift(1u, (MBITS - 1))); + int32_t const e = int32_t(hnnx::safe_rshift(inval, (MBITS - 1)) & 0xFFu) - 126; + return {e, m}; +} + +/** + * @brief returns the parameters for scaling. + * bit 31-24: left shift amount + * bit 23-16: right shift amout + * bit 15- 0: scale factor + * + * Input must not be inf,nan, zero, negative or denormal. + * + */ +[[maybe_unused]] inline ALWAYSINLINE constexpr uint32_t get_scaling_params(float x, int max_sl, int max_sr) +{ + auto [e, m] = get_scalefactor<15>(x); + // Set a sl or sr amount to perform a multiply of 2^exponent by mantissa. + int sl = (e > 0) ? e : 0; + int sr = (e > 0) ? 0 : -e; + // The max_sl allows the addition of extra left shifts when working with small numbers having negative exponents. + // For every extra left shift, there is an offsetting right shift added so that the net right shift amount + // required from the exponent stays the same. The max_sr parameter provides a ceiling to the required offsetting + // right shifts, preventing the total right shift requirement from being large enough to erase data through shifting. + if (sl == 0 && sr > 0) { + sl = min_i32(max_sl, max_i32(max_sr - sr, 0)); + sr = sr + sl; + } + return ((uint32_t(sl) & 0x0FFu) << 24u) | ((uint32_t(sr) & 0x0FFu) << 16u) | uint32_t(m); +} + +/** + * @brief given a scale in float and a recip shift amount + * return a quantized scale multiplier and change recip shamt inplace + * + */ +inline uint32_t get_quantized_multipiler(const float scale_f, int &recip_shamt) +{ + recip_shamt = (scale_f <= 1.0f) ? 0 : flt_getexp(scale_f); + uint32_t scale = static_cast(roundf(flt_ldexp(scale_f, (31 - recip_shamt)))); + scale = (scale < 0x7fffffffu) ? scale : 0x7FFFFFFFu; + return scale; +} + +/** + * @brief given a scale in float and a recip shift amount + * return a quantized scale multiplier and change recip shamt inplace + * + */ +//Now with corrected spelling +inline uint32_t get_quantized_multiplier(const float scale_f, int &recip_shamt) +{ + return get_quantized_multipiler(scale_f, recip_shamt); +} +#endif /*AFUNCS_H*/ diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/allocator.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/allocator.h new file mode 100755 index 0000000000000..844bcf4c7ec50 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/allocator.h @@ -0,0 +1,236 @@ +//============================================================================== +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef ALLOCATOR_H +#define ALLOCATOR_H 1 + +#include +#include +#include +#include "dtype_enum.h" +#include "weak_linkage.h" +#include "macros_attribute.h" +#include "forward_classes.h" +#include "hexagon_nn_types.h" + +enum class MemoryClass { + Plain, + TCM, + UnCached, // for spill/fill DDR + XXX_LAST_MEMORY_TYPE, + Default = Plain +}; + +PUSH_VISIBILITY(default) + +extern bool TrackedAllocError; + +class Graph; +class HexagonNNEnv; +namespace fa { +struct PoolDesc; +struct BigBuff; +struct RuntimeAllocator; +} // namespace fa +namespace hnnx { + +class Serializer; +class Deserializer; + +// some options flags (powers of 2) for calls to Tensor::allocate +enum AllocOptions { + uncached_int8 = 0x1, // override MemoryClass to UnCached. + uncached_int16 = 0x2, + uncached_fp16 = 0x4 +}; + +/* + * Maybe FIXME: It seems like FancyAllocator has just about all the same interfaces as Allocator, + * is all this pimpl stuff needed, or could we just inherit Allocator and have a unique_ptr + * in our graph? + */ + +class Allocator { + public: + // MIN_ALIGN, MAX_ALIGN: + // - both must be powers of 2 + // - 8 <= MIN_ALIGN <= MAX_ALIGN + // All allocations will be aligned to at least MIN_ALIGN, both start and end of each region. + // This includes sub-allocations in memory pools. + // Alignment requests > MAX_ALIGN may be treated as MAX_ALIGN if allocated in DDR. + // + static constexpr unsigned MIN_ALIGN = 256; + static constexpr unsigned MAX_ALIGN = 256; + + // The alignment used by TCM allocation; >= MIN_ALIGN + static constexpr unsigned TCM_ALLOC_ALIGN = 2048; + + static void *vacant() { return (void *)2; } // special value for 'vacant' slot. + enum Mode { AllocVirtual, AllocPhysical, AllocTemp, AllocTempEnd, AllocComplete, LastMode = AllocComplete }; + + // AllocTemp/AllocTempEnd are used in Virtual mode, to set a 'Temp Physical' mode + // where allocation is done to physical memory, but into memory blocks which + // are discarded when we return via AllocTempEnd (So, AllocTempEnd is not possible as an actual + // current mode). + // This is intended to support nesting (multiple levels of AllocTemp; each + // AllocTempEnd discards all allocs since the matching AllocTemp; but + // currently nesting is not supported, so AllocTemp must be followed by AllocTempEnd, + // which actually takes you back to AllocVirtual + // AllocComplete allows no further allocations. A deserialized allocator + // is in this state. + + API_EXPORT Allocator(Mode mode_in, Graph &graph_in) : graph(graph_in), mode(mode_in){}; + API_EXPORT virtual ~Allocator() = 0; + + Graph &graph; + + // Either allocates enough, or dips into a buffer (and changes the buffer pointer and size parameter accordingly). + // al is an alignment parameter; it must be a power of 2 or the code below won't work. + API_EXPORT void *tracked_aligned_alloc(size_t al, size_t bytes, fa::BigBuff *const bb = nullptr); + API_EXPORT void tracked_free(void *aligned_ptr) noexcept; + + API_EXPORT virtual void allocate_n(void **arrp, size_t n, size_t block_size, size_t alignment, MemoryClass memclass, + unsigned options, DType dtype); + + // options for allocate_persistent_blocks. + // if 'allnew' is *not* present, it is assumed that all of the pointers + // are either null, or point to existing persistent blocks. The 'null' ones + // are replaced with new allocations, and the ref counts are increased in both cases. + // with 'allnew': pointers are assumed to contain garbage. Equivalent to zeroing the + // pointer table first. + // + // zoneB: with this, ref counts are update in 'B' zone instead of A + // + // incref: ovverides 'allnew'; all of the existing pointers are required to be valid persistent + // blocks; the ref counts are increased by 1 + // decref: overrides 'incref and allnew'; all of the pointers are required to be valid persistent + // blocks; the ref counts are reduced by 1. If total refs are zero, block is freed. + // the pointer table is not updated. + // + // infinite: newly alloc'd blocks get refcount set to a huge number, instead of 1. + // Currently this is used when deserializing, since we can't free things immediately when in Crate. + // + enum persistent_options { + allnew = 1u, // assume existing pointers are garbage, allocate them all. + zoneB = 2u, // reference count in zone B instead of A. + incref = 4u, // enforce that all existing are persistnent; incref them. + decref = 8u, + infinite = 16u, // refcounts on new blocks, set to a huge # instead of 1. + }; + + // allocate n 'persistent' blocks of the given size/alignment, and update the table. + API_EXPORT virtual void allocate_persistent_blocks(void **table, size_t nblocks, size_t block_size, + size_t alignment, unsigned options); + + API_EXPORT inline void *allocate(const void *oldval, size_t block_size, size_t alignment, MemoryClass memclass, + unsigned options, DType dtype) + { + PUSH_WARNING() + DISABLE_WARNING("-Wcast-qual", MSVC_NO_EQUIV) + void *tmp = const_cast(oldval); + POP_WARNING() + allocate_n(&tmp, 1, block_size, alignment, memclass, options, dtype); + return tmp; + } + + API_EXPORT Mode get_mode() const { return mode; } + API_EXPORT virtual void set_mode(Mode new_mode); + + API_EXPORT virtual void set_tcm_pool(void *base, size_t size); + + API_EXPORT virtual void set_largest_memory_alloc_size(size_t size); + + /* + * Serialize all the internal data for the allocator. + * Memory regions / pools, etc. + */ + API_EXPORT virtual void serialize(Serializer &) const; + /* + * Deserialize the allocator, restore internal data from buffer. + */ + API_EXPORT virtual void deserialize(HexagonNNEnv &env, Deserializer &dctx, + hexagon_nn_wide_address_const_t params_weights = 0U, + const size_t params_weights_length = 0, + hexagon_nn_wide_iovec_t const &weights = NULL_IOVEC); + + API_EXPORT virtual int find_replaceable_mempool(unsigned const replaceable_pool_seq, + fa::PoolDesc &found_pool) const; + + // LCOV_EXCL_START [SAFTYSWCCB-1542] + API_EXPORT static inline constexpr size_t fixup_alignment(size_t align) + { + static_assert(MIN_ALIGN >= 8 && (MIN_ALIGN & (MIN_ALIGN - 1)) == 0, "bad MIN_ALIGN"); + static_assert(MAX_ALIGN >= MIN_ALIGN && (MAX_ALIGN & (MAX_ALIGN - 1)) == 0, "bad MAX_ALIGN"); + if (MIN_ALIGN < MAX_ALIGN) { + return std::max(MIN_ALIGN, std::min(MAX_ALIGN, align)); + } else { + return MIN_ALIGN; + } + } + // LCOV_EXCL_STOP + + API_EXPORT static inline constexpr size_t round_up_align(size_t n, size_t align) + { + return (n + (align - 1)) & ~(align - 1); + } + template API_EXPORT static inline T *round_up_align(T *p, size_t align) + { + return (T *)round_up_align((size_t)p, align); + } + + protected: + Mode mode = AllocVirtual; +}; + +// +// this is s 'shim' class to help in making dummy allocators. It defines overrides +// for all of the pure-virtual methods, so you don't need to +// +class FakeAllocator : public Allocator { + public: + API_EXPORT FakeAllocator(Allocator::Mode mode_in, Graph &graph_in) : Allocator(mode_in, graph_in){}; + API_EXPORT virtual ~FakeAllocator(); +}; + +// this is an accessor which is used by the Dma 'Fill' operation +// to get a source pointer for reading const, based on (pool_id, offset). +// It also holds the base pointer for ddr spill area. +// Maybe other things could be added later. + +class MemPoolRunTimeAccessor { + hexagon_nn_wide_address_t spill_area; + fa::PoolDesc const *pool_table; // pool_table[0] is for poolid=1 + unsigned max_pool_id; + + public: + API_EXPORT MemPoolRunTimeAccessor(hexagon_nn_wide_address_const_t spill_area_in, fa::PoolDesc const *const pt, + unsigned const pt_size) + : spill_area(spill_area_in), pool_table(pt), max_pool_id(pt_size) + { + } + API_EXPORT MemPoolRunTimeAccessor() : spill_area(0), pool_table(nullptr), max_pool_id(0) {} + API_EXPORT MemPoolRunTimeAccessor(MemPoolRunTimeAccessor const &) = default; + API_EXPORT MemPoolRunTimeAccessor &operator=(MemPoolRunTimeAccessor const &) = default; + + // pool ids are >= 1, <= num_pools + API_EXPORT constexpr unsigned num_pools() const { return max_pool_id; } //LCOV_EXCL_LINE [SAFTYSWCCB-1542] + // map pool_id to base address of the data, for persistent pool; also get 'is_weights' flag. + // implementation in runtime_alloc.h + std::pair get_persistent_pool_base_iswts(unsigned pool_id) const; + API_EXPORT hexagon_nn_wide_address_t get_spill_area() const { return spill_area; } + + // used to construct the ConstExtentDescriptor during prep + // implementation in fa_alloc.h + API_EXPORT fa::PoolDesc const *get_descriptor(unsigned pool_id) const; +}; + +} // namespace hnnx + +POP_VISIBILITY() + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/bake_defs.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/bake_defs.h new file mode 100755 index 0000000000000..11d01bcb31b95 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/bake_defs.h @@ -0,0 +1,244 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef BAKE_DEFS +#define BAKE_DEFS 1 +#include +#include +#include +#include + +#include "executable.h" + +// Contains defs for host-side and target side, so try not +// to add too many 'host only' things. + +#ifdef __hexagon__ +#define HNNX_ARCH_CAN_RUN_BAKED 1 +#endif + +namespace hnnx { + +namespace bake { + +using tgt_ptr_word = unsigned; +using tgt_sizet_word = unsigned; +static constexpr unsigned tgt_ptr_bytes = sizeof(tgt_ptr_word); +static constexpr unsigned tgt_sizet_bytes = sizeof(tgt_sizet_word); +static constexpr bool op_has_graphp = false; +static constexpr unsigned tensor_uptr_ptrs = 2; +static constexpr unsigned max_opaquet_align = 1024; // must be power of 2 + +// This should be OK as a first approx: includes hexagon and x86-32 +static constexpr bool host_can_run_baked = sizeof(void *) == tgt_ptr_bytes; + +inline unsigned constexpr round_up(unsigned x, unsigned m) +{ + return ((x + (m - 1)) / m) * m; +} + +// functions to calculate size, align of various things. They +// are included in target build so we can static_assert that sizes are what we think they are. +// (all must be constexpr). + +// {size, alignment} of typical_op +inline constexpr std::pair typical_op_tgt_size_align(unsigned n_in, unsigned n_out) +{ + // 1 pointer per input, plus tensor_uptr_ptrs per output; but if n_in = n_out == 0, it's 1 pointer. + // (for a 'fill' byte). + unsigned num_io_ptrs = n_in + n_out * tensor_uptr_ptrs; + if (num_io_ptrs == 0) num_io_ptrs = 1; // n_in = n_out = 0 case + return {tgt_ptr_bytes * ((op_has_graphp ? 2 : 1) // vptr, and maybe Graph * + + num_io_ptrs), // inputs and outputs + tgt_ptr_bytes}; // align +} + +// 'tensor_op_tgt_size_align is used for crate accounting of ShapeWrapperOp, ConstWrapperOp, DummyOp +// In a proper 'baked graph' we don't need to insert these, just the tensors... + +inline constexpr std::pair tensor_op_tgt_size_align(unsigned n_out) +{ + // happens to be the same as TypicalOp with no inputs... + return typical_op_tgt_size_align(0, n_out); +} + +// {size, alignment, extra} of typical_op_with_compiler +// extra_len is the len of the extra data +// extra_align is its alignment. +// The 3rd return value is the offset of the 'extra' within the image. +// +inline constexpr std::tuple +typical_op_extra_tgt_size_align(unsigned n_in, unsigned n_out, unsigned extra_len, unsigned extra_align) +{ + std::pair base_size = typical_op_tgt_size_align(n_in, n_out); + unsigned extra_offs = base_size.first; + if (extra_len > 0) { + extra_align = std::max(extra_align, base_size.second); + extra_len = round_up(extra_len, extra_align); + extra_offs = round_up(extra_offs, extra_align); + base_size.first = extra_offs + extra_len; + base_size.second = extra_align; + } + return {base_size.first, base_size.second, extra_offs}; +} + +// {size, alignment} of variadic op (without the in, out array contents)! +constexpr std::pair variadic_op_tgt_size_align(unsigned n_in, unsigned n_out) +{ + const unsigned cratevec_words = 2; + return {tgt_ptr_bytes * (1 // vptr + + (op_has_graphp ? 1 : 0) // Graph * + + 2 * cratevec_words), // two cratevecs + tgt_ptr_bytes}; // align +} +// {size, alignment} of simple_op_wrapper (without the in, out array contents)! +constexpr std::pair simplewrap_op_tgt_size_align(unsigned n_in, unsigned n_out) +{ + // this is just one more pointer than a variadic op... + const auto var_result = variadic_op_tgt_size_align(n_in, n_out); + return {var_result.first + tgt_ptr_bytes, var_result.second}; +} + +// {size, alignment} of a ChunkPreloadOp +constexpr std::pair chunk_preload_op_tgt_size_align() +{ + return {tgt_ptr_bytes * (1 // vptr + + (op_has_graphp ? 1 : 0) // Graph * + + 2), // ptr, len; + tgt_ptr_bytes}; // align +} + +// +// {size_align} of Shape object +// +constexpr std::pair shape_tgt_size_align(unsigned rank) +{ + // tgt_sizet_bytes * (1 + 1 + 2 * rank) = + // vtable ptr + // shapeflag flags + padding[] + // std::array dims + // std::array max_dims + // + rank = std::array pad + return {round_up(tgt_sizet_bytes * (1 + 1 + 1 + 2 * rank) + rank, tgt_sizet_bytes), tgt_sizet_bytes}; +} + +// +// {size_align} of DynamicShape object +// +constexpr std::pair dynamic_shape_tgt_size_align(const unsigned rank) +{ + // std::array dims == tgt_sizet_bytes * rank + // (shapeflag flags + padding[]) + vtable ptr + dynamic_state = (3 * tgt_sizet_bytes) + return {round_up(tgt_sizet_bytes * rank + (4 * tgt_sizet_bytes), tgt_sizet_bytes), tgt_sizet_bytes}; +} + +// +// {size_align} of interface object (may or may not be quantized) +// +constexpr std::pair interface_tgt_size_align(bool is_quantized) +{ + return {tgt_sizet_bytes + (is_quantized ? round_up(3 * 4, tgt_sizet_bytes) : 0), tgt_sizet_bytes}; +} + +// {size_align} of Tensors, of three different forms: +// +// 'general' tensor +// +constexpr std::pair tensor_general_tgt_size_align() +{ + return {tgt_sizet_bytes * 4 + 2 * tgt_ptr_bytes, tgt_sizet_bytes}; +} + +// 'shape' tensor, of given rank. +// +constexpr std::pair tensor_shape_tgt_size_align(unsigned rank) +{ + return {tgt_sizet_bytes * ((rank == 0 ? 1 : rank) + 1), tgt_sizet_bytes}; +} + +// 'scalar' tensor, need to know if the interface is 'quantized' or not +// Note, this assumes all value are <= size_t bytes. +// +constexpr std::pair tensor_scalar_tgt_size_align(bool is_quantized) +{ + const unsigned ifc_size = interface_tgt_size_align(is_quantized).first; + return {tgt_sizet_bytes * 2 + ifc_size, tgt_sizet_bytes}; +} +// sizeof OpExtraInfo on target: {long long, 2 * unsigned, char *, 4 * padbyte} +constexpr std::pair OpExtraInfo_size_align = {24, 8}; + +// The size of a SliceDispatchOp for the given number of slices. +// Currently it's always the same regardless of 'nslices'; We may introduce 'right-sized' +// value, in which case 'exact=true' will get the 'real' size; but exact = false will always +// give the full size. +constexpr std::pair slice_dispatch_op_size_align(unsigned const nslices, bool const exact = false) +{ + return {tgt_sizet_bytes * ((op_has_graphp ? 5 : 4) + 3 * Executable::MAX_OP_SLICES), tgt_sizet_bytes}; +} + +// The size of a Predicated Op +constexpr std::pair pred_op_size_align() +{ + return {tgt_sizet_bytes * ((op_has_graphp ? 5 : 4) + 3), tgt_sizet_bytes}; +} + +// this is used in e.g. +// if constexpr(host_can_run_baked) static_assert(size_align_matches(N_IN, N_OUT)); + +template constexpr bool size_align_matches(SZAL sz) +{ + return sizeof(T) == std::get<0>(sz) && alignof(T) == std::get<1>(sz); +} + +// This is a utility to check that a type T has a given size and aligment, using static_assert; +// Just need to include a call to 'do-nothing' bake::check_size_align::template check(); +// The static assert is *disabled* unless compiling on hexagon (or compatible host). +// +// It's more complex than it needs to be, since it's designed to make sure the type and +// numbers wind up in the error message, e.g. you could end up with +// error: static_assert failed due to requirement 'claimed(40) == actual(48)' "size not as claimed" +// static_assert(claimed(CLAIMED_SIZE) == actual(ACTUAL_SIZE), "size not as claimed"); +// ... note: in instantiation of function template specialization 'check_szal::check_size_align<..., ...>' +// +template struct check_size_align { + static constexpr int claimed(int K) { return K; } + static constexpr int actual(int K) { return K; } + template static constexpr bool check_size() + { + static_assert(claimed(CLAIMED_SIZE) == actual(ACTUAL_SIZE), "size not as claimed"); + return CLAIMED_SIZE == ACTUAL_SIZE; + } + template static constexpr bool check_align() + { + static_assert(claimed(CLAIMED_ALIGN) == actual(ACTUAL_ALIGN), "align not as claimed"); + return CLAIMED_ALIGN == ACTUAL_ALIGN; + } + + template static constexpr bool check() + { + bool result = true; + if constexpr (host_can_run_baked) { + result = check_size() && check_align(); + } + return result; + } +}; + +} // namespace bake + +// +// op_opaque_tgt_info must be specialized for each OpaqueT used in TypicalOpWithCompiler +// +template struct op_opaque_tgt_info { + // static constexpr unsigned length = ..; // length of the struct on target CPU + // static constexpr unsigned alignment = ... // aligbment on target CPU +}; + +} // namespace hnnx + +#endif // BAKE_DEFS diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/builtin_intrinsics.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/builtin_intrinsics.h new file mode 100755 index 0000000000000..3496b792f25aa --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/builtin_intrinsics.h @@ -0,0 +1,247 @@ +//============================================================================== +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +// Compiler builtin intrinsic functions should be specified in this file + +#ifndef BUILTIN_INTRINSICS_H_ +#define BUILTIN_INTRINSICS_H_ + +#include +#include +#include +#include + +// Branch prediction +#if defined(__clang__) + +#define HEX_LIKELY(x) __builtin_expect(!!(x), 1) +#define HEX_UNLIKELY(x) __builtin_expect(!!(x), 0) + +#define HEX_ASSUME __builtin_assume +#define HEX_UNREACHABLE __builtin_unreachable + +#elif defined(_MSC_VER) + +#define HEX_LIKELY(x) (x) +#define HEX_UNLIKELY(x) (x) + +#define HEX_ASSUME __assume +#define HEX_UNREACHABLE() __assume(0) + +#elif defined(__GNUC__) +//No equivalent __builtin_assume in GNUC. Hence leaving empty. +#define HEX_ASSUME(cond) + +#define HEX_LIKELY(x) __builtin_expect(!!(x), 1) +#define HEX_UNLIKELY(x) __builtin_expect(!!(x), 0) +#define HEX_UNREACHABLE __builtin_unreachable + +#endif // defined(__clang__) + +// Overflow detection +#if defined(__clang__) || defined(__GNUC__) + +#define HEX_ADD_OVERFLOW __builtin_add_overflow +#define HEX_MUL_OVERFLOW __builtin_mul_overflow + +#elif defined(_MSC_VER) + +#include + +template static inline bool HEX_ADD_OVERFLOW(_T a, _T b, _T *out) +{ + *out = a + b; + return ((b > 0) && (a > std::numeric_limits<_T>::max() - b)) || + ((b < 0) && (a < std::numeric_limits<_T>::min() - b)); +} + +template static inline bool HEX_MUL_OVERFLOW(_T a, _T b, _T *out) +{ + *out = a * b; + return ((b > 0) && (a > std::numeric_limits<_T>::max() / b || a < std::numeric_limits<_T>::min() / b)) || + ((b < 0) && (a > std::numeric_limits<_T>::min() / b || a < std::numeric_limits<_T>::max() / b)); +} + +#endif // __clang__ + +// Count bits + +#include + +template static inline int HEX_COUNT_ONE_BIT(_T x) +{ + return std::bitset(x).count(); +} + +#define HEX_COUNT_ONE_BIT_ULL HEX_COUNT_ONE_BIT +#define HEX_COUNT_ONE_BIT_UL HEX_COUNT_ONE_BIT + +#if defined(__clang__) || defined(__GNUC__) + +#define HEX_COUNT_LEADING_ZERO __builtin_clz +#define HEX_COUNT_LEADING_ZERO_UL __builtin_clzl +#define HEX_COUNT_LEADING_ZERO_ULL __builtin_clzll + +#define HEX_COUNT_TRAILING_ZERO __builtin_ctz +#define HEX_COUNT_TRAILING_ZERO_UL __builtin_ctzl +#define HEX_COUNT_TRAILING_ZERO_ULL __builtin_ctzll + +#elif defined(_MSC_VER) + +#include + +// Returns the number of leading 0-bits in x, starting at the most significant +// bit position. If x is 0, the result is undefined. +static inline int HEX_COUNT_LEADING_ZERO_ULL(unsigned long long x) +{ + unsigned long where; + if (_BitScanReverse64(&where, x)) return static_cast(63 - where); + return 64; // Undefined behavior +} + +static inline int HEX_COUNT_LEADING_ZERO(unsigned int x) +{ + unsigned long where; + if (_BitScanReverse(&where, x)) return static_cast(31 - where); + return 32; // Undefined Behavior. +} + +static inline int HEX_COUNT_LEADING_ZERO_UL(unsigned long x) +{ + return sizeof(x) == 8 ? HEX_COUNT_LEADING_ZERO_ULL(x) : HEX_COUNT_LEADING_ZERO(static_cast(x)); +} + +// Returns the number of trailing 0-bits in x, starting at the least significant +// bit position. If x is 0, the result is undefined. +static inline int HEX_COUNT_TRAILING_ZERO_ULL(unsigned long long x) +{ + unsigned long where; + if (_BitScanForward64(&where, x)) return static_cast(where); + return 64; // Undefined Behavior. +} + +static inline int HEX_COUNT_TRAILING_ZERO(unsigned int x) +{ + unsigned long where; + if (_BitScanForward(&where, x)) return static_cast(where); + return 32; // Undefined Behavior. +} + +static inline int HEX_COUNT_TRAILING_ZERO_UL(unsigned long x) +{ + return sizeof(x) == 8 ? HEX_COUNT_TRAILING_ZERO_ULL(x) : HEX_COUNT_TRAILING_ZERO(static_cast(x)); +} + +#endif // defined(__clang__) + +// Atomic operation + +#if defined(__clang__) || defined(__GNUC__) + +#define HEX_ATOMIC_FETCH_AND_ADD __sync_fetch_and_add + +#define HEX_ATOMIC_FETCH_AND_AND __sync_fetch_and_and +#define HEX_ATOMIC_FETCH_AND_OR __sync_fetch_and_or + +#define HEX_ATOMIC_VAL_COMPARE_AND_SWAP __sync_val_compare_and_swap +#define HEX_ATOMIC_BOOL_COMPARE_AND_SWAP __sync_bool_compare_and_swap + +#elif defined(_MSC_VER) + +#include + +#define HEX_ATOMIC_FETCH_AND_ADD(_p, _v) \ + (sizeof *(_p) == sizeof(__int64) ? _InterlockedExchangeAdd64((__int64 *)(_p), (__int64)(_v)) \ + : _InterlockedExchangeAdd((long *)(_p), (long)(_v))) + +template static inline _T HEX_ATOMIC_FETCH_AND_AND(_T volatile *_p, _T _v) +{ + _InterlockedAnd((long *)_p, (long)_v); + return static_cast<_T>(*_p); +} + +template static inline _T HEX_ATOMIC_FETCH_AND_OR(_T volatile *_p, _T _v) +{ + _InterlockedOr((long *)_p, (long)_v); + return static_cast<_T>(*_p); +} + +#define HEX_ATOMIC_VAL_COMPARE_AND_SWAP(_p, _old, _new) \ + (sizeof *(_p) == sizeof(__int64) \ + ? _InterlockedCompareExchange64((__int64 *)(_p), (__int64)(_new), (__int64)(_old)) \ + : _InterlockedCompareExchange((long *)(_p), (long)(_new), (long)(_old))) + +#define HEX_ATOMIC_BOOL_COMPARE_AND_SWAP(_p, _old, _new) (HEX_ATOMIC_VAL_COMPARE_AND_SWAP(_p, _old, _new) == (_old)) + +#endif // defined(__clang__) + +namespace hnnx { + +/** + * @brief promote_shift_operand reflects the integral promotions for small integer types. + * safe_lshift/safe_rshift must be aware of these promotions, since the C++ standard only + * defines the behavior for shift operations where the RHS is between 0 and + * 1 less than the bit-width of the *promoted* type of the LHS. + */ +template struct promote_shift_operand { + typedef T type; +}; + +template <> struct promote_shift_operand { + using type = int; +}; +template <> struct promote_shift_operand { + using type = int; +}; +template <> struct promote_shift_operand { + using type = int; +}; +template <> struct promote_shift_operand { + using type = int; +}; +template <> struct promote_shift_operand { + using type = int; +}; + +template using promote_shift_operand_t = typename promote_shift_operand::type; + +// The following portable template functions are replacements for the +// built-in shift operations, << and >>, that provide the following guarantees: +// +// 1. Both the left and right operands of the shift will be treated as unsigned. +// This, by construction, prevents any undefined or implementation-defined +// behavior that may arise when shifting negative-valued expressions. +// 2. The right operand will be bit-masked in a way that guarantees +// that its value is in the range [0, bitwidth(promoted_left_operand) - 1] + +template constexpr unsigned get_safe_shift_mask() +{ + return unsigned(CHAR_BIT * sizeof(promote_shift_operand_t>>) - 1); +} + +template ()> +constexpr auto safe_lshift(T const value, S const shift_amount) +{ + static_assert(std::is_integral::value && std::is_integral::value, + "safe_lshift only makes sense for integral parameters"); + assert((static_cast(shift_amount) & ~mask) == 0 && "shift_amount is out of range"); + return value << shift_amount; +} + +template ()> +constexpr auto safe_rshift(T const value, S const shift_amount) +{ + static_assert(std::is_integral::value && std::is_integral::value, + "safe_rshift only makes sense for integral parameters"); + assert((static_cast(shift_amount) & ~mask) == 0 && "shift_amount is out of range"); + return value >> shift_amount; +} + +} // namespace hnnx + +#endif /* BUILTIN_INTRINSICS_H_ */ diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/c_tricks.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/c_tricks.h new file mode 100755 index 0000000000000..0531625039312 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/c_tricks.h @@ -0,0 +1,21 @@ +//============================================================================== +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef C_TRICKS_H +#define C_TRICKS_H 1 + +#define CTRICKS_PASTER2(A, B) A##B +#define CTRICKS_PASTER(A, B) CTRICKS_PASTER2(A, B) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define PROBABLY(x) __builtin_expect(!(!(x)), 1) +#define YEAHRIGHT(x) __builtin_expect(!(!(x)), 1) + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cc_pp.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cc_pp.h new file mode 100755 index 0000000000000..c4363d8cb3e6f --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cc_pp.h @@ -0,0 +1,26 @@ +//============================================================================== +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CC_PP_H +#define CC_PP_H 1 + +/* + * C++ Preprocessor Definitions + */ + +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END \ + } \ + ; +#else +#define EXTERN_C_BEGIN /* NOTHING */ +#define EXTERN_C_END /* NOTHING */ +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/check_hvx.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/check_hvx.h new file mode 100755 index 0000000000000..bd12354b0a314 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/check_hvx.h @@ -0,0 +1,35 @@ +//============================================================================== +// +// Copyright (c) 2022-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#include "cc_pp.h" +#include "macros_attribute.h" +#include "weak_linkage.h" + +#ifndef CHECK_HVX_H +#define CHECK_HVX_H 1 + +// +// This makes sure that we have an HVX context (or not). Does nothing on H2 or +// QuRT, but on x86, makes use of a TLS variable to do the check. +// + +#ifdef __hexagon__ + +static inline void check_hvx() {} +static inline void check_not_hvx() {} + +#else + +PUSH_VISIBILITY(default) +API_EXPORT void check_hvx(); +API_EXPORT void check_not_hvx(); +POP_VISIBILITY() + +#endif + +#endif // CHECK_HVX_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_descriptor.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_descriptor.h new file mode 100755 index 0000000000000..a7f50569eb471 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_descriptor.h @@ -0,0 +1,207 @@ +//============================================================================== +// +// Copyright (c) 2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CONST_EXTENT_DESCRIPTOR_H +#define CONST_EXTENT_DESCRIPTOR_H 1 + +#include +#include +#include +#include +#include "forward_classes.h" +#include "serialize_defs.h" +#include "pickle_header_tags.h" +#include "const_extent_shared.h" + +namespace hnnx { + +// This class is used, on both encoder and decoder, to contain a 'const extent descriptor' in its raw form, (just an array of uint32) +// and provide higher-level access to the contents. + +class ConstExtentDesc { + protected: + using table_t = std::vector; + // The 'table' may or may not contain the 'padding' section at the end; this is not accessed, + // and the serialize method will always generate the required padding. + table_t table; + // some values broken out from the header... + unsigned extab_n = 0, extab_idx = 0; // number of extents, and word index where they start + unsigned mptab_n = 0, mptab_idx = 0; // number of memory pools, and word index where they start. + unsigned desc_len = 0; // length of the entire descriptor in bytes (0 if invalid descriptor) + + bool scan_table(); // sanity check, and unpacks the above; returns true if OK. + + public: + static uint8_t constexpr EXTENT_FLAGS_BITFIELD_LSB = 8; + static uint8_t constexpr EXTENT_FLAGS_BITFIELD_WIDTH = 8; + + /// + /// @brief Values for 8b flags in extent record + /// + static uint8_t constexpr EXTENT_FLAG_RESERVED_0 = (1 << 0); + static uint8_t constexpr EXTENT_FLAG_RESERVED_1 = (1 << 1); + static uint8_t constexpr EXTENT_FLAG_RESERVED_2 = (1 << 2); + static uint8_t constexpr EXTENT_FLAG_RESERVED_3 = (1 << 3); + static uint8_t constexpr EXTENT_FLAG_IS_FAR_HINT = (1 << 4); ///< Contents maybe far + static uint8_t constexpr EXTENT_FLAG_RESERVED_5 = (1 << 5); + static uint8_t constexpr EXTENT_FLAG_RESERVED_6 = (1 << 6); + static uint8_t constexpr EXTENT_FLAG_RESERVED_7 = (1 << 7); + + // Return from 'extent_info'. + struct extab_entry { + uint32_t extent_flags; + uint32_t align; // a power of 2, >= 64 + uint64_t offset; // offset, in bytes, from the start of the descriptor, to where the data is. + uint64_t length; // length of the data in bytes. + }; + // Return from 'mempool_info'. + // Note: if 'adjust_offset' is true, the 'offset' field from the containing extent will be added to offset, + // so that the offset is from the start of the descriptor, instead of the start of the containing extent. + struct mempool_entry { + uint32_t mempool_id; // a mempool id >=2 indicating a const mempool + uint32_t extent_id; // an extent_id, >=1 + uint64_t offset; // offset in bytes of the data from the start of the extent (see note above) + uint64_t length; // length in bytes of the data + }; + // optional name of the const_extent this descriptor corresponds to. Used for matching in weight_sharing. + std::string name = std::string{}; + + ConstExtentDesc() {} + ConstExtentDesc(table_t &&table_in); + void serialize(Serializer &) const; + inline bool load_table(table_t &&table_in) + { + table = std::move(table_in); + return scan_table(); + } + + constexpr bool is_valid() const { return desc_len != 0; } + + constexpr unsigned descriptor_length() const { return desc_len; } + + constexpr unsigned num_extents() const { return extab_n; } + constexpr unsigned num_mempools() const { return mptab_n; } + + // unpack a row of the extent table + // NOTE: extent_id is 1-based, must be 1 .. num_extents() + extab_entry extent_info(unsigned extent_id) const; + + // unpack a row of the mempool table. + // note: idx is not a mempool idx, it is a 1-based row in range 1...num_mempools(); + // if adjust_offset, the offset of the containing extent is added to the offset + // of the mempool in the returned value. + mempool_entry mempool_info(unsigned idx, bool adjust_offset = false) const; + + // The ordering of the data and the descriptors is such that: + // + // (1) extent_info(1).offset >= descriptor_length() + // mempool_info(1,true).offset >= descriptor_length() + // (2) for i >=2, + // extent_info(i).offset >= extent_info(i+1).offset + extent_info(i+1).length + // mempool_info(i,true).offset >= mempool_info(1-1,true).offset + mempool_info(1-1).length + // + +#if !defined(PREPARE_DISABLED) + /// + /// @brief Memory pool record iterator + /// @details Use to iterator over records in memory pool table in constant + /// extent descriptor + /// + class mempool_iterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = ConstExtentDesc::mempool_entry; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + + /// + /// @brief Constructor + /// @param [in] cedesc A valid constant extent descriptor instance + /// @param [in] index Record index (zero-based!) + /// + explicit mempool_iterator(ConstExtentDesc const &cedesc, uint32_t index) : _cedesc(cedesc), _index(index) {} + + /// + /// @brief Increment record + /// @return Iterator + /// + mempool_iterator &operator++() + { + // Increment IFF valid constant extent descriptor and mempool record + // index within range + _index += (_cedesc.is_valid() && (_index < _cedesc.mptab_n)) ? 1 : 0; + return *this; + } + + /// + /// @brief Equality operator + /// @return true if iterators are equal + /// + bool operator==(mempool_iterator const &other) const { return _index == other._index; } + + /// + /// @brief Inequality operator + /// @return true if iterators are not equal + /// + bool operator!=(mempool_iterator const &other) const { return !(*this == other); } + + /// + /// @brief Dereference iterator + /// + reference operator*(); + + private: + /// + /// @brief Reference to a constant extent descriptor instance + /// @details It contains the blob representing constant extent segment + /// + ConstExtentDesc const &_cedesc; + + /// + /// @brief Current index + /// + uint32_t _index; + + /// + /// @brief Mempool record entry + /// @details It is assigned when on iterator dereference + /// + value_type _entry; + }; + + /// + /// @brief Return mempool iterator initialized to the first record + /// @return Mempool iterator + /// + mempool_iterator begin() { return mempool_iterator(*this, 0); } + + /// + /// @brief Return mempool iterator beyond the last record + /// @warning Intended to be used as a sentinel + /// @return Mempool iterator + /// + mempool_iterator end() { return mempool_iterator(*this, mptab_n); } +#endif +}; +#ifndef PREPARE_DISABLED +// Called at the end of serializing a graph, if 'const extent' mode is enabled. +// See comment in const_extent_descriptor.cc for full details. +// LCOV_EXCL_START [SAFTYSWCCB-1542] +size_t write_aligned_const_info(Graph const &gr, Serializer &sctx, unsigned buried_aux_n_words = 0); +#else +inline constexpr size_t write_aligned_const_info(Graph const &gr, Serializer const &sctx, unsigned = 0) +{ + return 0; +} +// LCOV_EXCL_STOP +#endif + +} // namespace hnnx + +#endif // CONST_EXTENT_DESCRIPTOR_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_shared.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_shared.h new file mode 100755 index 0000000000000..39c95e26ed561 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/const_extent_shared.h @@ -0,0 +1,81 @@ +//============================================================================== +// +// Copyright (c) 2024 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CONST_EXTENT_SHARED_H_ +#define CONST_EXTENT_SHARED_H_ + +namespace hnnx { +// definitions pertaining to the 'const extent descriptor'. + +constexpr unsigned CONST_EXTENT_DESC_MAGIC = 0x71c43c9b; +// if a const extent descriptor has a 'cbname' in it, the last 32-bit slot +// is this value. The 0x3e, 0x00 is the ">\0" at the end of the cbname +constexpr unsigned CONST_EXTENT_CBNAME_TAG = 0xebbe003e; + +// This must be a power of 2, and >= 64. +// This is effectively a 'quiet' minimum on options.serialize_const_alignment, which sets +// the actual alignment. +// It is not necessary for the decoder to know what value of alignment was used in the encoder. +constexpr unsigned CONST_EXTENT_MIN_ALIGN = 256; +// +// this is a (non-quiet) maximum on options.serialize_const_alignment +constexpr unsigned CONST_EXTENT_MAX_ALIGN = 1024 * 1024; + +/// +/// @brief Size of const extent descriptor header +/// +constexpr unsigned CONST_EXTENT_HEADER_SIZE_WORDS = 4u; +constexpr unsigned CONST_EXTENT_HEADER_SIZE_BYTES = CONST_EXTENT_HEADER_SIZE_WORDS * 4u; + +/// +/// @brief Size of an extent record +/// @details Const extent descriptor contains a table of such records +/// +constexpr unsigned CONST_EXTENT_RECORD_SIZE_WORDS = 4u; +constexpr unsigned CONST_EXTENT_RECORD_SIZE_BYTES = CONST_EXTENT_RECORD_SIZE_WORDS * 4u; + +/// +/// @brief Offset of extent record table relative to const extent descriptor +/// @details Both byte and words offsets are listed +/// +constexpr unsigned CONST_EXTENT_RECORD_TAB_OFFSET_WORDS = 4u; +constexpr unsigned CONST_EXTENT_RECORD_TAB_OFFSET_BYTES = CONST_EXTENT_RECORD_TAB_OFFSET_WORDS * 4u; + +/// +/// @brief Size of mempool record in a const extent descriptor +/// @details Both byte and word sizes are provided +/// +constexpr unsigned CONST_EXTENT_MEMPOOL_RECORD_SIZE_WORDS = 4u; +constexpr unsigned CONST_EXTENT_MEMPOOL_RECORD_SIZE_BYTES = CONST_EXTENT_MEMPOOL_RECORD_SIZE_WORDS * 4u; + +// This function is used by deserializer to help it extract the extent-desc table (as a vector) from some +// arbitrary point down the pickle. Parameter is a pointer to the first 4 words; the return value is +// 0 if the first two words do not look like CEDesc header; +// n otherwise (where 'n' is the number of 32-bit words to extract). +// +inline unsigned const_extent_hdr_check(uint32_t const *const hdrp) +{ + if (hdrp[0] != CONST_EXTENT_DESC_MAGIC) return 0; + const unsigned word0 = hdrp[1]; + const unsigned hdr_len16 = word0 >> 24u; // units of 16 bytes + const unsigned desc_len64 = word0 & 0xFFFFFFu; // units of 64 bytes + const unsigned n_extent = hdrp[2] & 0xFFFFFFu; + const unsigned n_mempool = hdrp[3] & 0xFFFFFFu; + // no. of words actually needed + const unsigned desc_words = 4 * (hdr_len16 + n_extent + n_mempool); + + // note, n_extent == n_mempool == 0 is allowed. + if (hdr_len16 == 0 || desc_len64 == 0 || n_extent > n_mempool || desc_words > desc_len64 * 16) { + return -1; + } + return desc_words; +} + +} // namespace hnnx + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/constraints.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/constraints.h new file mode 100755 index 0000000000000..b30f7b8f5c871 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/constraints.h @@ -0,0 +1,121 @@ +//============================================================================== +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CONSTRAINTS_H +#define CONSTRAINTS_H + +#include "interface_defs.h" +#include "op_def.h" + +#include +#include + +namespace constraint_lib { + +/** \defgroup OptConstraint Constraint Expressions for Optimization Rules + * \ingroup OptimizationFuncs + * + * @{ + */ +//! Find the chunksize of a given tensor type in a given dimension (a constant). +/// For instance, LAYOUT_CHUNKSIZE(QUint8CroutonTensor,3) gives size_t(32) +/// +#define LAYOUT_CHUNKSIZE(TYPENAME, IDX) (TYPENAME::layout.ChunkSizes[(IDX)]) + +// some convenience wrappers... + +//! IS_FLOAT16("operand") -> bool (true if operand has Float16 output) +#define IS_FLOAT16(X) EQ(DTYPE_OF(X), DType::Float16) + +//! IS_FLOAT32("operand") -> bool (true if operand has float output) +#define IS_FLOAT32(X) EQ(DTYPE_OF(X), DType::Float32) + +//! IS_FLOAT("operand") -> bool (alias of IS_FLOAT32) +#define IS_FLOAT(X) IS_FLOAT32(X) + +//! IS_QUINT8("operand") -> bool (true if operand has 'QUInt8' output) +#define IS_QUINT8(X) EQ(DTYPE_OF(X), DType::QUInt8) + +//! IS_QINT8("operand") -> bool (true if operand has 'QInt8' output) +#define IS_QINT8(X) EQ(DTYPE_OF(X), DType::QInt8) + +//! IS_QINT16("operand") -> bool (true if operand has 'QInt16' output) +#define IS_QINT16(X) EQ(DTYPE_OF(X), DType::QInt16) + +//! IS_QUINT16("operand") -> bool (true if operand has 'QUInt16' output) +#define IS_QUINT16(X) EQ(DTYPE_OF(X), DType::QUInt16) + +//! IS_QINT32("operand") -> bool (true if operand has 'QInt32' output) +#define IS_QINT32(X) EQ(DTYPE_OF(X), DType::QInt32) +//! IS_INT32("operand") -> bool (true if operand has 'Int32' output) +#define IS_INT32(X) EQ(DTYPE_OF(X), DType::Int32) + +//! IS_INT64("operand") -> bool (true if operand has 'Int64' output) +#define IS_INT64(X) EQ(DTYPE_OF(X), DType::Int64) + +//! IS_QUANT_TYPE("operand") -> bool (true if operand has 'Quantized' output) +#define IS_QUANT_TYPE(X) OR(IS_QUINT8(X), IS_QINT8(X), IS_QINT16(X), IS_QUINT16(X), IS_QINT32(X)) +//! IS_QUANT_SIGNED("operand") -> bool (true if operand has 'Signed Quantized' output) +#define IS_QUANT_SIGNED(X) OR(IS_QINT32(X), IS_QINT16(X), IS_QINT8(X)) +//! IS_SIGNED_SYMM("operand") -> bool (true if operand has 'Signed Quantized' output with offset == 0) +#define IS_SIGNED_SYMM(X) AND(IS_QUANT_SIGNED(X), EQ(ZERO_OFFSET_OF(X), 0)) + +// The problem with IS_SIGNED_SYMM is that it tends to get used as +// AND( IS_QINT8(X), IS_SIGNED_SYMM(X)) +// which expands to X.dtype==qint8 && ( (X.dtype ==qint32 || X.dtype == .. ) && X.zero_offs == 0) +// So, use IS_QINT8_SYMM(X) etc instead. + +//! IS_QINT8_SYMM("operand") -> bool (true if operand has QINT8 output with offset == 0) +#define IS_QINT8_SYMM(X) AND(IS_QINT8(X), EQ(ZERO_OFFSET_OF(X), 0)) +//! IS_QINT16_SYMM("operand") -> bool (true if operand has QINT16 output with offset == 0) +#define IS_QINT16_SYMM(X) AND(IS_QINT16(X), EQ(ZERO_OFFSET_OF(X), 0)) +//! IS_QINT32_SYMM("operand") -> bool (true if operand has QINT32 output with offset == 0) +#define IS_QINT32_SYMM(X) AND(IS_QINT32(X), EQ(ZERO_OFFSET_OF(X), 0)) + +//! IS_FULLY_CONNECT_WEIGHT("operand") -> bool (true if operand is QUInt8 or (QInt8 and symmetrically quantized)) +#define IS_FULLY_CONNECT_WEIGHT(X) OR(IS_QUINT8(X), IS_QINT8_SYMM(X)) + +//! IS_FLOAT16_BOTH("operand", "operand") -> bool (true if both operands are FP16 type) +#define IS_FLOAT16_BOTH(X, Y) AND(IS_FLOAT16(X), IS_FLOAT16(Y)) +//! IS_FLOAT16_ALL("operand", ...) -> bool (true if all operands are FP16 type) +#define IS_FLOAT16_ALL(...) IS_DTYPE_ALL(DType::Float16, __VA_ARGS__) +//! IS_FLOAT32_ALL("operand", ...) -> bool (true if all operands are FP32 type) +#define IS_FLOAT32_ALL(...) IS_DTYPE_ALL(DType::Float32, __VA_ARGS__) + +//! DIM_CHANNEL("operand") -> unsigned (extract depth dimension, #4) +#define DIM_CHANNEL(X) DIM_OF(X, 4) +//! DIM_DEPTH("operand") -> unsigned (extract depth dimension, #3) +#define DIM_DEPTH(X) DIM_OF(X, 3) +//! DIM_WIDTH("operand") -> unsigned (extract width dimension, #2) +#define DIM_WIDTH(X) DIM_OF(X, 2) +//! DIM_HEIGHT("operand") -> unsigned (extract height dimension, #1) +#define DIM_HEIGHT(X) DIM_OF(X, 1) +//! DIM_BATCHES("operand") -> unsigned (extract batches dimension, #0) +#define DIM_BATCHES(X) DIM_OF(X, 0) + +//! DIM_NFILTS("operand") -> unsigned (extract 'output depth' dimension from filter weights, #3) +#define DIM_NFILTS(X) DIM_OF(X, 3) +//! DIM_FILTDEPTH("operand") -> unsigned (extract 'input depth' dimension from filter weights, #2) +#define DIM_FILTDEPTH(X) DIM_OF(X, 2) +//! DIM_FILTWIDTH("operand") -> unsigned (extract 'filter width' dimension from filter weights, #1) +#define DIM_FILTWIDTH(X) DIM_OF(X, 1) +//! DIM_FILTHEIGHT("operand") -> unsigned (extract 'filter height' dimension from filter weights, #0) +#define DIM_FILTHEIGHT(X) DIM_OF(X, 0) + +#define MAX_SPARSE_ELEMENTS(X) DIM_OF(X, (MAX_DIMENSIONS - 1)) + +//! IS_EMPTY_DIM("operand", dim) -> bool (true if size of dim is 0) +#define IS_EMPTY_DIM(X, DIM) EQ(DIM_OF(X, DIM), 0) + +//! IS_EMPTY("operand") -> bool (true if size of all dims is 0) +#define IS_EMPTY(X) AND(IS_EMPTY_DIM(X, 0), IS_EMPTY_DIM(X, 1), IS_EMPTY_DIM(X, 2), IS_EMPTY_DIM(X, 3)) + +} // namespace constraint_lib +/** @} */ + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/conversions.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/conversions.h new file mode 100755 index 0000000000000..4cb348c637953 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/conversions.h @@ -0,0 +1,609 @@ +//============================================================================== +// +// Copyright (c) 2018 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef CONVERSIONS_H +#define CONVERSIONS_H + +#include +#include +#include +#include +#include + +#include "builtin_intrinsics.h" + +#ifdef __hexagon__ +#include "hexagon_protos.h" +#endif + +#include "float16.h" + +#if defined(__clang__) +#define ATTR_NO_SANITIZE(CATEGORY) __attribute__((no_sanitize(CATEGORY))) +#else +#define ATTR_NO_SANITIZE(CATEGORY) /*empty */ +#endif + +namespace hnnx { + +namespace scast { + +// for a given floating type F, and a integer type TI, +// intrange_within_float::max() +// generates the largest value representable in type F which will fit into TI without overflow. +// in many cases this is F(std::numeric_limits::max()), +// but there are exceptions when the mantissa of F is narrower than TI; in those cases we +// want the representable value which is smaller than the integer's max value, not the nearest: +// F TI +// Float16 int16 32752.0 (0x7ff0) +// Float15 uint16 65504.0 (0xffe0) +// float int32 2147483520.0 (0x7fffff80) +// float uint32 4294967040.0 (0xFFFFFF00) +// float int64 9.223371487e18 (0x7fff_ff80_0000_0000) +// float uint64 1.844674297e+19 (0xFFFF_FF00__0000_0000) +// double int64 9223372036854774784.0 (0x7FFF_FFFF_FFFF_FC00) +// double uint64 18446744073709549568.0 (0xFFFF_FFFF_FFFF_F800) +// +// All of the 'min' limits are zero or powers of 2, so those can be converted +// directly from std::numeric_limits::min() +// +// +template struct intrange_within_float { +}; + +// LCOV_EXCL_START [SAFTYSWCCB-1736] constexprs resolved during compile time +template struct intrange_within_float { + static_assert(std::numeric_limits::is_integer); + static inline constexpr Float16 max() + { + if constexpr (sizeof(TI) < 2) { + return Float16(std::numeric_limits::max()); + } else if constexpr (sizeof(TI) == 2) { + return std::numeric_limits::is_signed ? Float16(32752.0f) : Float16(65504.0f); + } else { + return std::numeric_limits::is_signed ? Float16(-65504.0f) : Float16(65504.0f); + } + } + // 'min' value of integer range is always exactly representable + static inline constexpr Float16 min() { return Float16(std::numeric_limits::min()); } +}; + +template struct intrange_within_float { + static_assert(std::numeric_limits::is_integer); + static inline constexpr float max() + { + if constexpr (sizeof(TI) < 4) { + return float(std::numeric_limits::max()); + } else if constexpr (sizeof(TI) == 4) { + return std::numeric_limits::is_signed ? 2147483520.0f : 4294967040.0f; + } else { + static_assert(sizeof(TI) == 8); + return std::numeric_limits::is_signed ? 9.223371487e18f : 1.844674297e+19f; + } + } + // 'min' value of integer range is always exactly representable + static inline constexpr float min() { return float(std::numeric_limits::min()); } +}; + +template struct intrange_within_float { + static_assert(std::numeric_limits::is_integer); + static inline constexpr double max() + { + if constexpr (sizeof(TI) < 8) { + return double(std::numeric_limits::max()); + } else { + static_assert(sizeof(TI) == 8); + return std::numeric_limits::is_signed ? 9223372036854774784.0 : 18446744073709549568.0; + } + } + // 'min' value of integer range is always exactly representable + static inline constexpr float min() { return double(std::numeric_limits::min()); } +}; +// LCOV_EXCL_STOP + +template struct satcast_helper { + static_assert(std::numeric_limits::is_specialized && std::numeric_limits::is_specialized); + static inline TOUT constexpr op(TIN val) + { + if constexpr (!std::numeric_limits::is_integer) { // convert to a float + return TOUT(val); + } else { + constexpr bool OUTS = std::numeric_limits::is_signed; + if constexpr (std::numeric_limits::is_integer) { + // integer to integer. + // widening? or same width, same signedness? + constexpr bool INS = std::numeric_limits::is_signed; + if (sizeof(TOUT) > sizeof(TIN) || (sizeof(TOUT) == sizeof(TIN) && OUTS == INS)) { + // if the output is unsigned and the input < 0, return 0 + // otherwise it's a normal cast. + return (!OUTS && INS && val < 0) ? TOUT(0) : TOUT(val); + } else if (sizeof(TOUT) == sizeof(TIN)) { + if (!OUTS) { // same size, different signs + return (val < 0) ? (TOUT)0 : (TOUT)val; // signed->unsigned + } else { + constexpr TIN lim = std::numeric_limits::max(); + return (val > lim) ? (TOUT)lim : (TOUT)val; + } + } else { + // narrowing conversion + if (!OUTS) { + constexpr TIN m = std::numeric_limits::max(); + return (val < 0) ? TOUT(0) : (val > m) ? TOUT(m) : TOUT(val); + } else { + constexpr TIN mn = INS ? std::numeric_limits::min() : 0; + constexpr TIN mx = std::numeric_limits::max(); + return (val < mn) ? TOUT(mn) : (val > mx) ? TOUT(mx) : TOUT(val); + } + } + } else { // float to integer + if constexpr (sizeof(TOUT) <= sizeof(int32_t)) { + if constexpr (OUTS) { + constexpr TIN loval = intrange_within_float::min(); + constexpr TIN hival = intrange_within_float::max(); + int32_t const tmp = (int32_t)std::max(loval, std::min(hival, val)); + return satcast_helper::op(tmp); + } else { + constexpr TIN loval = 0.0; + constexpr TIN hival = intrange_within_float::max(); + uint32_t const tmp = (uint32_t)std::max(loval, std::min(hival, val)); + return satcast_helper::op(tmp); + } + } else { // 64-bit output assumed + constexpr TIN loval = intrange_within_float::min(); + constexpr TIN hival = intrange_within_float::max(); + return (TOUT)std::max(loval, std::min(hival, val)); + } + } + } + } +}; +// specialize for conversion to same +template struct satcast_helper { + static_assert(std::numeric_limits::is_specialized); + static inline TT constexpr op(TT val) { return val; } +}; + +#ifdef __hexagon__ + +// saturate to types <= int. +template struct q6_sat_int { +}; +template <> struct q6_sat_int { + static inline int op(int x) { return Q6_R_satb_R(x); } +}; +template <> struct q6_sat_int { + static inline int op(int x) { return Q6_R_satub_R(x); } +}; +template <> struct q6_sat_int { + static inline int op(int x) { return Q6_R_sath_R(x); } +}; +template <> struct q6_sat_int { + static inline int op(int x) { return Q6_R_satuh_R(x); } +}; + +// TODO: these should be done again for 'long' if long is also 32 bits. +#if 0 // NOTE: we can't really do this unless intrinsics are constexpr +template <> struct satcast_helper { + static inline uint8_t /*constexpr*/ op(int val) + { + return Q6_R_satub_R(val); + } +}; +template <> struct satcast_helper { + static inline int8_t /*constexpr*/ op(int val) { return Q6_R_satb_R(val); } +}; +template <> struct satcast_helper { + static inline uint16_t /*constexpr*/ op(int val) + { + return Q6_R_satuh_R(val); + } +}; +template <> struct satcast_helper { + static inline int16_t /*constexpr*/ op(int val) { return Q6_R_sath_R(val); } +}; +#endif + +#endif +} // end namespace scast + +} // namespace hnnx + +/** + * @brief saturate_cast( TIN val ) will work on any two numeric types; + * if the input is outside the numeric range of the output type, it + * will be range-limited. + * + * it works as follows: + * * if TOUT is a floating type, the operation is the same as the C++ cast. + * * if TOUT is integer and TIN is float, the input is first converted + * to one of int32,uint32, int64, uint64 ensuring that out-of-range values + * are clipped; and then converted to the output type as below (if it is smaller + * than 32 bits) (The 2-step conversion is intended to work well when things + * are specialized to support native hexagon ops). + * * Otherwise they are both integers. + * - If the output width is larger than the input (or if they are the same size + * and of the same signedness): + * * if the output is unsigned, and the input is < 0, the result is zero + * * otherwise the result is the same as a C++ cast (all values representable) + * - Otherwise, it is a saturating cast; values are limited to the range of TOUT. + */ +template inline constexpr TOUT saturate_cast(TIN val) +{ + return hnnx::scast::satcast_helper::op(val); +} + +/** + * @brief T saturate_round( float val ) + * round val to nearest int, and saturate to range of T. + * + * T must be an integer type, at most 32 bits. + */ +// For general C platform, we need to clip the range before converting to int; +// for hexagon the conversions saturate. +// +#ifndef __hexagon__ +template inline TOUT saturate_round(float val) +{ + static_assert(sizeof(TOUT) <= 8 && std::numeric_limits::is_integer); + return saturate_cast(std::nearbyintf(val)); +} + +#else +template inline TOUT saturate_round(float val) +{ + static_assert(sizeof(TOUT) <= 8 && std::numeric_limits::is_integer); + if constexpr ((sizeof(TOUT) == 8) && !std::numeric_limits::is_signed) { + // convert to unsigned u64, rounding, saturating + return Q6_P_convert_sf2ud_R(val); + } else if constexpr ((sizeof(TOUT) == 8) && std::numeric_limits::is_signed) { + // convert to int64, rounding + return Q6_P_convert_sf2d_R(val); + } else if constexpr ((sizeof(TOUT) == 4) && !std::numeric_limits::is_signed) { + // convert to unsigned u32, rounding, saturating + return Q6_R_convert_sf2uw_R(val); + } else { + // convert to int32,rounding; + int const r = Q6_R_convert_sf2w_R(val); + if constexpr (sizeof(TOUT) < 4) return static_cast(hnnx::scast::q6_sat_int::op(r)); + return static_cast(r); // LCOV_EXCL_LINE [SAFTYSWCCB-1736] + } +} +#endif + +namespace hnnx { + +/** + * @brief 'proper' compare of any two integer types + * proper_gt( a, b) => a > b; + * E.g. if a is unsigned and b is signed, the operation checks to see if b is < 0; + * if so, the result is true; otherwise an unsigned compare is done: a > (unsigned)b + * + */ +namespace prpercmp { + +/** + * @brief if both A and B are either *int*, or smaller than int, + * then promote them both to int and compare them. + * + * otherwise, if TA is wider than TB, (or the same, with TA unsigned): + * promote b to TA, and then compare them. + * Exception, if TA is unsigned and TB is signed and b < 0; then a struct proper_cmp_helper { + static_assert(std::numeric_limits::is_integer && std::numeric_limits::is_integer); + static const bool ASIGNED = std::numeric_limits::is_signed; + static const bool BSIGNED = std::numeric_limits::is_signed; + + // compare by promoting both to int, when... + static const bool CMP_AS_INT = (sizeof(TA) < sizeof(int) || (sizeof(TA) == sizeof(int) && ASIGNED)) && + (sizeof(TB) < sizeof(int) || (sizeof(TB) == sizeof(int) && BSIGNED)); + // otherwise, compare by promoting B to A when ... + static const bool B_TO_A = sizeof(TA) > sizeof(TB) || (sizeof(TA) == sizeof(TB) && !ASIGNED); + // otherwise, compare by promoting A to B + + static inline bool constexpr eq(TA a, TB b) + { + if (CMP_AS_INT) { + return (int)a == (int)b; + } else if (B_TO_A) { + if (!ASIGNED && BSIGNED && b < 0) return false; + return a == (TA)b; + } else { + if (!BSIGNED && ASIGNED && a < 0) return false; + return (TB)a == b; + } + } + static inline bool constexpr lt(TA a, TB b) + { + if (CMP_AS_INT) { + return (int)a < (int)b; + } else if (B_TO_A) { + if (!ASIGNED && BSIGNED && b < 0) return false; // a < b always false if b<0 + return a < (TA)b; + } else { + if (!BSIGNED && ASIGNED && a < 0) return true; // a < b always true if a<0 + return (TB)a < b; + } + } +}; +/** + * @brief specialize for comparison to same type + */ +template struct proper_cmp_helper { + static_assert(std::numeric_limits::is_integer); + static inline bool constexpr eq(T a, T b) { return a == b; } + static inline bool constexpr lt(T a, T b) { return a < b; } +}; + +} // end namespace prpercmp + +} // namespace hnnx + +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value. + * proper_eq(a,b) => a == b; + * + * E.g. if a is signed and <0, and b is unsigned, result will always be false. + * + */ + +template inline bool constexpr proper_eq(TA a, TB b) +{ + return hnnx::prpercmp::proper_cmp_helper::eq(a, b); +} +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value + * proper_ne(a,b) => !proper_eq(a,b); + */ +template inline bool constexpr proper_ne(TA a, TB b) +{ + return !hnnx::prpercmp::proper_cmp_helper::eq(a, b); +} +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value + * proper_lt(a,b) => a inline bool constexpr proper_lt(TA a, TB b) +{ + return hnnx::prpercmp::proper_cmp_helper::lt(a, b); +} +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value + * proper_ge(a,b) => a>=b; + */ +template inline bool constexpr proper_ge(TA a, TB b) +{ + return !hnnx::prpercmp::proper_cmp_helper::lt(a, b); +} +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value + * proper_gt(a,b) => a>b; + */ +template inline bool constexpr proper_gt(TA a, TB b) +{ + return hnnx::prpercmp::proper_cmp_helper::lt(b, a); +} +/** + * @brief 'proper' compare of any two integer types, respecting signedness and actual numeric value + * proper_le(a,b) => a<=b; + */ +template inline bool constexpr proper_le(TA a, TB b) +{ + return !hnnx::prpercmp::proper_cmp_helper::lt(b, a); +} +/** + * @brief x >= lo && x < limit, using proper compares + */ +template inline bool constexpr proper_inrange(TA x, TB lo, TC limit) +{ + return proper_ge(x, lo) && proper_lt(x, limit); +} + +/** + * @brief x >= lo && x <= hi, using proper compares + */ +template inline bool constexpr proper_inrange_closed(TA x, TB lo, TC hi) +{ + return proper_ge(x, lo) && proper_le(x, hi); +} + +/** + * @brief find the 'width' of an unsigned value (# of bits needed to contain it) + * this is floor( log2(x))+1 + * (and 0 when x = 0) + * + */ +inline int constexpr binary_bitwidth(unsigned x) +{ + return (x == 0) ? 0 : (sizeof(unsigned) * 8 - HEX_COUNT_LEADING_ZERO(x)); +} +/** + * @brief find the 'width' of an unsigned long value (# of bits needed to contain it) + * this is floor( log2(x))+1 + * (and 0 when x = 0) + * + */ +inline int constexpr binary_bitwidth(unsigned long x) +{ + return (x == 0) ? 0 : (sizeof(unsigned long) * 8 - HEX_COUNT_LEADING_ZERO_UL(x)); +} +/** + * @brief find the 'width' of an unsigned long long value (# of bits needed to contain it) + * this is floor( log2(x))+1 + * (and 0 when x = 0) + * + */ +inline int constexpr binary_bitwidth(unsigned long long x) +{ + return (x == 0) ? 0 : (sizeof(unsigned long long) * 8 - HEX_COUNT_LEADING_ZERO_ULL(x)); +} +/** + * @brief saturating u32+u32 add + */ +inline uint32_t /*constexpr*/ addu32_sat(uint32_t a, uint32_t b) +{ + uint64_t const prod = (uint64_t)a + b; + return saturate_cast(prod); +} + +/** + * @brief saturating i32+i32 add + */ +inline int32_t /*constexpr*/ addi32_sat(int32_t a, int32_t b) +{ +#ifdef __hexagon__ + return Q6_R_add_RR_sat(a, b); +#else + int64_t prod = (int64_t)a + b; + return saturate_cast(prod); +#endif +} + +/** + * @brief saturating u32xu32 multiply + */ +inline uint32_t constexpr mulu32_sat(uint32_t a, uint32_t b) +{ + uint64_t const prod = (uint64_t)a * b; + return saturate_cast(prod); +} + +/** + * @brief saturating i32xi32 multiply + */ +inline int32_t constexpr muli32_sat(int32_t a, int32_t b) +{ + int64_t const prod = (int64_t)a * b; + return saturate_cast(prod); +} + +/** + * @brief saturating u64xu64 multiply + */ +inline uint64_t /*constexpr*/ mulu64_sat(uint64_t a, uint64_t b) +{ + uint64_t prod = 0; + if (HEX_MUL_OVERFLOW(a, b, &prod)) { + prod = std::numeric_limits::max(); + } + return prod; +} + +/** + * @brief saturating i64xi64 multiply + */ +inline int64_t /*constexpr*/ muli64_sat(int64_t a, int64_t b) +{ + int64_t prod = 0; + if (HEX_MUL_OVERFLOW(a, b, &prod)) { + prod = (int64_t(uint64_t(a) ^ uint64_t(b)) >= 0) ? std::numeric_limits::max() + : std::numeric_limits::min(); + } + return prod; +} +/** + * @brief add unsigned+unsigned->unsigned, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline unsigned constexpr addu32_modular(unsigned a, unsigned b) +{ + return a + b; +} +/** + * @brief subtract unsigned-unsigned->unsigned, escaping 'unsigned overflow' checks + * For '-unsigned_var', use subu32_modular(0,unsigned_var) + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline unsigned constexpr subu32_modular(unsigned a, unsigned b) +{ + return a - b; +} +/** + * @brief multiply unsigned*unsigned->unsigned, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline unsigned constexpr mulu32_modular(unsigned a, unsigned b) +{ + return a * b; +} +/** + * @brief mul-add u32*u32+u32->u32, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline unsigned constexpr muladdu32_modular(unsigned a, unsigned b, unsigned c) +{ + return a * b + c; +} + +/** + * @brief add u64+u64->u64, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline uint64_t constexpr addu64_modular(uint64_t a, uint64_t b) +{ + return a + b; +} + +/** + * @brief subtract u64-u64->u64, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline uint64_t constexpr subu64_modular(uint64_t a, uint64_t b) +{ + return a - b; +} +/** + * @brief mul u64*u64->u64, escaping 'unsigned overflow' checks + */ +ATTR_NO_SANITIZE("unsigned-integer-overflow") +inline uint64_t constexpr mulu64_modular(uint64_t a, uint64_t b) +{ + return a * b; +} + +/** + * @brief 'image' conversion from TIN to TOUT (which must be the same size) + * e.g. image_convert( 1.25f) -> 0x3fa00000 + */ + +template inline constexpr TOUT image_convert(TIN x) +{ + static_assert(sizeof(TOUT) == sizeof(TIN)); + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_trivially_constructible_v); + TOUT out; + std::memcpy(&out, &x, sizeof(TOUT)); + return out; +} + +// round up A to a multiple of B. +// b is expected to be > 0 even if signed. + +template inline constexpr size_t round_up(size_t a, TD b) +{ + static_assert(std::is_integral_v, "round_up can only apply to integer types"); + // for b being a power of 2, this should compile as (a+(b-1)) &~(b-1) + return b * ((a + (b - 1)) / b); +} +// for int, b is expected to be > 0; +// this will work for negative a, e.g. round_up(-53,10) -> -50 +template inline constexpr size_t round_up(int a, TD b) +{ + static_assert(std::is_integral_v, "round_up can only apply to integer types"); + int const bi = b; + int const tmp = a + ((a > 0) ? (bi - 1) : 0); + return bi * (tmp / bi); +} + +#endif /*CONVERSIONS_H*/ diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost.h new file mode 100755 index 0000000000000..8f0b21ccb86e5 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost.h @@ -0,0 +1,38 @@ +//============================================================================== +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef COST_H +#define COST_H 1 + +// NOTE: WHATCOST may be something like SNAIL/128 +#define COST_OF(FUNC, WHATCOST) COST_OF_OP(typename DerivedType<(FUNC)>::type, WHATCOST) +#define COST_OF_F(FUNC, WHATCOSTFN) COST_OF_OP_F(typename DerivedType<(FUNC)>::type, WHATCOSTFN) + +#ifdef PREPARE_DISABLED +#define COST_OF_OP(OP, WHATCOST) +#define COST_OF_OP_F(OP, WHATCOSTFN) +#else +#define COST_OF_OP(OP, WHATCOST) \ + template <> [[maybe_unused]] constexpr hnnx::cost_function_t hnnx::get_costf() \ + { \ + return hnnx::cost_function_t(float(StandardCosts::WHATCOST)); \ + } + +#define COST_OF_OP_F(OP, WHATCOSTFN) \ + template <> \ + float hnnx::cost_function_t::cfunc(hnnx::cost_function_t const &, const Graph &graph_in, const Op *op) \ + { \ + return WHATCOSTFN(graph_in, op); \ + } \ + template <> [[maybe_unused]] constexpr hnnx::cost_function_t hnnx::get_costf() \ + { \ + return hnnx::cost_function_t(hnnx::cost_function_t::cfunc, 1.0); \ + } +#endif + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost_funcs.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost_funcs.h new file mode 100755 index 0000000000000..286945b9b34b8 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/cost_funcs.h @@ -0,0 +1,56 @@ +//============================================================================= +// +// Copyright (c) 2020 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================ + +#ifndef COST_FUNCS_H +#define COST_FUNCS_H +#include +#include +#include "weak_linkage.h" +#include "macros_attribute.h" +PUSH_VISIBILITY(default) + +class Graph; +class Op; + +namespace hnnx { + +class API_EXPORT cost_function_t { + using inner_func_t = float (*)(cost_function_t const &, const Graph &, Op const *); + inner_func_t funcp; + float val; + + public: + cost_function_t(cost_function_t const &) = default; + cost_function_t &operator=(cost_function_t const &) = default; + constexpr explicit cost_function_t(float val_in) : funcp(simple_cost_function), val(val_in) {} + constexpr cost_function_t(inner_func_t f, float val_in) : funcp(f), val(val_in) {} + constexpr cost_function_t() noexcept : funcp(simple_cost_function), val(0.0f) {} + + inline float operator()(const Graph &graph_in, Op const *op) const { return (*funcp)(*this, graph_in, op); } + static float simple_cost_function(cost_function_t const &self, const Graph &, Op const *) + { + return self.val; + } // just returns val; + + float get_val() const { return val; } + + // unreliable compare for two cost func: returns -1,0,1 if this cost + // is <,=,> than rhs cost, with the second result being true; or <0,false> + // if it can't tell. + std::pair compare(cost_function_t const &rhs) const; + + template static float cfunc(cost_function_t const &, const Graph &, Op const *); +}; + +API_EXPORT cost_function_t cost_func_from_str(std::string_view); + +} // namespace hnnx + +POP_VISIBILITY() + +#endif diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/crate.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/crate.h new file mode 100755 index 0000000000000..494f51e40fa0f --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/crate.h @@ -0,0 +1,471 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +/* + * crate.h + * + * Created on: Aug 1, 2019 + * Author: smithg + */ + +#ifndef CRATE_H_ +#define CRATE_H_ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "is_detected.h" +#include "forward_classes.h" +#include "macros_attribute.h" +#include "weak_linkage.h" +#include "size_align_code.h" + +PUSH_VISIBILITY(default) + +class Graph; +class Tensor; + +/// @brief A 'Crate' allows construction of some number of different data types, +/// contiguously packed into a few large memory blocks. +/// +/// Example: +/// +/// Crate crt; +/// Thing tp* = crt.emplace( ... ctor parms for Thing ... ) +/// AnotherThing tp2* = crt.emplace( ... ctor parms for AnotherThing ... ) +/// +/// When the crate is destroyed, all of the contained objects are destroyed in the reverse +/// order. You cannot 'remove' a single entry using +/// +/// crt.erase has been deprecated +/// +/// However, this is likely not going to free any memory; it will just call the dtor of the +/// object (and make sure it doesn't get called later, when the Crate is cleared or destroyed). +/// +/// You can also emplace variable-sized arrays of trivially-destructable objects. +/// +/// alloc_array does not initialize: +/// +/// float * farr = crt.alloc_array(n); +/// +/// alloc_array_zero does zero-initializing: +/// +/// int * farr = crt.alloc_array_zero(n); +/// +/// If an allocation needs space larger than CHUNKBYTES, it will get its own chunk. +/// +// Each record containing an object has a non-null 'dtor' field; if the object is trivially destructible, +// this will be (dtor_funcp)1, and the object is not on the linked-list. +// +// note: +// A constructor may emplace additional records in the crate recursively. Likewise, +// it's OK if the dtors call erase() on other objects. If this happens during a 'clear', +// the erase calls are ignored since the other objects are going to get dtor'd anyhow (if they have not +// been already). +// Important: if object A's constructor places B into the crate, then B will very likely get destroyed +// first when the crate is cleared. Thus, A's destructor can't look at B (it can erase B, which is ignored +// as described above). + +// +// new 'raw' mode: +// - when the crate is in 'raw' mode, no destructors are registered. inserting an object +// increases 'alloc_count' in the chunk header, but does not increment 'nrec', nor any +// does it increase Crate::m_records. +// - raw mode is entered by enable_raw_mode(size_needed): +// which does this in addition to enabling raw mode: +// - if there is no current chunk, or if the current chunk doesn't have room for 'size_needed' bytes, +// a new chunk is added which does. +// - enable_raw_mode(size_needed) returns a chunk handle. +// +// Internally, raw_mode causes add_record_slot() to do the same thing, but it only moves alloc_count, it does +// not assign a slot index, and 'idx' is -1 in the returned struct. +// All callers of add_record_slot() *must* check for raw mode (can be done by checking idx < 0), and then avoid +// adding an dtor or doing '++m_records'. +// +// it's also possible to call .enable_raw_mode(), disable_raw_mode() +// but .enable_raw_mode() does nothing if there isn't at least one chunk allocated. +// + +namespace hnnx { + +// +// This is used to statically determine whether a type T has a clear(Graph&) +// method. This is used as an additional destructor which takes a Graph +// reference. +// + +template using clear_t = decltype(std::declval().clear(std::declval())); + +template constexpr bool has_clear = is_detected_v; + +class Deserz; +class DCrate; + +class Crate { + API_EXPORT static constexpr size_t CHUNKBYTES = (1 << 16); + static_assert(CHUNKBYTES % 8 == 0 && CHUNKBYTES >= 128); + typedef void (*dtor_funcp)(Graph *graph_in, void *); + API_EXPORT static dtor_funcp DTOR_TRIVIAL() { return (dtor_funcp)1; } + API_EXPORT static dtor_funcp DTOR_IN_PROCESS() { return (dtor_funcp)2; } + + //! A record in the index of a chunk + struct index_rec { + unsigned loc; ///< offset in bytes to the object + dtor_funcp + dtor; ///< pointer to dtor function (null if empty record; (DTOR_TRIVIAL if the object is trivial dtor) + }; + //! A chunk record in the crate. + /// + /// Each chunk is created as an array of uint64_t, via make_unique + /// The memory in a chunk has a chunkhdr, which is followed by: + /// + /// [Objects][Objects][Objects]--> free space <--[Index records] + /// + /// 'alloc_count' is the next offset available to be allocated. + /// index records are entered in reverse order from the end. So, the last nrec*sizeof(index_rec) + /// bytes of the area, are the index. + /// + typedef std::unique_ptr uptr_chunk_t; + struct chunkhdr; + API_EXPORT static chunkhdr *hdr_of(uptr_chunk_t &p) { return reinterpret_cast(p.get()); } + API_EXPORT static chunkhdr const *hdr_of(uptr_chunk_t const &p) + { + return reinterpret_cast(p.get()); + } + /// The chunkhdr is the first portion of the chunk, and is immediately followed + /// by data_len bytes, which is a multiple of 8. + struct API_EXPORT alignas(8) chunkhdr { + unsigned data_len; ///< length of the data area following header, bytes (>=CHUNKBYTES). + unsigned nrec; ///< records in use (including deleted ones) + unsigned alloc_count; ///< offset of first byte in 'free space' + // init to a given length (header not included) + void init(unsigned length) + { + data_len = length; + nrec = 0; + alloc_count = 0; + } + // reset (preserve data_len) + void init() + { + nrec = 0; + alloc_count = 0; + } + // pointer to 'offs ' within data area + inline uint8_t *get_ptr(unsigned offs) { return (uint8_t *)(this + 1) + offs; } + // pointer to end of the allocation + inline uint8_t *get_end_ptr() { return (uint8_t *)(this + 1) + data_len; } + // amount of space remaining + inline size_t space_avail() const { return data_len - alloc_count - nrec * sizeof(index_rec); } + // get pointer to an index record. + // record 0 is the last (oldest) one. + index_rec *index_p(int idx) { return (index_rec *)get_end_ptr() - (idx + 1); } + static uptr_chunk_t allocate(unsigned len); + }; + std::vector m_chunks; /// < chunks with data + std::vector m_free; /// < chunks without + typedef std::vector::iterator chunk_iter; + + bool m_rawmode = false; + bool m_clearing = false; ///< set while clearing. + size_t m_allrecords = 0; ///< includes removed and 'padding' records + size_t m_records = 0; ///< only actual, non-erased records. + + //! Returned from add_record_slot (which is used to create a new record) + struct recposn { + chunkhdr *chunkp; ///< the chunk in which it was found + void *objp; ///< pointer to the object + int idx; ///< index within the chunk (= -1 if insert was done in raw mode) + }; + API_EXPORT recposn add_record_slot(size_t bytes, size_t align); + API_EXPORT void recover_ctor_throw(recposn const &) noexcept; + API_EXPORT void install_dtor(recposn const &, dtor_funcp dtor_func); + API_EXPORT void move_to_free(chunk_iter chunk_to_free); + + public: + class ChunkHandle { + friend class Crate; + chunkhdr *chunkp; + + protected: + ChunkHandle(chunkhdr *cp) : chunkp(cp){}; + + public: + ChunkHandle() : chunkp(nullptr) {} // null handle may only be assigned-to + ChunkHandle(ChunkHandle const &) = default; + ChunkHandle &operator=(ChunkHandle const &) = default; + friend inline bool operator==(ChunkHandle const &a, ChunkHandle const &b) { return a.chunkp == b.chunkp; } + std::pair get_memory_extent() const + { + size_t const len = chunkp->get_ptr(chunkp->alloc_count) - (uint8_t *)chunkp; + return {chunkp, len}; + } + }; + + API_EXPORT Crate(); ///< Construct a new Crate + Crate(Crate const &) = delete; + Crate &operator=(Crate const &) = delete; + + // get the preload handle for the first chunk + ChunkHandle first_chunk_handle() const + { + return ChunkHandle(m_chunks.empty() ? nullptr : hdr_of(const_cast(*this).m_chunks.front())); + } + // get the preload handle for the most recent chunk + ChunkHandle last_chunk_handle() const + { + return ChunkHandle(m_chunks.empty() ? nullptr : hdr_of(const_cast(*this).m_chunks.back())); + } + // 'raw mode' + ChunkHandle enable_raw_mode(unsigned bytes_needed); + API_EXPORT void enable_raw_mode(); + void disable_raw_mode() { m_rawmode = false; } + bool raw_mode() const { return m_rawmode; } + + // Note that the destructor doesn't do anything. You have to call clear() manually. + API_EXPORT ~Crate(); + //! The number of objects in the crate. + size_t size() const { return m_records; } + //! The number of chunks in use + size_t chunk_count() const { return m_chunks.size(); } + //! The amount of space left in the current chunk, approximately. + /// DO NOT CALL unless chunk_count() > 0 + size_t current_chunk_space_remain() const { return hdr_of(this->m_chunks.back())->space_avail(); } + //! Delete all objects. Does not necessarily free all storage to the + /// system; but all retained storage is availabe for re-use in the crate. + /// Note that this is no longer called by the destructor- it must be called explicitly. + API_EXPORT void clear(Graph *graph_in); + // Special entry for deserialzing in segments. + // If it is possible to allocate, in current raw-mode chunk, everything from offset 'start' + // up to but not including 'limit', this is done, and the base address of that region is returned. + // otherwise does nothing and returns null. + API_EXPORT void *allocate_bulk(size_t start, size_t limit); + + //! Construct an object of type T into the crate, using the + /// parameters of any constructor of T. It is acceptable for the + /// constructor to call the emplace method to add other objects to + /// the crate. + template API_HIDDEN T *emplace(Args &&...args) + { + recposn const pos = add_record_slot(sizeof(T), alignof(T)); + // construct the object + if constexpr (std::is_nothrow_constructible::value) { + new (pos.objp) T(std::forward(args)...); + } else { + try { + new (pos.objp) T(std::forward(args)...); + } catch (const std::exception &e) { + recover_ctor_throw(pos); + throw; + } + } + if (pos.idx >= 0) { + // register destructor + if constexpr (!std::is_trivially_destructible::value) { + // Obtain a callable '~T()' function. + // this typically generates a jump, or a small inline; lambda can + // be cast to a function pointer since it has no state. + auto dtor_func = [](Graph *graph_in, void *obj) { + if constexpr (has_clear) { + static_cast(obj)->clear(graph_in); + } + static_cast(obj)->~T(); + }; + install_dtor(pos, (dtor_funcp)dtor_func); + } else { + ++m_records; // note, install_dtor does this too. + } + } + return static_cast(pos.objp); + } + + using deserialize_op_func = void *(*)(void *, Deserz &); + using deserialize_dtor_func = void (*)(Graph *, void *); + + // Alternate interface to cut down on template instantations: + // init_func is used to initialize the memory, and dtor_func + // is is used to register the destructor. It's up to the user + // to provide the correct size and alignment. + + API_EXPORT void *emplace_explicit(Deserz &dctx, deserialize_op_func init_func, deserialize_dtor_func dtor_func, + size_align_code_t size_al); + + //! Allocate 'n' of type T in the crate. + /// Will initially be garbage; T must be trivially destructable (unless waived) + template T *alloc_array(size_t n) + { + static_assert(DTOR_OK || std::is_trivially_destructible::value); + if (n == 0) return nullptr; + recposn const pos = add_record_slot(sizeof(T) * n, alignof(T)); + if (pos.idx >= 0) m_records++; + return static_cast(pos.objp); + } + //! Allocate 'n' of type T in the crate. + /// Will be zero-filled; T must be trivially destructable. + template T *alloc_array_zero(size_t n) + { + T *const res = alloc_array(n); + if (n != 0) ::memset(res, 0, sizeof(T) * n); + return res; + } + //! Allocate 'n' of type T in the crate. + /// Will be "value constructed"; in case of things like int and pointer, + /// this means they will be zeroed. + /// + /// T must be trivially destructable. + template T *alloc_array_value(size_t n) + { + T *res = alloc_array(n); + if (n != 0) std::uninitialized_value_construct_n(res, n); + return res; + } +}; + +/* + * EJP: This seems silly, but I don't know how to get visibility into Graph into a templated Tensor because of include hell. + */ + +API_EXPORT Crate *graph_crate(Graph &graph_in); + +// +// replacement for vector, for use in ops; + +// +// limited options for constructor: +// (1) copy, or move, from vector - need Graph *; +// (2) create with a given size, null-initialized; - need Graph *; +// (3) create empty, and then fill in later +// using init( Graph* , std::vector const &) +// or init( Graph* , std::vector &&) +// or init( Graph *, size ) +// or init( Graph *, T const *ptr, size ); +// or init_move( Graph *, T *ptr, size ); + +// With option 3, it assumed that the 'init' is done during the constructor of +// a host object - this is needed during deserialize, for instance. +// the 'len' is 32 bits so this type occupies 2 pointers, vs. 3 for std::vector. +// +// If 'T' has a destructor, the cratevec's destructor will invoke that on +// each element of the vector, in reverse order. +// when the 'move-from' mechanisms to init from 'std::vector && are used, +// the supplied vector will not be cleared; but its elements will all be +// 'moved-from'. + +template class cratevec { + T *m_ptr; + unsigned m_len; + using vec_t = std::vector; + static constexpr bool need_dtor = !std::is_trivially_destructible::value; + + public: + using iterator = T *; + using const_iterator = T const *; + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + using reference = T &; + using const_reference = T const &; + + cratevec() : m_ptr(nullptr), m_len(0) {} + cratevec(Graph *g, vec_t const &v) : cratevec() + { + if (!v.empty()) init(g, v.data(), v.size()); + } + cratevec(Graph *g, vec_t &&v) : cratevec() + { + if (!v.empty()) init_move(g, v.data(), v.size()); + } + cratevec(Graph *g, size_t n) : cratevec() { init(g, n); } + cratevec(cratevec const &) = delete; + cratevec(cratevec &&) = delete; + ~cratevec() + { + if constexpr (need_dtor) { + if (m_len > 0) { + T *const ptr0 = m_ptr; + T *ptr = ptr0 + m_len; + do { + ptr--; + ptr->~T(); + } while (ptr > ptr0); + } + } + } + + cratevec &operator=(cratevec const &) = delete; + cratevec &operator=(cratevec &&) = delete; + + void init(Graph *g, T const *data, size_t n) + { + assert(m_len == 0); + if (n) { + m_ptr = graph_crate(*g)->alloc_array(n); + std::uninitialized_copy_n(data, n, m_ptr); + m_len = n; + } + } + void init_move(Graph *g, T *data, size_t n) + { + assert(m_len == 0); + if (n) { + m_ptr = graph_crate(*g)->alloc_array(n); + std::uninitialized_move_n(data, n, m_ptr); + m_len = n; + } + } + // these methods get used during deserialize, so allow it to pass crate in directly. + void init(hnnx::Crate *const crate_p, size_t const n) + { + assert(m_len == 0); + if (n) { + m_ptr = crate_p->alloc_array(n); + std::uninitialized_value_construct_n(m_ptr, n); + m_len = n; + } + } + // The DCrate version is defined in dcrate_inlines.h + void init(hnnx::DCrate *crate_p, size_t n); + + void init(Graph *const g, size_t const n) { init(graph_crate(*g), n); } + void init(Graph *const g, vec_t const &v) { init(g, v.data(), v.size()); } + void init(Graph *const g, vec_t &&v) { init_move(g, v.data(), v.size()); } + + iterator begin() noexcept { return m_ptr; } + iterator end() noexcept { return m_ptr + m_len; } + const_iterator begin() const noexcept { return m_ptr; } + const_iterator end() const noexcept { return m_ptr + m_len; } + const_iterator cbegin() const noexcept { return m_ptr; } + const_iterator cend() const noexcept { return m_ptr + m_len; } + size_type size() const noexcept { return m_len; } + T *data() noexcept { return m_ptr; } + T const *data() const noexcept { return m_ptr; } + bool empty() const noexcept { return m_len == 0; } + reference operator[](size_type idx) { return m_ptr[idx]; } + const_reference operator[](size_type idx) const { return m_ptr[idx]; } + reference at(size_type idx) + { + if (idx >= m_len) throw std::range_error("cratevec"); + return m_ptr[idx]; + } + const_reference at(size_type idx) const { return const_cast(*this).at(idx); } + reference front() { return m_ptr[0]; } + const_reference front() const { return m_ptr[0]; } + reference back() { return m_ptr[m_len - 1]; } + const_reference back() const { return m_ptr[m_len - 1]; } +}; + +} // namespace hnnx + +POP_VISIBILITY() + +#endif /* CRATE_H_ */ diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/dcrate_inlines.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/dcrate_inlines.h new file mode 100755 index 0000000000000..a48e7bc909904 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/dcrate_inlines.h @@ -0,0 +1,101 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef DCRATE_INLINES_H +#define DCRATE_INLINES_H 1 + +#include +#include +#include + +#include "macros_attribute.h" +#include "deser_concurrent.h" +#include "crate.h" + +namespace hnnx { + +// alloc 'amount' bytes with given alignment. +inline void *DCrate::do_alloc(const size_t align, const size_t amount) +{ + size_t basep = size_t(nextp); + if (align > 4) { + basep = (basep + (align - 1)) & ~(align - 1); + } + size_t const next_base = basep + amount; + if (next_base > (size_t)limitp) return nullptr; + nextp = (void *)next_base; // update 'nextp' ... + return (void *)basep; +} + +template inline T *DCrate::alloc_array(const size_t n) +{ + if (nextp != nullptr) { + void *const allocp = do_alloc(alignof(T), sizeof(T) * n); + if (allocp) return (T *)allocp; + } + return cratep->alloc_array(n); +} + +template inline T *DCrate::emplace(Args &&...args) +{ + if (nextp != nullptr) { + void *const allocp = do_alloc(alignof(T), sizeof(T)); + if (allocp) { + new (allocp) T(std::forward(args)...); + return (T *)allocp; + } + } + return cratep->emplace(std::forward(args)...); +} + +template <> +inline void *DCrate::emplace_explicit(Deserz &dctx, deserialize_op_func const init_func, + deserialize_dtor_func const dtor_func, size_align_code_t const size_al) +{ + if (nextp != nullptr) { + void *const allocp = do_alloc(size_al.align(), size_al.size()); + if (allocp) { + init_func(allocp, dctx); + return allocp; + } + } + return cratep->emplace_explicit(dctx, init_func, dtor_func, size_al); +} + +// this will be used in place of 'emplace' when the constructor parms +// are just 'Deserz &' +template inline T *DCrate::emplace0(Deserz &dctx) +{ + deserialize_op_func const ctor = [](void *const ptr, Deserz &dctx) -> void * { + new (ptr) T(dctx); + return ptr; + }; + if (nextp != nullptr) { + void *const allocp = do_alloc(alignof(T), sizeof(T)); + if (allocp) { + (ctor)(allocp, dctx); + return (T *)allocp; + } + } + return (T *)cratep->emplace_explicit(dctx, ctor, nullptr, size_align_code_t::for_type()); +} +// init method of cratevec using 'Dcrate' is declared here to avoid header inclusion madness. +// +template inline void hnnx::cratevec::init(hnnx::DCrate *crate_p, size_t n) +{ + assert(m_len == 0); + if (n) { + m_ptr = crate_p->alloc_array(n); + std::uninitialized_value_construct_n(m_ptr, n); + m_len = n; + } +} + +} // namespace hnnx + +#endif // DCRATE_INLINES_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent.h new file mode 100755 index 0000000000000..16db21a082cf1 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent.h @@ -0,0 +1,288 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef DESER_CONCURRENT_H +#define DESER_CONCURRENT_H 1 + +#include +#include +#include +#include +#include +#include +#include + +#include "deser_concurrent_defs.h" + +// this is intended to be included only in "deserialize.h" + +struct PreloadInfo; + +namespace hnnx { +struct runlist_seg_descriptor; +class Crate; +class Deserz; +class fixup_supplemental_recs; +class InitTimeSchedule; + +// describes a 'span' of the deserialized data +struct deser_segment_span { + void *base; + void *limit; +}; + +// This describes a partially-decoded segment; includes fixups. +// This should stay small so we can place it inside Deserz, and std::move it +// out (to keep the fixup list) when done with the segment. +struct runlist_fixup_state { + unsigned segno = 0; + size_t *crate_begin = nullptr; // where the data starts in the crate + runlist_seg_descriptor *seg_desc = nullptr; // Corresponding 'runlist_seg_descriptor' for reference. + // The next three are copied from the runlist_auxdata_seg_desc + uint32_t base_tensor_index = 0; // first tensor index defined this segment + uint32_t base_blocktable_index = 0; // first blocktable index defined in this segment + uint32_t base_sharedobj_index = 0; // first 'shared_object' index defined in this segment + // fixup data + size_t *fixup_list_head = nullptr; // head of the 'fixup list', or null if none. + fixup_supplemental_recs *fixup_supplemental; // supplemental fixup list + + runlist_fixup_state() = default; + ~runlist_fixup_state() = default; + runlist_fixup_state(runlist_fixup_state const &) = default; + // *Some* implementations of c++lib require this to have operator= (non-move) + // in order for std::vector containing it to be constructed via resize. + runlist_fixup_state &operator=(runlist_fixup_state const &) = default; + // the move-ctor and move-assign must leave the source with no fixup list, + // and segno = 0. + runlist_fixup_state(runlist_fixup_state &&from) { do_move_from(std::move(from)); } + runlist_fixup_state &operator=(runlist_fixup_state &&from) + { + do_move_from(std::move(from)); + return *this; + } + + private: + // this is used in move-constructor and move-assign; it will always leave 'from' + // with certain 'null' values to trap cases where we're using the wrong instance. + void do_move_from(runlist_fixup_state &&from) + { + segno = from.segno; + crate_begin = from.crate_begin; + seg_desc = from.seg_desc; + base_tensor_index = from.base_tensor_index; + base_blocktable_index = from.base_blocktable_index; + base_sharedobj_index = from.base_sharedobj_index; + fixup_list_head = from.fixup_list_head; + fixup_supplemental = from.fixup_supplemental; + from.segno = 0; + from.seg_desc = nullptr; + from.fixup_list_head = nullptr; + } +}; +// +// This contains 'supplemental' fixup records for a segment; there is one instance in each runlist_seg_descriptor, +// and a pointer to in the runlist_fixup_state. When the 'runlist_fixup_state' is moved in or out of the Deserz, +// the pointer to this remains. +// To avoid the overhead of vec_push_back, this // has a static array into which values are recorded; +// when this is full (or near full), all the records within are appended to the vector in a single operation. +// At the end of the operation, any remaining records are appended to the vector, but only if the vector +// is not empty (we can read the records out of the fixed array, if they all fit). +// +// The append() is not safe unless 'ensure_room_for' is checked first; you can e.g. do ensure_room_for(3) +// ahead of doing up to 3 append +// It is best to use a constant as parameter to ensure_room_for, i.e. ahead of code which may append +// *up to* 4 values, use ensure_room_for(4); this simplifies the inline expansion of 'ensure_room_for', +// and makes very little difference to performance compared to using the exact value. +// +class fixup_supplemental_recs { + static constexpr unsigned ARR_SIZE = 64; + unsigned num_in_arr = 0; + uint32_t fixed_arr[ARR_SIZE]; + std::vector var_arr; + unsigned n_vec = 0; // = var_arr.size() + + public: + void clear(); + unsigned constexpr size() const { return num_in_arr + n_vec; } + void reserve(unsigned const n) { var_arr.reserve(n); } + inline void ensure_room_for(unsigned const n) + { + assert(n <= ARR_SIZE); + if (num_in_arr > ARR_SIZE - n) flush_to_vec(); + } + // append allowed only when preceded by 'ensure_room_for' + inline void append(uint32_t const val) + { + assert(num_in_arr < ARR_SIZE); + fixed_arr[num_in_arr++] = val; + } + // use instead of 'ensure_room_for(1); push_back(n)' + inline void push_back(uint32_t const val) + { + if (num_in_arr > ARR_SIZE - 1) flush_to_vec(); + fixed_arr[num_in_arr++] = val; + } + // After all push_back() done, do a 'finish' + // and then get_limits() can be used to traverse the data. + void finish(); // flushes, but only if the vec is not empty. + std::pair get_limits() const; + + protected: + void flush_to_vec(); +}; + +// An array of these (size N+1) is used to hold the +// information used in deserializing each each segment. +// The [N+1] is partially used; some operations may use +// e.g. arr[i+1].auxinfo.some_field to find out where something +// ends for the current segment, using the start of the next segment; +// so N-1 entry needs a next. + +struct runlist_seg_descriptor { + runlist_auxdata_seg_desc auxinfo; // the data from the 'aux_data' record for this segment + runlist_fixup_state segfixup; // the deserialization state (moved in and out of Deserz as needed) + fixup_supplemental_recs fixup_supp; // fixup supplemental recs. + deser_segment_span span_to_deser = {}; + // These are used to configure the last preload in each segment, which preloads a region + // which is either partially, or entirely, in the next segment. So, the first two entries + // below are actually set at the end of deserialization of the previous segment; the end_preload + // is set by the current segment deserialize. + // The information stored in [N] is for configuring + // the last preload in the last segment, with end_preload set to 'end of crate'; in this case + // start_preload could be <= the end of the crate, and then we don't configure it. + // likewise the information in [0] is only 'end_preload', which can be used to configure + // 'Graph::m_initial_preload' (it should go from start-of-crate to seg[0].end_preload). + // In some cases (hopefully, only in testing) we may have segments with no preloads in them, + // in which case null pointers will appear in some of these; the ChunkPreload ops need to + // configured by getting info from adjacent segments. + PreloadInfo *prev_seg_final_preload{}; // points to the prev segments' final PreloadInfo + char *start_preload{}; // the preload start address for prev seg's final preload + char *end_preload{}; // end address for prev seg's final preload +}; + +// One instance of this is in Deserializer, called segments. +// It is created 'empty', and populated when we encounter the valid +// Aux Data record. +// +class DeserSegDescs { + unsigned n_segs = 0; + // points to an array of n_seg + 1, if n_segs > 0 + std::unique_ptr seg_arr; + + public: + DeserSegDescs() = default; + ~DeserSegDescs() = default; + DeserSegDescs(DeserSegDescs const &) = delete; + DeserSegDescs(DeserSegDescs &&) = default; + DeserSegDescs &operator=(DeserSegDescs const &) = delete; + DeserSegDescs &operator=(DeserSegDescs &&) = default; + + // these two are used to create the array + void set_size(unsigned const n); // used to create sized, empty array + runlist_seg_descriptor *data() { return seg_arr.get(); } + + constexpr unsigned num_segs() const { return n_segs; } + constexpr bool is_active() const { return n_segs != 0; } + // note: 'i' may be 0 .. num_segs(); only can use when 'is_active'. + runlist_seg_descriptor &operator[](unsigned const i) { return seg_arr[i]; } + runlist_seg_descriptor const &operator[](unsigned const i) const { return seg_arr[i]; } + + // We can add other data in here, to manage the concurrent deserialization. + unsigned n_threads = 0; // set when allocating the 'Deserz' array + std::vector deserz_arr; // sized as 'n_threads'. + + // start-of-crate, rounded to a multiple of 32; Calculated before any multi-thread + // operations. Use to configure Graph::m_initial_preload. + void *crate_preload_start_boundary; + // end-of-crate, rounded up to multiple of 32. Calculated before any multi-thread + // operations. No 'ChunkPreloadOp' will exceed this. + void *crate_preload_final_boundary; + + InitTimeSchedule *initSchedule; +}; + +// A 'DCrate' is a proxy object stored within Deserz. +// It has some of the same methods as Crate; but if nextp is not null, +// it will allocated into the space at 'nextp', limited by 'limitp' +// Otherwise it will use the Crate. +// Most methods are defined as inlines in dcrate_inlines,h +// +class DCrate { + // these are either both null, or both non-null and 4-aligned. + void *nextp = nullptr; + void *limitp = nullptr; + Crate *cratep = nullptr; + + public: + DCrate() {} + ~DCrate() {} + DCrate(DCrate const &) = default; + DCrate(DCrate &&) = default; + DCrate &operator=(DCrate const &) = default; + DCrate &operator=(DCrate &&) = default; + explicit DCrate(Crate &c) : cratep(&c) {} + void set_crate(Crate &c) { cratep = &c; } + Crate *crate() { return cratep; } + bool is_active() const { return nextp != nullptr; } + + constexpr size_t bytes_remaining() const { return (char *)limitp - (char *)nextp; } + char *next_loc() { return (char *)nextp; } + std::pair range_remain() { return {(char *)nextp, (char *)limitp}; } + + void set_memory_range(void *base, unsigned len) + { + nextp = base; + limitp = (void *)((char *)base + len); + } + void remove_memory_range() + { + nextp = nullptr; + limitp = nullptr; + } + + // Methods of Crate we want to support (See crate.h for more more detail). + // Note that the constructors invoked in 'emplace' and 'emplace_explicit' + // can and will recursively call 'emplace' to construct their sub-objects. + template T *emplace(Args &&...args); + // variant of 'emplace' which can use the 'emplace_explicit' call to avoid + // instantiating the constructor twice + template T *emplace0(Deserz &dctx); + // (this is defined with 'template' args, only so it can be declared here without + // forward refs. All are pass-by-value. Only one specialization will be defined). + template void *emplace_explicit(Deserz &dctx, FI, FD, SA); + // array allocation, used to make all arrays in crate during deserialize. + template T *alloc_array(size_t n); + + private: + // reserve the specified data in the range, and return pointer to start; or + // return null if not possible. + void *do_alloc(size_t align, size_t amount); +}; + +// defines the encoding in the upper 3 bits of the last word of a 'multi-word' supplemental record +// all must be 4..7, since a 0 in the msb indicates a 'short' record. + +constexpr unsigned SUPPFIXUP_CAT_tensor = 4; +constexpr unsigned SUPPFIXUP_CAT_sharedobj = 5; +constexpr unsigned SUPPFIXUP_CAT_blocktable = 6; // with indices packed in one word +constexpr unsigned SUPPFIXUP_CAT_blocktable_full = 7; // .. in two words +constexpr unsigned SUPPFIXUP_CAT_SHIFT = 29u; + +bool fixup_encode_for_blocktable(runlist_fixup_state &seginfo, uint32_t idx, uint32_t table_offs, void **ptrloc); + +// high-level operations in the 'deserialize by segments' code. + +GraphStatus do_multiseg_deser(Deserializer &dctx, size_t ref_deser_pos); +GraphStatus segmentjob_deserialize_ops(Deserializer &dctx, unsigned segno, unsigned threadno); +GraphStatus segmentjob_process_fixups(Deserializer &dctx, unsigned segno, unsigned threadno); +GraphStatus segmentjob_compile_ops(Deserializer &dctx, unsigned segno, unsigned threadno); +void resolve_chunk_preload_after_multiseg_deser(Deserializer &dctx); + +} // namespace hnnx + +#endif // DESER_CONCURRENT_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent_defs.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent_defs.h new file mode 100755 index 0000000000000..3d72ed7d2de71 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deser_concurrent_defs.h @@ -0,0 +1,97 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef DESER_CONCURRENT_DEFS_H +#define DESER_CONCURRENT_DEFS_H 1 + +#include +#include + +namespace hnnx { + +// NOTE: this file contains defs for concurrent deserialize which are needed on both decode and prepare +// side; mostly just the format of the Aux Data records. +// Defs needed only on decode side are in 'deser_concurrent.h', which #includes this file. + +constexpr unsigned DesConcur_MIN_SEGMENTS = 8; // can't have less than this number. + +// This is the number of runlist slots in the runlist_auxdata_seg_desc format. +// It must be >= the actual number. This number is coded into the start of the AuxData +// payload. If the number gets bigger, the reader of the aux-data +// record will need to be able to cope with the older, smaller value. + +constexpr unsigned DesConcur_MAX_RUNLISTS = 4; + +// The 'Aux Data' record describing the runlist partition has a payload formed of +// a runlist_auxdata_header, followed immediately by N+1 of runlist_auxdata_seg_desc. +// The number N is in the header; there may be additional words after, which can be +// ignored +// +// Aux Data header record. +// The 'record_version' is reserved to flag changes in the format, so that +// if it changes, new skel can understand old records. +// Currently, It has this format; most changes will expand one of the fields +// so following this may be adequate to capture version changes; if it is not, +// add flags in the upper bits. +// bits 31 ..13 : reserved, 0 +// bit 12: set of crate sizes are calculated based on 'dynamic tensor' sizes +// bits 11..8 length of the header in uint32's +// bits 7..3 length of 'segment' record, in uint32's +// bits 2..0 .. value of DesConcur_MAX_RUNLISTS +// +struct runlist_auxdata_header { + unsigned record_version; // see above + unsigned numsegs : 16; // number of segments; >= 8, likely <= 64 but who knows + unsigned hdrflags : 16; // reserved for flags + unsigned runlist_offset; // see below +}; + +// 'runlist_offset' is the offset, in u32's units, from the 'num_in_tensors' word +// to the 'n_ops_total' word. This is needed by 'weight share' processing in order to +// adjust the deser_offset values to accommodate changes in the encoding length of pointers. + +// The N segments are described by an array of N+1 of runlist_auxdata_seg_desc; +// segment i is defined by arr[i] (start) and arr[i+1] (end). +// An exception is 'crate_seg_len'- this may be less than arr[i+1].crate_offset - arr[i].crate_offset +// due to padding. +// In the final record arr[N]: +// - crate_seg_len is not used (0) +// - The *_list_posn records are the total length of the runlists +// - the four 'base_*_index' values are all 1 greater than any index used in the graph +// +struct runlist_auxdata_seg_desc { + uint32_t deser_offset; // where the input (pickle) data begins - reference point is the start of 'Runlist' as + // // defined in docs/pickle_format.md, i.e. the location of 'n_ops_total' word + uint32_t crate_offset; // offset in crate + uint32_t crate_seg_len; // crate length needed (not used in final entry) + uint32_t runlist_posn[DesConcur_MAX_RUNLISTS]; // where the segment starts in Op* runlist + uint32_t execlist_posn[DesConcur_MAX_RUNLISTS]; // where the segment starts in 'execlist' + uint32_t base_opseq_index; // first 'op_sequence_marker' index used in the segment. + uint32_t base_tensor_index; // first tensor index defined this segment + uint32_t base_blocktable_index; // first blocktable index defined in this segment + uint32_t base_sharedobj_index; // first 'shared_object' index defined in this segment +}; + +// Bit in the header version indicating crate sizes allow for 'dynamic shapes'. +// NOTE: if that gets backed out later, leave this here but remove it from DesConcur_AUXDATA_REC_VERSION +// +constexpr unsigned DesConcur_AUXDATA_REC_VERSION_DYNSHAPE_SIZES = 4096; + +constexpr unsigned DesConcur_AUXDATA_REC_VERSION = // composed of: + ((sizeof(runlist_auxdata_header) / sizeof(uint32_t)) * 256 // header size + + (sizeof(runlist_auxdata_seg_desc) / sizeof(uint32_t)) * 8 // seg desc len + + DesConcur_MAX_RUNLISTS) | + DesConcur_AUXDATA_REC_VERSION_DYNSHAPE_SIZES; + +// values to be used to 'grow' old crate estimate to compensate for 'dyn shape' mismatch +constexpr unsigned DesConcur_CrateGrowPerTensor = 2; // number of words per 'tensor' +constexpr unsigned DesConcur_CrateGrowPerShared = 2; // number of words per 'shared object' + +} // namespace hnnx + +#endif // DESER_CONCURRENT_DEFS_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserialize_tensors.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserialize_tensors.h new file mode 100755 index 0000000000000..43f14039fd1ad --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserialize_tensors.h @@ -0,0 +1,68 @@ +//============================================================================== +// +// Copyright (c) 2021-2023 Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef DESERIALIZE_TENSORS_H +#define DESERIALIZE_TENSORS_H 1 + +#include +#include +#include +#include +#include +#include +#include "limits.h" +#include "log.h" + +#include "forward_classes.h" +#include "serdes_tensors.h" + +namespace hnnx { + +// see comment in serdes_tensors.h for overview of how this works. + +class Deserializer; + +class DeserTensorConn : public SerTensorConnDefs { + typedef unsigned tensor_idx; + typedef Tensor const *ptr_type; + + // this collects all of the tensor_def we have seen. index is seq_index-1. + std::vector defined_tensors; + + public: + DeserTensorConn() {} + // process a tensor definition + void tensor_def(Deserz &, ptr_type); + // process n tensor refs. + void tensor_refs(Deserz &, ptr_type *ptrs, unsigned num); + // process a tensor ref + void tensor_ref(Deserz &dctx, ptr_type &ptr) { tensor_refs(dctx, &ptr, 1); } + + // TODO: remove these two, we don't use them, and should not. + // read an identity (for use in subsequent need_fixup) + tensor_idx read_identity(Deserz &); + // apply the identity to 'fix' a tensor pointer (usually now, sometimes later + void need_fixup(tensor_idx ident, ptr_type *dst); + + // 'reserve' the defined tensors to avoid allocation overhead... + inline void reserve_tensors(const size_t n) { defined_tensors.reserve(n); } + // resize the 'defined tensors' table to its full capacity (specified). + // Used only in multi-thread deserialize, prior to deserializing the runlist. + inline void resize_tensordef_table(const size_t n) { defined_tensors.resize(n); } + + // this is for use by 'reference fixup' code, in concurrent deserialize. + std::vector const &get_defined_tensors() const { return defined_tensors; } + + protected: + tensor_idx read_identity_inline(Deserz &); + void apply_fixup_inline(tensor_idx idx, ptr_type *dst); +}; + +} // namespace hnnx + +#endif // DESERIALIZE_TENSORS_H diff --git a/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserializer.h b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserializer.h new file mode 100755 index 0000000000000..7312ae8bdd948 --- /dev/null +++ b/prebuilts/QNN_SDK/2.34.0.250424/include/QNN/HTP/core/deserializer.h @@ -0,0 +1,761 @@ +//============================================================================== +// +// Copyright (c) Qualcomm Technologies, Inc. +// All Rights Reserved. +// Confidential and Proprietary - Qualcomm Technologies, Inc. +// +//============================================================================== + +#ifndef DESERIALIZER_H +#define DESERIALIZER_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "limits.h" +#include "dtype.h" +#include "log.h" +#include "allocator.h" +#include "op_extra_info.h" + +#include "serialize_defs.h" +#include "forward_classes.h" +#include "deserialize_tensors.h" +#include "macros_attribute.h" +#include "const_extent_descriptor.h" +#include "weak_linkage.h" +#include "size_align_code.h" +#include "deser_concurrent.h" +#include "hexagon_nn_types.h" + +namespace hnnx { +class DMA_Manager; +class Crate; +/** + * @brief \ref Serializer and \ref Deserializer modules that provides + * a mechanism to flatten (serialize) and reconstruct (deserialize) + * primitive and user-defined data types. The initial objective + * was to create an in-memory representation of the optimized + * \ref Graph on x86 which can then be reconstructed and executed on + * a qdsp target, essentially, a means to Graph caching. + * + */ +using tensor_deserializer_fn = uptr_Tensor (*)(Deserz &); + +using deserialize_op_func = void *(*)(void *, Deserz &); // Allocation function +using deserialize_dtor_func = void (*)(Graph *, void *); // Deallocation function +class SimpleOpBase; +using deserialize_make_unique = std::unique_ptr (*)(); + +struct op_deserializer_fn { + op_deserializer_fn(deserialize_op_func init_func_in, const size_align_code_t sizeal_in) + : init_func(init_func_in), size_align_code(sizeal_in) + { + } + op_deserializer_fn(deserialize_op_func init_func_in, deserialize_dtor_func dtor_func_in, + const size_align_code_t sizeal_in) + : dtor_func(dtor_func_in), init_func(init_func_in), size_align_code(sizeal_in){}; + op_deserializer_fn(const op_deserializer_fn &) = default; + op_deserializer_fn(op_deserializer_fn &&) = default; + op_deserializer_fn &operator=(const op_deserializer_fn &) = delete; + deserialize_dtor_func dtor_func = nullptr; + deserialize_op_func init_func = nullptr; + const size_align_code_t size_align_code{}; + inline constexpr size_t get_size() const { return size_align_code.size(); } + inline constexpr size_t get_align() const { return size_align_code.align(); } +}; + +// here's a quick and dirty way to make these maps go faster: compare string_view starting with len; +// and if the len is the same, then compare the middle character, and if that's the same, +// use memcmp. This avoids getting slowed down by a lot of long common prefixes in the type names. +// and we don't care about the weird ordering it generates. +// +struct trick_stringview_lt { + bool operator()(std::string_view const &a, std::string_view const &b) const + { + unsigned const na = a.size(); + unsigned const nb = b.size(); + if (na != nb) return na < nb; + char const *const pa = a.data(); + char const *const pb = b.data(); + if (pa == pb || na == 0) return false; // pa==pb is a common case. + unsigned const char_a = pa[na >> 1]; + unsigned const char_b = pb[na >> 1]; + if (char_a != char_b) return char_a < char_b; + return ::memcmp(pa, pb, na) < 0; + } +}; + +using op_deserializer_map_t = std::map, trick_stringview_lt>; +using tensor_deserializer_map_t = std::map; +using cexdesc_deserializer_map = std::map; + +using const_extent_t = std::pair; +using weight_buf_deserializer_map = std::map; + +/** + * @brief Deserializer class to reverse the serialization + * process and reconstruct the data for specific types + * + */ +class Deserz : public DeSerError { + friend class Deserializer; // weirdly, sometimes a derived class needs to be a friend. + friend class DeserTensorConn; + + protected: + Deserz(Deserializer *full_deser, char const *p, size_t n, Graph *g = nullptr); + + public: + // I want to make this protected, but can't. + // Even code which has access to a protected copy_ctor + // of foo can't invoke .resize(n, foo_inst) on a std::vector. This + // seems like a defect in C++. Applies to various 'emplace' methods too; + // the 'emplace' can only ever use public ctors. + Deserz(Deserz const &) = default; + + public: + virtual ~Deserz(); // please keep this as first virtual method declared. + + // These three ONLY TO BE USED when setting up a Deserz to start processing a segment. + void setup_source_span(deser_segment_span const &); + void setup_dcrate_out(void *base, size_t len); + void setup_next_tensor_index(unsigned const idx) { next_tensordef_index = idx; } + + typedef uint32_t object_identity_type; + + // Note, various accessor methods are defined as inlines below 'class Deserializer'. + // true if this Deserz is really an instance of Deserializer. + constexpr bool is_base_deser() const; + + using op_deserialize_fn_list_t = std::vector; + using tensor_deserialize_fn_list_t = std::vector; + + op_deserialize_fn_list_t &get_op_deserialize_fn_list(); + tensor_deserialize_fn_list_t &get_tensor_deserialize_fn_list(); + std::vector &get_blocktable_link_table(); + // when deserializing an op: + // - call deserialize_tensor_ref (or _refs) on all the input tensor pointers + // - pass all output tensor addresses to deserialize_tensor_def + // Sequence must match serialization; note that the deserialize-ctor of Tensor + // calls deserialize_tensor_def on itself; so there is no need to call it elsewhere, + // except for specialized types which are constructed otherwise during depickle (e.g., + // types embedded in the Op). + // + // Some ops have multiple copies of some input tensor pointers; for these, it's possible + // serialize just one reference, and the deserialize it using + // auto id = deserialize_object_identity() // <- corresponds to serialize_tensor_ref + // need_tensor_fixup( id, &first_tensor_pointer); + // (other deserialize activity can happen here) + // need_tensor_fixup( id, &second_tensor_pointer); + + void deserialize_tensor_def(Tensor const *tensor_ptr); + void deserialize_tensor_ref(Tensor const *&where); + void deserialize_tensor_refs(Tensor const **ptrs, unsigned n); + template void deserialize_tensor_ref(T const *&where); + template void deserialize_tensor_refs(T const **ptrs, unsigned n); + object_identity_type deserialize_object_identity(); + void need_tensor_fixup(object_identity_type oid, Tensor const **where); + + Graph &graph() const { return *graph_ptr; } + Crate *crate() { return d_crate.crate(); } + DCrate *dcrate() { return &d_crate; } + DeserSegDescs const &get_segments() const; // gets ref to associated 'segments' object + op_deserializer_map_t const &get_op_deser_map() const { return *op_deserializer_map; } + + bool is_aligned_const_format() const; + bool has_pending_tensor_updates(); + + bool is_shared_dynamic_tensor_shape_format() const; + + fa::RuntimeAllocator *allocator; + DCrate d_crate; // contains a crate pointer + + protected: + // hoist pointers to these maps into Deserializer to avoid static lock overhead + op_deserializer_map_t const *op_deserializer_map; + tensor_deserializer_map_t const *tensor_deserializer_map; + Graph *graph_ptr{}; + Deserializer *full_deser; + + char const *bufstart; // start of current buffer + char const *bufend; // first byte we can't read + char const *bufp; // next to read + char const *buf_limit; // <= bufend; where 'fill_buffer' needs to be called. + size_t bytes_filled; // bytes previously filled + + uint32_t op_flags; + OpExtraInfo op_extra_info; + + unsigned next_tensordef_index = 1; // belongs to 'tensorconn' but needs to be in Deserz. + // 'format version'. Currently only ones used are 0 = classic, 1 = July/2023 + // Only access through methods like .classic_format(); + // This is changed to non-zero value based on seeing certain Aux Data records + // (which must appear before the allocator). + int format_version = 0; + + // this is used in multi-thread decoding. It is important that + // it remains null-constructed if the object is really a base of Deserializer; + // it is only used in 'segment' Deserz instances. + runlist_fixup_state seg_fixup_state{}; + + /** + * @brief throws an error since deserializer detected + * deserialization on insufficient bytes i.e. an underflow + * + */ + API_EXPORT virtual char const *fill_buffer(); // called for underflow on short operation + + /** + * @brief Deserialize data of specified length and write into + * buffer provided by caller + * + * @param[out] p buffer to write to + * @param[in] len length of the \ref bufp to read from + * @param[in] align if true, skip input bytes to a boundary of 4 + */ + API_EXPORT virtual void deserialize_fread(void *p, size_t len, bool align); + + /** + * @brief Get current position of buffer from which next data will be read + * + * @return size_t offset from buffer start + */ + size_t buffer_offset() const { return bufp - bufstart; } + /** + * @brief Available buffer size remaining for deserialization + * + * @return size_t remaining bytes size + */ + size_t buffer_remain() const { return bufend - bufp; } + + /** + * @brief deserialize buffer for type T + * + * @retval T returs the deserialized value of type T + * + * Note: This is the templated API called by deserialize_T() functions + * + * Note: Cannot be used for more than 4 bytes, there is a specialized version to read u64. + */ + template T simple_deserialize() + { + static_assert(sizeof(T) <= 4, "can only read sizeof(T) <= 4"); + constexpr size_t W = 4; + char const *curr_p = bufp; + if (curr_p >= buf_limit) { + curr_p = fill_buffer(); + } + T const val = *(T const *)(curr_p); + bufp = curr_p + W; + return val; + } + // see comment above deserialize_shared_obj. + API_EXPORT std::pair deserialize_shared_obj_func(void const **ptrloc); + API_EXPORT uint64_t deser_u64_slowpath(); + void initial_l2fetch(); // called only from ctor + + public: + inline constexpr bool classic_format() const { return format_version == 0; } + /** + * @brief deserialize data of type which calls simple_deserialize + * + * @param val data to deserialize + * + * Note: the below are the only types supported for deserialize_type + */ + API_EXPORT uint64_t deserialize_uint64(); // inline later + inline float deserialize_float() { return simple_deserialize(); } + inline uint32_t deserialize_uint32() { return simple_deserialize(); } + inline NN_INT32_T deserialize_int32() { return simple_deserialize(); } + inline int16_t deserialize_int16() { return simple_deserialize(); } + inline uint16_t deserialize_uint16() { return simple_deserialize(); } + inline int8_t deserialize_int8() { return simple_deserialize(); } + inline uint8_t deserialize_uint8() { return simple_deserialize(); } + + inline uint64_t deserialize_namesig() { return deserialize_uint64(); } + + // note, this is defined as an inline in deserializer.cc and not available elsewhere + tensor_deserializer_fn deserialize_tensor_identification(unsigned tensor_class_index); + + // deserialize string + // **NOTE** will throe runtime error if called in a Deserz which is not really a Deserialize. + API_EXPORT std::string_view deserialize_str(); + + uint32_t get_op_flags() const { return op_flags; }; + void clear_op_flags() { op_flags = 0; }; + void set_op_flags(uint32_t f) { op_flags = f; }; + + const OpExtraInfo &get_op_extra_info() const { return op_extra_info; }; + void clear_extra_info() { op_extra_info.clear(); }; + void set_op_extra_info(OpExtraInfo in_op_extra_info) { op_extra_info = in_op_extra_info; }; + + /** + * @brief deserialize buffer for specified size + * + * @param[in] alloc_size number of bytes to read from \ref bufp + * @param[out] ptr destination buffer for the read bytes + * @return size_t number of bytes actually read + */ + API_EXPORT size_t deserialize_buf(size_t alloc_size, void *ptr); + /** + * @brief similar to deserialize_buf but first deserialize a + * uint32_t size of bytes that should match the alloc_size + * + * @param[in] alloc_size number of bytes to read from \ref bufp + * @param[out] ptr destination buffer for the read bytes + * @return size_t number of bytes actually read + */ + API_EXPORT size_t deserialize_buf_withlen(size_t alloc_size, void *ptr); + // deserialize a pointer as 64 bits + inline void *deserialize_ptr() { return (void *)size_t(deserialize_uint64()); } + + template T deserialize_type(); + + template std::array deserialize_array(); + + /** + * @brief convernience wrappers for deserialize fuctions that + * take in different number of arguments of uint32_t type + * + * @return std::tuple (first, second) uint32_t data deserialized + */ + // convenience wrappers (to reduce inlined code size w/o much loss of speed) + API_EXPORT std::tuple deserialize_uint32_x2(); + API_EXPORT std::tuple deserialize_uint32_x3(); + API_EXPORT std::tuple deserialize_uint32_x4(); + + API_EXPORT void deserialize_uint32_arr(uint32_t *p, size_t N); + + // to reduce code size in the templates, we can deserialize arrays of + // N uint32 to sizet + API_EXPORT void deserialize_uint32_arr_sizet(size_t *p, size_t N); + + /** + * @brief deserialize array containing uint32_t type date + * + * @tparam N size of the array + * @return std::array array containing the deserialized values + */ + template std::array deserialize_uint32_array_sizet() + { + std::array res; + deserialize_uint32_arr_sizet(&res[0], N); + return res; + } + + // + // This is used for shared objects like Shape and Interface. + // it deserializes the index, and decides if it's the first instance. + // - must always pass the address which needs to point to it; though it + // will be not be set by this function. + // - if retval.second is null, then the object was previously deserialized, + // and return.first is the pointer to it. + // - otherwise, caller must deserialize the instance, and store the pointer + // at *retval.second. retval.first will be null in this case. + // In scenarios where delayed resolution is used, the return may be {token,null} + // where 'token' is actually delayed resolution token. + // + template + std::pair // see above + deserialize_shared_obj(T const **const loc) + { + auto const res = deserialize_shared_obj_func((void const **)loc); + return {(T const *)res.first, (T const **)res.second}; + } + + // Increment tue current read position of internal buffer without reading anything + void deserialize_skip_words(size_t nwords); + + // Apply the 'pointer fixups' contained within seg_info. This can + // be called with 'this' being any Deserz or Deserializer associated + // with the operation (it is only used to access tables in Deserializer). + // This can only be done on a given segment when all previous have + // been deserialized; so if we have one Deserz per thread, we need + // to 'move' the seg_info object out of it after completing the segment, + // and use this later to do the fixups. + // Returns true if ok, false if failed. + // Will leave the fixup list empty on success. + bool apply_segment_fixups(runlist_fixup_state &seg_info) const; + + // Methods to move 'seg_fixup_state' object in or out. + void install_seg_fixup_state(runlist_fixup_state &&src) { seg_fixup_state = std::move(src); } + runlist_fixup_state extract_seg_fixup_state() { return std::move(seg_fixup_state); } + void extract_seg_fixup_state_to(runlist_fixup_state &dest) { dest = std::move(seg_fixup_state); } + + // and a read_only accessor + runlist_fixup_state const &fixup_state() const { return seg_fixup_state; } + + // for Tensor::deserialize_blocktable + inline bool fixup_encode_for_blocktable(uint32_t const idx, uint32_t const table_offs, void **const ptrloc) + { + return hnnx::fixup_encode_for_blocktable(seg_fixup_state, idx, table_offs, ptrloc); + } +}; + +///////////////// + +class Deserializer : public Deserz { + friend class Deserz; + + public: + /** + * @brief Construct a new Deserializer object + * + * @param[in] p buffer that needs to be deserialized + * @param[in] n length of the buffer + * @param[in] g pointer Graph object to deserialize (usually null, since object + * is being passed to the Graph::Graph ctor to deserialize; that ctor + * must immediately call dctx.set_graph(*this) ) + */ + API_EXPORT Deserializer(char const *p, size_t n, Graph *g = nullptr); + API_EXPORT virtual ~Deserializer(); // please keep this as first virtual method declared. + + void set_graph(Graph &g); + + inline void deserialize_tensor_def(Tensor const *tensor_ptr) { tensorconn.tensor_def(*this, tensor_ptr); } + inline void deserialize_tensor_ref(Tensor const *&where) { tensorconn.tensor_ref(*this, where); } + inline void deserialize_tensor_refs(Tensor const **ptrs, unsigned n) { tensorconn.tensor_refs(*this, ptrs, n); } + inline void deserialize_pred_conditions(std::vector &pred_cond_list) + { + // get the number of items in the vector + uint32_t num_of_objects = deserialize_uint32(); + assert(num_of_objects <= UINT32_MAX); + if (num_of_objects > 0) { + pred_cond_list.resize(num_of_objects); + + // TODO: remove this once we know how to update it at runtime + // Currently setting it to true + pred_cond_list.at(0) = 1; + } + } + template inline void deserialize_tensor_ref(T const *&where) + { + static_assert(std::is_base_of::value); + tensorconn.tensor_ref(*this, *(Tensor const **)&where); + } + template void deserialize_tensor_refs(T const **ptrs, unsigned n) + { + static_assert(std::is_base_of::value); + tensorconn.tensor_refs(*this, (Tensor const **)ptrs, n); + } + inline object_identity_type deserialize_object_identity() { return tensorconn.read_identity(*this); } + + inline void need_tensor_fixup(object_identity_type oid, Tensor const **where) { tensorconn.need_fixup(oid, where); } + inline void resolve_fixups() + { + [[maybe_unused]] const object_identity_type newval = tensorconn.read_identity(*this); + assert(newval == 0); + } + + constexpr bool is_aligned_const_format() const { return aligned_const_format_flag; } + void set_aligned_const_format(const bool v = true) { aligned_const_format_flag = v; } + + constexpr bool is_shared_dynamic_tensor_shape_format() const { return shared_dynamic_tensor_shape; } + void set_shared_dynamic_tensor_shape_format(const bool v = true) { shared_dynamic_tensor_shape = v; } + + PUSH_WARNING() + DISABLE_WARNING("-Wcast-qual", MSVC_NO_EQUIV) + // valid when the entire pickle, in const_extent format, is loaded as a single, persistent dma buffer + inline unsigned char *get_weight_pointer() { return ((unsigned char *)bufstart) + (4 * pickle_len_words); }; + POP_WARNING() + inline size_t get_weight_size() { return (bufend - bufstart) - (4 * pickle_len_words); }; + + inline op_deserialize_fn_list_t &get_op_deserialize_fn_list() { return op_deserialize_fn_list; } + inline tensor_deserialize_fn_list_t &get_tensor_deserialize_fn_list() { return tensor_deserialize_fn_list; } + + // Next 4 methods are used to support 'deserialize_by_segments'. + // 'get_forward_span' returns a 'deser_segment_span' (pair of pointers) for a region of deserialized data + // from 'ref + start' up to 'ref + end', where start and end (0 <= start < end) are byte offsets + // relative to some position 'ref' in the deserialized data, and 'ref' is the value which bytes_consumed() + // returned at that reference point. All should be multiples of 4. + deser_segment_span get_forward_span(size_t ref, size_t start, size_t end); + // used to get a reference point for bytes_consumed + size_t bytes_consumed() const { return bufp - bufstart; } + // used to skip past the last 'get_forward_span' we did + void skip_to_after_span(deser_segment_span const &); + // resize tables: tensor, shared_obj, linktable, according to info in final_segdesc + void resize_object_tables(runlist_auxdata_seg_desc const &final_desc); + + uint32_t crate_size_according_to_segments() const; + + protected: + std::vector objindex; // index of pointers to shape, etc. + // the state of the 'tensor connectivity' deserialize engine. + DeserTensorConn tensorconn; + bool aligned_const_format_flag = false; + bool shared_dynamic_tensor_shape = false; + + // this is used in 'deserialize_str', so it ideally should be in Deserz; but + // it's pretty large; so, put it here and forbid calling deserialize_str + // on a Derserz which not really a Deserialize. We only use it to decode + // 'classic' pickles, so this is ok. + char name_buf[4096]; // used for string view + + // do the reference fixups on a segment. Return true if OK. + // See Deserz::apply_segment_fixups for public API. + static bool do_segment_fixups(runlist_fixup_state &seginfo, Deserz const &dctx0); + + public: + inline constexpr bool classic_format() const { return format_version == 0; } + inline void set_format_2307() { format_version = 1; } + + // This is called when a 'class index' Aux Data is encountered. + // It must deserialize exactly the indicated number of payload words. + // is_tensor = false for "Co" (op class index), and true for "Ct" (tensor class index) + API_EXPORT void auxdata_class_index(unsigned payload_words, bool is_tensor); + // + // called when an 'Nt' Aux data is encountered, which provides some array sizes for the + // deserialization. + // It must deserialize exactly the indicated number of payload words. + API_EXPORT void auxdata_temparr_sizes(unsigned payload_words); + // Called when a 'AuxTag_deserializeSegments' is encountered. If it likes + // the record, it will set up the 'segments' object. + API_EXPORT void auxdata_deserialize_segments(unsigned payload_words); + + // called when a 'KS' Aux data is encountered, which provides a const_extent_descriptor + // It must deserialize exactly the indicated number of payload words. + API_EXPORT int auxdata_read_const_extent_descriptor(const unsigned payload_words); + // helper for above. payload_words is the length WITH PADDING + API_EXPORT int extract_const_extent_name(const unsigned payload_words, std::string &retVal); + + // Extract a std::vector containing the 'const extent descriptor table, + // from a given offset (in units of 32-bit words) relative to the start of the pickle. + // or separate pointer (if separate buffer for the weights was passed in). + // This does not affect the current position. + // If there is a problem, it returns an empty vector; caller *must* check and report. + // This uses hnnx::const_extent_hdr_check to understand how much it should read, + // and to do basic check. + API_EXPORT std::vector extract_const_extent_table(size_t posn_in_words); + std::vector extract_const_extent_table(hexagon_nn_wide_address_const_t weight_data, + const size_t weight_size); + // given a destination char pointer, prefilled with \null, fills it in with the name of the const_extent + // caller must provide destination of sufficient length + std::string name_from_weight_data(hexagon_nn_wide_address_const_t weight_data, const uint32_t weight_length); + // helper func for above. return -1 if name not present. + std::string get_name(hexagon_nn_wide_address_const_t weight_data, const uint32_t weight_length); + // give a vector of weight_data buffers, stores them all in the appropriate map + void store_named_weight_bufs(const hexagon_nn_wide_address_const_t *const buffers, const uint64_t *const lengths, + const unsigned num_buffers); + // + // copy 'len' bytes of data at offset offs_bytes in the pickle into location dstp. + // returns true if it's possible. You can maybe pass a DMA_Manager to have it queued... + // offs_bytes defined as uint64_t to support possible 'far' data on hexagon. + API_EXPORT bool extract_const_extent_data(uint64_t offs_bytes, size_t len, void *dstp, DMA_Manager *dma = nullptr); + // same, using an external const_extent + bool extract_const_extent_data(uint64_t offs_bytes, size_t len, void *dstp, + hexagon_nn_wide_address_const_t weight_data, const size_t weight_length); + + // This extracts the 'objindex', when it is needed e.g. to 'patch' interfaces. + // Must be done only after deserializing, and can only be done once. + std::vector extract_objindex() { return std::move(objindex); } + + DeserSegDescs segments; // array of runlist_seg_descriptor, empty if not doing multiseg. + + // this is used to pass the offset of the const-extent-descriptor (recorded as pickle_len) + // to the alloc->deserialize. + size_t pickle_len_words; + + // OPTIONAL maps from weight buffer names to the descriptors and the buffers, respectively + cexdesc_deserializer_map named_cexdescs; + weight_buf_deserializer_map named_weight_bufs; + + void *uncached_ptr; + uint32_t uncached_len; + + std::vector op_deserialize_fn_list; + std::vector tensor_deserialize_fn_list; + + // used to 'link' shared blocktables during deser. + std::vector blocktable_link_table; +}; + +///////////////// + +// true if this Deserz is really an instance of Deserializer. +inline constexpr bool Deserz::is_base_deser() const +{ + return static_cast(full_deser) == this; +} + +inline bool Deserz::is_aligned_const_format() const +{ + return full_deser->aligned_const_format_flag; +} +inline bool Deserz::is_shared_dynamic_tensor_shape_format() const +{ + return full_deser->shared_dynamic_tensor_shape; +} +inline Deserz::op_deserialize_fn_list_t &Deserz::get_op_deserialize_fn_list() +{ + return full_deser->op_deserialize_fn_list; +} +inline Deserz::tensor_deserialize_fn_list_t &Deserz::get_tensor_deserialize_fn_list() +{ + return full_deser->tensor_deserialize_fn_list; +} +inline std::vector &Deserz::get_blocktable_link_table() +{ + return full_deser->blocktable_link_table; +} +// For these in Deserz, we must call the corresponding methods on the +// tensorconn in 'full_deser', but must pass 'this' as first parameter. +inline void Deserz::deserialize_tensor_def(Tensor const *const tensor_ptr) +{ + full_deser->tensorconn.tensor_def(*this, tensor_ptr); +} +inline void Deserz::deserialize_tensor_ref(Tensor const *&where) +{ + full_deser->tensorconn.tensor_ref(*this, where); +} +inline void Deserz::deserialize_tensor_refs(Tensor const **const ptrs, const unsigned n) +{ + full_deser->tensorconn.tensor_refs(*this, ptrs, n); +} +inline DeserSegDescs const &Deserz::get_segments() const +{ + return full_deser->segments; +} + +// unaligned read of 64-bits (two 32-bit aligned reads) +template <> inline uint64_t Deserz::simple_deserialize() +{ + char const *const curr_p = bufp; + if (curr_p + 8u > buf_limit) { + return deser_u64_slowpath(); + } + uint32_t const *const p = (uint32_t const *)(curr_p); + bufp = curr_p + 8u; + return p[0] + ((uint64_t)p[1] << 32); +} +inline uint64_t Deserz::deserialize_uint64() +{ + return simple_deserialize(); +} + +template <> inline uint64_t Deserz::deserialize_type() +{ + return deserialize_uint64(); +} +template <> inline float Deserz::deserialize_type() +{ + return deserialize_float(); +} +// sometimes uint32_t is unsigned long, sometimes it's unsigned +// sometimes unsigned long is uint64. Hopefully this should cover it all. +#if ULONG_MAX == UINT_MAX +template <> inline unsigned long Deserz::deserialize_type() +{ + return deserialize_uint32(); +} +template <> inline long Deserz::deserialize_type() +{ + return deserialize_int32(); +} +#endif +template <> inline unsigned Deserz::deserialize_type() +{ + return deserialize_uint32(); +} +template <> inline int Deserz::deserialize_type() +{ + return deserialize_int32(); +} +template <> inline int16_t Deserz::deserialize_type() +{ + return deserialize_int16(); +} +template <> inline uint16_t Deserz::deserialize_type() +{ + return deserialize_uint16(); +} +template <> inline int8_t Deserz::deserialize_type() +{ + return deserialize_int8(); +} +template <> inline uint8_t Deserz::deserialize_type() +{ + return deserialize_uint8(); +} + +// assert( dctx.deserialize_uint32() == SOME_CONST ); +// is not safe, since if you turn off asserts, it will no longer read the 4 bytes. This is to allow that to work +#define DESERIALIZE_ASSERT_UINT32(DCTX, VAL) \ + do { \ + uint32_t const tmp [[gnu::unused]] = (DCTX).deserialize_uint32(); \ + assert(tmp == (VAL)); \ + } while (0) + +#include "weak_linkage.h" +PUSH_VISIBILITY(default) + +/** + * @brief register the deserialization function for each \ref Op + * TypicalOp and VariadicOp derived classes are instantiated via + * template and hence the need to create a map of deserialize functions + * for each Op when they are generated at library initialization + * + * @param[in] tinf Op type_info that is used to key the map + * @param[in] fn Deserialize function + */ +API_EXPORT void deserialize_op_register(std::type_info const *tinf, const std::string_view type_tag, + const op_deserializer_fn &fn, bool is_external = false); +/** + * @brief register the deserialization function for each \ref Tensor + * Since \ref Tensor derived classes are instantiated via templates, there + * is a need to create a map of deserialize function for each Tensor at runtime + * + * @param[in] type_tag Tensor type tag that is used to key the map + * @param[in] fn Deserialize function + */ +API_FUNC_EXPORT void deserialize_tensor_register(std::type_info const &tinf, const char *type_tag, + tensor_deserializer_fn fn); + +POP_VISIBILITY() + +// this is fully defined in serialize_register.h +template struct deserialize_tensor_using_constructor; + +// this is fully defined in serialize_register.h +template struct alloc_func_for_op; +template struct dealloc_func_for_op; + +////////////////////// +// Forward decls of things defined in template_help.h +// +// contains_type< tuple, x >::value: true if x is in a,b,c ... +// no 'remove ref' etc is done. +template struct contains_type; +template struct not_contains_type; +template