add qcom dsp runtime (#6112)

* calling qualcomm dsp from python

* include so files

* add include file

* adsprpc.py

* running with adsprpc

* work

* 32-bit support in elf

* compilation works

* ion

* msm_ion

* working DSP backend

* getting 500 MFLOPS on matmul

* beam works with timing

* move to autogen

* disasm

* progress

* simple tests pass

* qcom_dsp

* more dsp autogen

* progress

* some progress

* works w/o lib

* checkpoint

* no lib

* ugh, better

* cleaner, but with lib. test good, but with the hack

* remove autogens

* small

* push

* simpler

* revert this

* run_3

* simpler

* android

* handle

* run it

* why?

* run2

* to gen

* cc

* cleaner

* elf

* part of autogen

* comemnt

* no lib

* autohen

* linter

* bug reproducer

* cleaner

* this repro is almost empty and doesn't work!!!!

* with this test_ops passes, no crashes anymore

* cleaner

* linter

* renames

* shorter

* remoev contextlib

* ugh

* myoy

* cleaner

* cleaner

* remove import

* conn

* import

* revert this

* remove heavy .so

* shorter alloc

* not tue anymore

---------

Co-authored-by: Comma Device <device@comma.ai>
Co-authored-by: George Hotz <geohot@gmail.com>
Co-authored-by: George Hotz <george@comma.ai>
This commit is contained in:
nimlgen 2024-09-13 21:01:33 +03:00 committed by GitHub
parent ca63207d23
commit 81a4a9623c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 7291 additions and 0 deletions

View File

@ -230,6 +230,19 @@ generate_adreno() {
python3 -c "import tinygrad.runtime.autogen.adreno"
}
generate_qcom() {
clang2py -k cdefstum \
extra/dsp/include/ion.h \
extra/dsp/include/msm_ion.h \
extra/dsp/include/adsprpc_shared.h \
extra/dsp/include/remote_default.h \
extra/dsp/include/apps_std.h \
-o $BASE/qcom_dsp.py
fixup $BASE/qcom_dsp.py
python3 -c "import tinygrad.runtime.autogen.qcom_dsp"
}
if [ "$1" == "opencl" ]; then generate_opencl
elif [ "$1" == "hip" ]; then generate_hip
elif [ "$1" == "comgr" ]; then generate_comgr
@ -239,6 +252,7 @@ elif [ "$1" == "hsa" ]; then generate_hsa
elif [ "$1" == "kfd" ]; then generate_kfd
elif [ "$1" == "nv" ]; then generate_nv
elif [ "$1" == "amd" ]; then generate_amd
elif [ "$1" == "qcom" ]; then generate_qcom
elif [ "$1" == "io_uring" ]; then generate_io_uring
elif [ "$1" == "libc" ]; then generate_libc
elif [ "$1" == "kgsl" ]; then generate_kgsl

125
extra/dsp/compile.py Executable file
View File

@ -0,0 +1,125 @@
#!/usr/bin/env python3
import os, ctypes, time, fcntl, mmap
import llvmlite.binding as llvm
from tinygrad.helpers import getenv, to_mv
from tinygrad.runtime.support.elf import elf_loader
from hexdump import hexdump
from tinygrad.runtime.autogen import libc
if getenv("IOCTL"): import run # noqa: F401 # pylint: disable=unused-import
adsp = ctypes.CDLL(ctypes.util.find_library("adsprpc"))
import adsprpc
import ion
import msm_ion
ION_IOC_ALLOC = 0
ION_IOC_MAP = 2
ION_IOC_SHARE = 4
ION_IOC_CUSTOM = 6
ION_ADSP_HEAP_ID = 22
ION_IOMMU_HEAP_ID = 25
def ion_iowr(fd, nr, args):
ret = fcntl.ioctl(fd, (3 << 30) | (ctypes.sizeof(args) & 0x1FFF) << 16 | (ord(ion.ION_IOC_MAGIC) & 0xFF) << 8 | (nr & 0xFF), args)
if ret != 0: raise RuntimeError(f"ioctl returned {ret}")
if __name__ == "__main__":
# TODO: mmap tensors to the DSP
# call the target function with the mmaped tensors
ion_fd = os.open("/dev/ion", os.O_RDWR | os.O_CLOEXEC)
arg3 = ion.struct_ion_allocation_data(len=0x1000, align=0x1000, heap_id_mask=1<<msm_ion.ION_SYSTEM_HEAP_ID, flags=ion.ION_FLAG_CACHED)
ion_iowr(ion_fd, ION_IOC_ALLOC, arg3)
print(arg3.handle)
arg2 = ion.struct_ion_fd_data(handle=arg3.handle)
ion_iowr(ion_fd, ION_IOC_SHARE, arg2)
print(arg2.fd)
res = libc.mmap(0, 0x1000, mmap.PROT_READ|mmap.PROT_WRITE, mmap.MAP_SHARED, arg2.fd, 0)
print("mmapped", hex(res))
to_mv(res, 0x10)[1] = 0xaa
from tinygrad.runtime.ops_clang import ClangCompiler
cc = ClangCompiler(args=["--target=hexagon", "-mcpu=hexagonv65", "-fuse-ld=lld", "-nostdlib"])
obj = cc.compile("""
typedef unsigned long long remote_handle64;
typedef struct { void *pv; unsigned int len; } remote_buf;
typedef struct { int fd; unsigned int offset; } remote_dma_handle;
typedef union { remote_buf buf; remote_handle64 h64; remote_dma_handle dma; } remote_arg;
void* HAP_mmap(void *addr, int len, int prot, int flags, int fd, long offset);
int HAP_munmap(void *addr, int len);
#define HAP_MEM_CACHE_WRITETHROUGH 0x40
int entry(unsigned long long handle, unsigned int sc, remote_arg* pra) {
if (sc>>24 == 1) {
//void *mmaped = *((void**)pra[0].buf.pv);
void *a = HAP_mmap(0, 0x1000, 3, 0, pra[1].dma.fd, 0);
((char*)a)[0] = 0x55;
((char*)a)[4] = 0x55;
((char*)a)[8] = 0x99;
//((char*)a)[1] = 0x9b;
//char ret = ((char*)a)[1];
HAP_munmap(a, 0x1000);
return 0;
//return ((int)mmaped)&0xFFFF;
//return ((char*)mmaped)[1];
//return sizeof(void*);
//((char*)mmaped)[0] = 55;
//return ((int)mmaped)&0xFFFF;
//void addr = *((void**)pra[1])
//return sizeof(remote_buf);
//((char*)pra[1].h64)[0] = 55;
//return ((char*)mmaped)[1];
//((char*)mmaped)[0] = 55;
// NOTE: you have to return 0 for outbufs to work
//return ((int)pra[1].h64)&0xFFFF;
}
return 0;
}
""")
with open("/tmp/swag.so", "wb") as f: f.write(obj)
handle = ctypes.c_int64(-1)
adsp.remote_handle64_open(ctypes.create_string_buffer(b"file:////tmp/swag.so?entry&_modver=1.0&_dom=cdsp"), ctypes.byref(handle))
print("HANDLE", handle.value)
#print(adsp.remote_handle64_invoke(handle, 0, None))
#rem = adsp.remote_register_buf(res, 0x1000, arg2.fd, 4)
#rem = adsp.remote_register_dma_handle(arg2.fd, 0x1000)
#print("remote_register_buf_attr", rem)
#out = ctypes.c_uint64(0)
#ret = adsp.remote_mmap(arg2.fd, 0, 0, 0x1000, ctypes.byref(out))
#print(ret)
#print("mapped at", hex(out.value))
#arg_2 = ctypes.c_int64(out.value)
arg_2 = ctypes.c_int64(arg2.fd)
pra = (adsprpc.union_remote_arg64 * 3)()
pra[0].buf.pv = ctypes.addressof(arg_2)
pra[0].buf.len = 8
pra[1].dma.fd = arg2.fd
pra[1].dma.len = 0x1000
print("invoke")
ret = adsp.remote_handle64_invoke(handle, (1<<24) | (1<<16) | (1 << 4), pra)
print("return value", ret, hex(ret))
#print(hex(arg_2.value), arg_2.value)
#time.sleep(0.1)
# flush the cache
"""
flush_data = msm_ion.struct_ion_flush_data(handle=arg3.handle, vaddr=res, offset=0, length=0x1000)
# ION_IOC_CLEAN_INV_CACHES
cd = ion.struct_ion_custom_data(
cmd=(3 << 30) | (ctypes.sizeof(flush_data) & 0x1FFF) << 16 | (ord(msm_ion.ION_IOC_MSM_MAGIC) & 0xFF) << 8 | (2 & 0xFF),
arg=ctypes.addressof(flush_data))
ret = ion_iowr(ion_fd, ION_IOC_CUSTOM, cd)
res2 = libc.mmap(0, 0x1000, mmap.PROT_READ|mmap.PROT_WRITE, mmap.MAP_SHARED, arg2.fd, 0)
"""
hexdump(to_mv(res, 0x10))
os._exit(0)

3
extra/dsp/gen.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
clang2py adsprpc_shared.h -k cdefstum -o adsprpc.py

File diff suppressed because it is too large Load Diff

328
extra/dsp/include/AEEStdErr.h Executable file
View File

@ -0,0 +1,328 @@
/*
* 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_EBADHANDLE (AEE_EOFFSET + 0x02C) ///< Invalid/Wrong handle
#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) ///<File handling related error
//NOTE: Used in both HLOS and DSP.
#define AEE_ENOSUCH (39) ///< No such name, port, socket
#define AEE_EINTERRUPTED (46) ///< Waitable call is interrupted,
///< the user should return to the HLOS and retry the call
#define AEE_ECONNRESET (104) ///< Connection reset by peer
#define AEE_EWOULDBLOCK (516) ///< Operation would block if not
///< non-blocking; wait and try
///< again
/**
* @}
*/
/** @defgroup sigverifyerror Sigverify error codes
* @{
*/
#define AEE_EINVALIDMSG (AEE_EOFFSET + 0x032) ///< Invalid SMD message from APPS
#define AEE_EINVALIDTHREAD (AEE_EOFFSET + 0x033) ///< Invalid thread
#define AEE_EINVALIDPROCESS (AEE_EOFFSET + 0x034) ///< Invalid Process
#define AEE_EINVALIDFILENAME (AEE_EOFFSET + 0x035) ///< Invalid filename
#define AEE_EINVALIDDIGESTSIZE (AEE_EOFFSET + 0x036) ///< Invalid digest size
#define AEE_EINVALIDSEGS (AEE_EOFFSET + 0x037) ///< Invalid segments
#define AEE_EINVALIDSIGNATURE (AEE_EOFFSET + 0x038) ///< Invalid signature
#define AEE_EINVALIDDOMAIN (AEE_EOFFSET + 0x039) ///< Invalid DSP domain
#define AEE_EINVALIDFD (AEE_EOFFSET + 0x03A) ///< Invalid file descriptor
#define AEE_EINVALIDDEVICE (AEE_EOFFSET + 0x03B) ///< Invalid Device or Device node open failed for the domain
#define AEE_EINVALIDMODE (AEE_EOFFSET + 0x03C) ///< Invalid Mode
#define AEE_EINVALIDPROCNAME (AEE_EOFFSET + 0x03D) ///< Invalid Process name
#define AEE_ENOSUCHMOD (AEE_EOFFSET + 0x03E) ///< No such module
#define AEE_ENOSUCHINSTANCE (AEE_EOFFSET + 0x03F) ///< No instance in the list lookup
#define AEE_ENOSUCHTHREAD (AEE_EOFFSET + 0x040) ///< No such thread
#define AEE_ENOSUCHPROCESS (AEE_EOFFSET + 0x041) ///< No such process
#define AEE_ENOSUCHSYMBOL (AEE_EOFFSET + 0x042) ///< No such symbol( dlsym for the symbol failed)
#define AEE_ENOSUCHDEVICE (AEE_EOFFSET + 0x043) ///< No such device
#define AEE_ENOSUCHPROP (AEE_EOFFSET + 0x044) ///< No such dal property
#define AEE_ENOSUCHFILE (AEE_EOFFSET + 0x045) ///< No such file found
#define AEE_ENOSUCHHANDLE (AEE_EOFFSET + 0x046) ///< No such handle
#define AEE_ENOSUCHSTREAM (AEE_EOFFSET + 0x047) ///< No such stream
#define AEE_ENOSUCHMAP (AEE_EOFFSET + 0x048) ///< No mapping exists for this address on DSP
#define AEE_ENOSUCHREGISTER (AEE_EOFFSET + 0x049) ///< No such register
#define AEE_ENOSUCHCLIENT (AEE_EOFFSET + 0x04A) ///< No such QDI client
#define AEE_EBADDOMAIN (AEE_EOFFSET + 0x04B) ///< Bad domain (not initialized)
#define AEE_EBADOFFSET (AEE_EOFFSET + 0x04C) ///< Bad buffer/page/heap offset
#define AEE_EBADSIZE (AEE_EOFFSET + 0x04D) ///< Bad buffer/page/heap size
#define AEE_EBADPERMS (AEE_EOFFSET + 0x04E) ///< Bad FILE/MAP/MEM permissions
#define AEE_EBADFD (AEE_EOFFSET + 0x04F) ///< Bad file descriptor
#define AEE_EBADPID (AEE_EOFFSET + 0x050) ///< Bad PID from HLOS
#define AEE_EBADTID (AEE_EOFFSET + 0x051) ///< Bad TID
#define AEE_EBADELF (AEE_EOFFSET + 0x052) ///< Bad elf file
#define AEE_EBADASID (AEE_EOFFSET + 0x053) ///< Bad asid
#define AEE_EBADCONTEXT (AEE_EOFFSET + 0x054) ///< Bad context
#define AEE_EBADMEMALIGN (AEE_EOFFSET + 0x055) ///< Bad memory alignment
#define AEE_EIOCTL (AEE_EOFFSET + 0x056) ///< ioctl call failed
#define AEE_EFOPEN (AEE_EOFFSET + 0x057) ///< file open error or device node open failed for DSP domain
#define AEE_EFGETS (AEE_EOFFSET + 0x058) ///< file get string error
#define AEE_EFFLUSH (AEE_EOFFSET + 0x059) ///< file flush error
#define AEE_EFCLOSE (AEE_EOFFSET + 0x05A) ///< file close error
#define AEE_EEOF (AEE_EOFFSET + 0x05B) ///< File EOF reached
#define AEE_EFREAD (AEE_EOFFSET + 0x05C) ///< file read failed
#define AEE_EFWRITE (AEE_EOFFSET + 0x05D) ///< file write failed
#define AEE_EFGETPOS (AEE_EOFFSET + 0x05E) ///< file get position failed
#define AEE_EFSETPOS (AEE_EOFFSET + 0x05F) ///< file set position failed
#define AEE_EFTELL (AEE_EOFFSET + 0x060) ///< file tell position failed
#define AEE_EFSEEK (AEE_EOFFSET + 0x061) ///< file seek failed
#define AEE_EFLEN (AEE_EOFFSET + 0x062) ///< file len greater than expected
#define AEE_EGETENV (AEE_EOFFSET + 0x063) ///< apps_std get enviroment failed
#define AEE_ESETENV (AEE_EOFFSET + 0x064) ///< apps_std set enviroment failed
#define AEE_EMMAP (AEE_EOFFSET + 0x065) ///< mmap failed
#define AEE_EIONMAP (AEE_EOFFSET + 0x066) ///< ion map failed
#define AEE_EIONALLOC (AEE_EOFFSET + 0x067) ///< ion alloc failed
#define AEE_ENORPCMEMORY (AEE_EOFFSET + 0x068) ///< ION memory allocation failed
#define AEE_ENOROOTOFTRUST (AEE_EOFFSET + 0x069) ///< No root of trust for sigverify
#define AEE_ENOTLOCKED (AEE_EOFFSET + 0x06A) ///< Unlock failed, not locked before
#define AEE_ENOTINITIALIZED (AEE_EOFFSET + 0x06B) ///< Not initialized
#define AEE_EUNSUPPORTEDAPI (AEE_EOFFSET + 0x06C) ///< unsupported API/request ID
#define AEE_EUNPACK (AEE_EOFFSET + 0x06D) ///< unpacking command failed
#define AEE_EPOLL (AEE_EOFFSET + 0x06E) ///< error while polling for event
#define AEE_EEVENTREAD (AEE_EOFFSET + 0x06F) ///< event read failed
#define AEE_EMAXBUFS (AEE_EOFFSET + 0x070) ///< Maximum buffers
#define AEE_EINVARGS (AEE_EOFFSET + 0x071) ///< Invalid Arguments
#define AEE_ECONNREFUSED (AEE_EOFFSET + 0x072) ///< Connection refused to DSP
#define AEE_EUNSIGNEDMOD (AEE_EOFFSET + 0x081) ///< test-sig not found, Unsigned shared object
#define AEE_EINVALIDHASH (AEE_EOFFSET + 0x082) ///< test-sig not found, Invalid hash object
#define AEE_EBADVA (AEE_EOFFSET + 0x083) ///< Bad VA address
#define AEE_ENOSUCHJOB (AEE_EOFFSET + 0x084) ///< No such job
#define AEE_ENOSUCHGROUP (AEE_EOFFSET + 0x084) ///< No such static pd group
#define AEE_EBADMAPREFCNT (AEE_EOFFSET + 0x085) ///< Bad map reference count
#define AEE_EBADPAGECNT (AEE_EOFFSET + 0x086) ///< Bad page count
#define AEE_EMAPALREADYPRESENT (AEE_EOFFSET + 0x087) ///< Map already present
#define AEE_ENOFREESECTION (AEE_EOFFSET + 0x088) ///< No more free sections available
#define AEE_U2GCLIENT_OPEN (AEE_EOFFSET + 0x089) ///< u2g client open failed
/**
* @}
*/
/** @defgroup smderror SMD error codes
* @{
*/
#if defined(__hexagon__)
#define AEE_EGLINK_OFFSET (AEE_EOFFSET + 0x100) ///< SMD errors offset
#define AEE_EGLINKBADPACKET (AEE_EOFFSET + 0x101) ///< SMD invalid packet size
#define AEE_EGLINKALREADYOPEN (AEE_EOFFSET + 0x102) ///< SMD port is already open
#define AEE_EGLINKOPENFAILED (AEE_EOFFSET + 0x103) ///< SMD port open failed
#define AEE_EGLINKWRITE (AEE_EOFFSET + 0x104) ///< SMD port write failed
#define AEE_EGLINKREGISTER (AEE_EOFFSET + 0x105) ///< SMD port register callback failed
#else
#define AEE_ESMD_OFFSET (AEE_EOFFSET + 0x100) ///< SMD errors offset
#define AEE_ESMDBADPACKET (AEE_EOFFSET + 0x101) ///< SMD invalid packet size
#define AEE_ESMDALREADYOPEN (AEE_EOFFSET + 0x102) ///< SMD port is already open
#define AEE_ESMDOPENFAILED (AEE_EOFFSET + 0x103) ///< SMD port open failed
#endif
/**
* @}
*/
/** @defgroup dalerror DAL error codes
* @{
*/
#define AEE_EDAL_OFFSET (AEE_EOFFSET + 0x120) ///< Dal error offset
#define AEE_EDALDEVATTACH (AEE_EOFFSET + 0x121) ///< DAL attach error
#define AEE_EDALINTREGISTER (AEE_EOFFSET + 0x122) ///< DAL interrupt register error
#define AEE_EDALINTUNREGISTER (AEE_EOFFSET + 0x123) ///< Dal interrupt unregister error
#define AEE_EDALGETPROP (AEE_EOFFSET + 0x124) ///< Dal get property
#define AEE_EDALGETVAL (AEE_EOFFSET + 0x125) ///< Dal get property value
#define AEE_EDCVSREQUEST (AEE_EOFFSET + 0x126) ///< Dal get property value
/**
* @}
*/
/** @defgroup qurterror QURT error codes
* @{
*/
#define AEE_EQURT_OFFSET (AEE_EOFFSET + 0x140) ///< QURT error offset
#define AEE_EQURTREGIONCREATE (AEE_EOFFSET + 0x141) ///< QURT region create failed
#define AEE_EQURTCACHECLEAN (AEE_EOFFSET + 0x142) ///< QURT cache clean failed
#define AEE_EQURTREGIONGETATTR (AEE_EOFFSET + 0x143) ///< QURT region get attribute failed
#define AEE_EQURTBADREGIONPERMS (AEE_EOFFSET + 0x144) ///< QURT bad permissions for region
#define AEE_EQURTMEMPOOLADD (AEE_EOFFSET + 0x145) ///< QURT Add to memory pool failed
#define AEE_EQURTREGISTERDEV (AEE_EOFFSET + 0x146) ///< QURT register device failed
#define AEE_EQURTMEMPOOLCREATE (AEE_EOFFSET + 0x147) ///< QURT create memory pool failed
#define AEE_EQURTGETVA (AEE_EOFFSET + 0x148) ///< QURT get VA failed
#define AEE_EQURTREGIONDELETE (AEE_EOFFSET + 0x149) ///< QURT region delete failed
#define AEE_EQURTMEMPOOLATTACH (AEE_EOFFSET + 0x14A) ///< QURT memory pool attach failed
#define AEE_EQURTTHREADCREATE (AEE_EOFFSET + 0x14B) ///< QURT thread create failed
#define AEE_EQURTCOPYTOUSER (AEE_EOFFSET + 0x14C) ///< QURT copy to user memory failed
#define AEE_EQURTMEMMAPCREATE (AEE_EOFFSET + 0x14D) ///< QURT map create failed
#define AEE_EQURTINVHANDLE (AEE_EOFFSET + 0x14E) ///< QURT Invalid client handle
#define AEE_EQURTBADASID (AEE_EOFFSET + 0x14F) ///< QURT Bad ASIC from QURT
#define AEE_EQURTOPENFAILED (AEE_EOFFSET + 0x150) ///< QURT QDI open failed
#define AEE_EQURTCOPYFROMUSER (AEE_EOFFSET + 0x151) ///< QURT Copy from user failed
#define AEE_EQURTLINELOCK (AEE_EOFFSET + 0x152) ///< QURT Line lock failed
#define AEE_EQURTQDIDEFMETHOD (AEE_EOFFSET + 0x153) ///< QURT QDI default method failed
#define AEE_EQURTCREATEHANDLE (AEE_EOFFSET + 0x154) ///< QURT create handle from obj failed
#define AEE_EQURTWRITABLEMEM (AEE_EOFFSET + 0x155) ///< QURT CPZ migration writable mem
#define AEE_EQURTTHREADCREATEDEF (AEE_EOFFSET + 0x156) ///< QURT thread create def
#define AEE_EQURTLOOKUPVA (AEE_EOFFSET + 0x157) ///< QURT lookup VA
#define AEE_EQURTLOOKUPPA (AEE_EOFFSET + 0x158) ///< QURT lookup PA
#define AEE_EQURTMIGRATESECURE (AEE_EOFFSET + 0x159) ///< QURT CPZ migration failure
#define AEE_EQURTQDIOPEN (AEE_EOFFSET + 0X160) ///< QURT QDI open failure
#define AEE_EQURTMAPREMOVE (AEE_EOFFSET + 0X161) ///< QURT map remove failure
#define AEE_EQURTQDICLOSE (AEE_EOFFSET + 0X162) ///< QURT QDI close failed
#define AEE_EQURTWAIT (AEE_EOFFSET + 0X163) ///< QURT Futex wait failed
/**
* @}
*/
/** @defgroup mmpmerr MMPM error codes
* @{
*/
#define AEE_EMMPM_OFFSET (AEE_EOFFSET + 0x170) ///< MMPM errors offset
#define AEE_EMMPMREQUEST (AEE_EOFFSET + 0x171) ///< MMPM Power request to failed
#define AEE_EMMPMRELEASE (AEE_EOFFSET + 0x172) ///< MMPM Release request failed
#define AEE_EMMPMSETPARAM (AEE_EOFFSET + 0x173) ///< MMPM set param request failed
#define AEE_EMMPMREGISTER (AEE_EOFFSET + 0x174) ///< MMPM Register request failed
#define AEE_EMMPMGETINFO (AEE_EOFFSET + 0x175) ///< MMPM Get info failed
#define AEE_EMAX_MMPM_CLIENTS (AEE_EOFFSET + 0x176) ///< MMPM Reached maximum clients per PD(HAP_MAX_CLIENTS)
#define AEE_EDCVSREGISTER (AEE_EOFFSET + 0x177) ///< ADSP DCVS client registration failed
#define AEE_PDRREGFAIL (AEE_EOFFSET + 0x178) ///< Error Callback Services Registration failed for PD
/**
* @}
*/
#define AEE_DEFAULT_PROCESS (AEE_EOFFSET + 0x180) ///< Default process in Guest OS is not present
#define AEE_ENULLCONTEXT (AEE_EOFFSET + 0x181) ///< User NULL context vote
#define AEE_EINVALIDJOB (AEE_EOFFSET + 0x182) ///< AsyncRPC Invalid job
#define AEE_EBUSY (AEE_EOFFSET + 0x183) ///< AsyncRPC Pending job
/** @defgroup heaperror Heap error codes
* @{
*/
#define E_APPS_BUSY_RETRY_LATER (AEE_EOFFSET + 0x190) ///< Retry because the apps is busy
#define E_HLOS_CAP_REACHED (AEE_EOFFSET + 0x191) ///< cannot allocate any more hlos mem
#define E_DPOOL_CAP_REACHED (AEE_EOFFSET + 0x192) ///< cannot allocate any more physpool mem
#define E_NO_MORE_FREE_SECTIONS (AEE_EOFFSET + 0x193) ///< No more free sections available to grow heap
/**
* @}
*/
#endif /* #ifndef AEESTDERR_H */

685
extra/dsp/include/HAP_power.h Executable file
View File

@ -0,0 +1,685 @@
/*==============================================================================
@file
HAP_power.h
@brief
Header file of DSP power APIs.
Copyright (c) 2015,2019 Qualcomm Technologies, Inc.
All rights reserved. Qualcomm Proprietary and Confidential.
==============================================================================*/
#ifndef _HAP_POWER_H
#define _HAP_POWER_H
#include "AEEStdErr.h"
//#include <string.h>
//#include <stdlib.h>
#define boolean char
#define FALSE 0
#define TRUE 1
#define uint64 unsigned long long
#define uint32 unsigned int
#define NULL 0
#ifdef __cplusplus
extern "C" {
#endif
//Add a weak reference so shared objects do not throw link error
#pragma weak HAP_power_destroy_client
/**
* 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. */
} 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_MAX = 255,
} HAP_dcvs_voltage_corner_t;
/**
* @} // HAP_power_enums
*/
#define HAP_DCVS_VCORNER_SVSPLUS HAP_DCVS_VCORNER_SVS_PLUS
#define HAP_DCVS_VCORNER_NOMPLUS HAP_DCVS_VCORNER_NOM_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 */
boolean sleep_disable; /**< TRUE to disable sleep/LPM modes, FALSE to enable */
} 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;
/** @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_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 */
};
} 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 disable/enable all low power modes.
* @param[in] context - User context.
* @param[in] sleep_disable - TRUE to disable all low power modes.
* FALSE to re-enable all low power modes.
* @returns - 0 on success
*/
/*static inline int HAP_power_set_sleep_mode(void* context, boolean 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

View File

@ -0,0 +1,319 @@
/*
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef ADSPRPC_SHARED_H
#define ADSPRPC_SHARED_H
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <linux/types.h>
#define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke)
#define FASTRPC_IOCTL_MMAP _IOWR('R', 2, struct fastrpc_ioctl_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 3, struct fastrpc_ioctl_munmap)
#define FASTRPC_IOCTL_MMAP_64 _IOWR('R', 14, struct fastrpc_ioctl_mmap_64)
#define FASTRPC_IOCTL_MUNMAP_64 _IOWR('R', 15, struct fastrpc_ioctl_munmap_64)
#define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd)
#define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t)
#define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init)
#define FASTRPC_IOCTL_INVOKE_ATTRS \
_IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs)
#define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t)
#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf)
#define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs)
#define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc)
#define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control)
#define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd)
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
#define DEVICE_NAME "adsprpc-smd"
/* Set for buffers that have no virtual mapping in userspace */
#define FASTRPC_ATTR_NOVA 0x1
/* Set for buffers that are NOT dma coherent */
#define FASTRPC_ATTR_NON_COHERENT 0x2
/* Set for buffers that are dma coherent */
#define FASTRPC_ATTR_COHERENT 0x4
/* Fastrpc attribute for keeping the map persistent */
#define FASTRPC_ATTR_KEEP_MAP 0x8
/* Fastrpc attribute for no map */
#define FASTRPC_ATTR_NOMAP (16)
/* Driver should operate in parallel with the co-processor */
#define FASTRPC_MODE_PARALLEL 0
/* Driver should operate in serial mode with the co-processor */
#define FASTRPC_MODE_SERIAL 1
/* Driver should operate in profile mode with the co-processor */
#define FASTRPC_MODE_PROFILE 2
/* Set FastRPC session ID to 1 */
#define FASTRPC_MODE_SESSION 4
/* INIT a new process or attach to guestos */
#define FASTRPC_INIT_ATTACH 0
#define FASTRPC_INIT_CREATE 1
#define FASTRPC_INIT_CREATE_STATIC 2
#define FASTRPC_INIT_ATTACH_SENSORS 3
/* Retrives number of input buffers from the scalars parameter */
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
/* Retrives number of output buffers from the scalars parameter */
#define REMOTE_SCALARS_OUTBUFS(sc) (((sc) >> 8) & 0x0ff)
/* Retrives number of input handles from the scalars parameter */
#define REMOTE_SCALARS_INHANDLES(sc) (((sc) >> 4) & 0x0f)
/* Retrives number of output handles from the scalars parameter */
#define REMOTE_SCALARS_OUTHANDLES(sc) ((sc) & 0x0f)
#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\
REMOTE_SCALARS_OUTBUFS(sc) +\
REMOTE_SCALARS_INHANDLES(sc) +\
REMOTE_SCALARS_OUTHANDLES(sc))
#define REMOTE_SCALARS_MAKEX(attr, method, in, out, oin, oout) \
((((uint32_t) (attr) & 0x7) << 29) | \
(((uint32_t) (method) & 0x1f) << 24) | \
(((uint32_t) (in) & 0xff) << 16) | \
(((uint32_t) (out) & 0xff) << 8) | \
(((uint32_t) (oin) & 0x0f) << 4) | \
((uint32_t) (oout) & 0x0f))
#define REMOTE_SCALARS_MAKE(method, in, out) \
REMOTE_SCALARS_MAKEX(0, method, in, out, 0, 0)
#ifndef VERIFY_PRINT_ERROR
#define VERIFY_EPRINTF(format, args) (void)0
#endif
#ifndef VERIFY_PRINT_INFO
#define VERIFY_IPRINTF(args) (void)0
#endif
#ifndef VERIFY
#define __STR__(x) #x ":"
#define __TOSTR__(x) __STR__(x)
#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__)
#define VERIFY(err, val) \
do {\
VERIFY_IPRINTF(__FILE_LINE__"info: calling: " #val "\n");\
if ((val) == 0) {\
(err) = (err) == 0 ? -1 : (err);\
VERIFY_EPRINTF(__FILE_LINE__"error: %d: " #val "\n", (err));\
} else {\
VERIFY_IPRINTF(__FILE_LINE__"info: passed: " #val "\n");\
} \
} while (0)
#endif
#define remote_arg64_t union remote_arg64
struct remote_buf64 {
uint64_t pv;
uint64_t len;
};
struct remote_dma_handle64 {
int fd;
uint32_t offset;
uint32_t len;
};
union remote_arg64 {
struct remote_buf64 buf;
struct remote_dma_handle64 dma;
uint32_t h;
};
#define remote_arg_t union remote_arg
struct remote_buf {
void *pv; /* buffer pointer */
size_t len; /* length of buffer */
};
struct remote_dma_handle {
int fd;
uint32_t offset;
};
union remote_arg {
struct remote_buf buf; /* buffer info */
struct remote_dma_handle dma;
uint32_t h; /* remote handle */
};
struct fastrpc_ioctl_invoke {
uint32_t handle; /* remote handle */
uint32_t sc; /* scalars describing the data */
remote_arg_t *pra; /* remote arguments list */
};
struct fastrpc_ioctl_invoke_fd {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
};
struct fastrpc_ioctl_invoke_attrs {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
unsigned int *attrs; /* attribute list */
};
struct fastrpc_ioctl_invoke_crc {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
unsigned int *attrs; /* attribute list */
unsigned int *crc;
};
struct fastrpc_ioctl_init {
uint32_t flags; /* one of FASTRPC_INIT_* macros */
uintptr_t file; /* pointer to elf file */
uint32_t filelen; /* elf file length */
int32_t filefd; /* ION fd for the file */
uintptr_t mem; /* mem for the PD */
uint32_t memlen; /* mem length */
int32_t memfd; /* ION fd for the mem */
};
struct fastrpc_ioctl_init_attrs {
struct fastrpc_ioctl_init init;
int attrs;
unsigned int siglen;
};
struct fastrpc_ioctl_munmap {
uintptr_t vaddrout; /* address to unmap */
size_t size; /* size */
};
struct fastrpc_ioctl_munmap_64 {
uint64_t vaddrout; /* address to unmap */
size_t size; /* size */
};
struct fastrpc_ioctl_mmap {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
uintptr_t vaddrin; /* optional virtual address */
size_t size; /* size */
uintptr_t vaddrout; /* dsps virtual address */
};
struct fastrpc_ioctl_mmap_64 {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
uint64_t vaddrin; /* optional virtual address */
size_t size; /* size */
uint64_t vaddrout; /* dsps virtual address */
};
struct fastrpc_ioctl_munmap_fd {
int fd; /* fd */
uint32_t flags; /* control flags */
uintptr_t va; /* va */
ssize_t len; /* length */
};
struct fastrpc_ioctl_perf { /* kernel performance data */
uintptr_t data;
uint32_t numkeys;
uintptr_t keys;
};
#define FASTRPC_CONTROL_LATENCY (1)
struct fastrpc_ctrl_latency {
uint32_t enable; /* latency control enable */
uint32_t level; /* level of control */
};
#define FASTRPC_CONTROL_SMMU (2)
struct fastrpc_ctrl_smmu {
uint32_t sharedcb;
};
#define FASTRPC_CONTROL_KALLOC (3)
struct fastrpc_ctrl_kalloc {
uint32_t kalloc_support; /* Remote memory allocation from kernel */
};
struct fastrpc_ioctl_control {
uint32_t req;
union {
struct fastrpc_ctrl_latency lp;
struct fastrpc_ctrl_smmu smmu;
struct fastrpc_ctrl_kalloc kalloc;
};
};
struct smq_null_invoke {
uint64_t ctx; /* invoke caller context */
uint32_t handle; /* handle to invoke */
uint32_t sc; /* scalars structure describing the data */
};
struct smq_phy_page {
uint64_t addr; /* physical address */
uint64_t size; /* size of contiguous region */
};
struct smq_invoke_buf {
int num; /* number of contiguous regions */
int pgidx; /* index to start of contiguous region */
};
struct smq_invoke {
struct smq_null_invoke header;
struct smq_phy_page page; /* remote arg and list of pages address */
};
struct smq_msg {
uint32_t pid; /* process group id */
uint32_t tid; /* thread id */
struct smq_invoke invoke;
};
struct smq_invoke_rsp {
uint64_t ctx; /* invoke caller context */
int retval; /* invoke return value */
};
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
uint32_t sc)
{
unsigned int len = REMOTE_SCALARS_LENGTH(sc);
return (struct smq_invoke_buf *)(&pra[len]);
}
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
struct smq_invoke_buf *buf)
{
unsigned int nTotal = REMOTE_SCALARS_LENGTH(sc);
return (struct smq_phy_page *)(&buf[nTotal]);
}
#endif

View File

@ -0,0 +1,208 @@
/**
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 _APPS_STD_H
#define _APPS_STD_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
#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__ */
/**
* standard library functions remoted from the apps to the dsp
*/
typedef int apps_std_FILE;
enum apps_std_SEEK {
APPS_STD_SEEK_SET,
APPS_STD_SEEK_CUR,
APPS_STD_SEEK_END,
_32BIT_PLACEHOLDER_apps_std_SEEK = 0x7fffffff
};
typedef enum apps_std_SEEK apps_std_SEEK;
typedef struct apps_std_DIR apps_std_DIR;
struct apps_std_DIR {
uint64 handle;
};
typedef struct apps_std_DIRENT apps_std_DIRENT;
struct apps_std_DIRENT {
int ino;
char name[255];
};
typedef struct apps_std_STAT apps_std_STAT;
struct apps_std_STAT {
uint64 tsz;
uint64 dev;
uint64 ino;
uint32 mode;
uint32 nlink;
uint64 rdev;
uint64 size;
int64 atime;
int64 atimensec;
int64 mtime;
int64 mtimensec;
int64 ctime;
int64 ctimensec;
};
/**
* @retval, if operation fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen)(const char* name, const char* mode, apps_std_FILE* psout) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_freopen)(apps_std_FILE sin, const char* name, const char* mode, apps_std_FILE* psout) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fflush)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fclose)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
/**
* @param, bEOF, if read or write bytes <= bufLen bytes then feof() is called
* and the result is returned in bEOF, otherwise bEOF is set to 0.
* @retval, if read or write return 0 for non zero length buffers, ferror is checked
* and a non zero value is returned in case of error with no rout parameters
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fread)(apps_std_FILE sin, byte* buf, int bufLen, int* bytesRead, int* bEOF) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fwrite)(apps_std_FILE sin, const byte* buf, int bufLen, int* bytesWritten, int* bEOF) __QAIC_HEADER_ATTRIBUTE;
/**
* @param, pos, this buffer is filled up to MIN(posLen, sizeof(fpos_t))
* @param, posLenReq, returns sizeof(fpos_t)
* @retval, if operation fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgetpos)(apps_std_FILE sin, byte* pos, int posLen, int* posLenReq) __QAIC_HEADER_ATTRIBUTE;
/**
* @param, if size of pos doesn't match the system size an error is returned.
* fgetpos can be used to query the size of fpos_t
* @retval, if operation fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fsetpos)(apps_std_FILE sin, const byte* pos, int posLen) __QAIC_HEADER_ATTRIBUTE;
/**
* @retval, if operation fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ftell)(apps_std_FILE sin, int* pos) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fseek)(apps_std_FILE sin, int offset, apps_std_SEEK whence) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_flen)(apps_std_FILE sin, uint64* len) __QAIC_HEADER_ATTRIBUTE;
/**
* @retval, only fails if transport fails
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_rewind)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_feof)(apps_std_FILE sin, int* bEOF) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ferror)(apps_std_FILE sin, int* err) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_clearerr)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_print_string)(const char* str) __QAIC_HEADER_ATTRIBUTE;
/**
* @param val, must contain space for NULL
* @param valLenReq, length required with NULL
* @retval, if fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_getenv)(const char* name, char* val, int valLen, int* valLenReq) __QAIC_HEADER_ATTRIBUTE;
/**
* @retval, if fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_setenv)(const char* name, const char* val, int override) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_unsetenv)(const char* name) __QAIC_HEADER_ATTRIBUTE;
/**
* This function will try to open a file given directories in envvarname separated by
* delim.
* so given environment variable FOO_PATH=/foo;/bar
* fopen_wth_env("FOO_PATH", ";", "path/to/file", "rw", &out);
* will try to open /foo/path/to/file, /bar/path/to/file
* if the variable is unset, it will open the file directly
*
* @param envvarname, name of the environment variable containing the path
* @param delim, delimiator string, such as ";"
* @param name, name of the file
* @param mode, mode
* @param psout, output handle
* @retval, 0 on success errno or -1 on failure
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen_with_env)(const char* envvarname, const char* delim, const char* name, const char* mode, apps_std_FILE* psout) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgets)(apps_std_FILE sin, byte* buf, int bufLen, int* bEOF) __QAIC_HEADER_ATTRIBUTE;
/**
* This method will return the paths that are searched when looking for a file.
* The paths are defined by the environment variable (separated by delimiters)
* that is passed to the method.
*
* @param envvarname, name of the environment variable containing the path
* @param delim, delimiator string, such as ";"
* @param name, name of the file
* @param paths, Search paths
* @param numPaths, Actual number of paths found
* @param maxPathLen, The max path length
* @retval, 0 on success errno or -1 on failure
*
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_get_search_paths_with_env)(const char* envvarname, const char* delim, _cstring1_t* paths, int pathsLen, uint32* numPaths, uint16* maxPathLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fileExists)(const char* path, boolean* exists) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fsync)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fremove)(const char* name) __QAIC_HEADER_ATTRIBUTE;
/**
* This function decrypts the file using the provided open file descriptor, closes the
* original descriptor and return a new file descriptor.
* @retval, if operation fails errno is returned
*/
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fdopen_decrypt)(apps_std_FILE sin, apps_std_FILE* psout) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_opendir)(const char* name, apps_std_DIR* dir) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_closedir)(const apps_std_DIR* dir) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_readdir)(const apps_std_DIR* dir, apps_std_DIRENT* dirent, int* bEOF) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_mkdir)(const char* name, int mode) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_rmdir)(const char* name) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_stat)(const char* name, apps_std_STAT* stat) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ftrunc)(apps_std_FILE sin, int offset) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_frename)(const char* oldname, const char* newname) __QAIC_HEADER_ATTRIBUTE;
#ifdef __cplusplus
}
#endif
#endif //_APPS_STD_H

204
extra/dsp/include/ion.h Normal file
View File

@ -0,0 +1,204 @@
/*
* drivers/staging/android/uapi/ion.h
*
* Copyright (C) 2011 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _UAPI_LINUX_ION_H
#define _UAPI_LINUX_ION_H
#include <stddef.h>
#include <linux/ioctl.h>
#include <linux/types.h>
typedef int ion_user_handle_t;
/**
* enum ion_heap_types - list of all possible types of heaps
* @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
* @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
* @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved
* carveout heap, allocations are physically
* contiguous
* @ION_HEAP_TYPE_DMA: memory allocated via DMA API
* @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask
* is used to identify the heaps, so only 32
* total heap types are supported
*/
enum ion_heap_type {
ION_HEAP_TYPE_SYSTEM,
ION_HEAP_TYPE_SYSTEM_CONTIG,
ION_HEAP_TYPE_CARVEOUT,
ION_HEAP_TYPE_CHUNK,
ION_HEAP_TYPE_DMA,
ION_HEAP_TYPE_CUSTOM, /*
* must be last so device specific heaps always
* are at the end of this enum
*/
ION_NUM_HEAPS = 16,
};
#define ION_HEAP_SYSTEM_MASK ((1 << ION_HEAP_TYPE_SYSTEM))
#define ION_HEAP_SYSTEM_CONTIG_MASK ((1 << ION_HEAP_TYPE_SYSTEM_CONTIG))
#define ION_HEAP_CARVEOUT_MASK ((1 << ION_HEAP_TYPE_CARVEOUT))
#define ION_HEAP_TYPE_DMA_MASK ((1 << ION_HEAP_TYPE_DMA))
#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8)
/**
* allocation flags - the lower 16 bits are used by core ion, the upper 16
* bits are reserved for use by the heaps themselves.
*/
#define ION_FLAG_CACHED 1 /*
* mappings of this buffer should be
* cached, ion will do cache
* maintenance when the buffer is
* mapped for dma
*/
#define ION_FLAG_CACHED_NEEDS_SYNC 2 /*
* mappings of this buffer will created
* at mmap time, if this is set
* caches must be managed
* manually
*/
/**
* DOC: Ion Userspace API
*
* create a client by opening /dev/ion
* most operations handled via following ioctls
*
*/
/**
* struct ion_allocation_data - metadata passed from userspace for allocations
* @len: size of the allocation
* @align: required alignment of the allocation
* @heap_id_mask: mask of heap ids to allocate from
* @flags: flags passed to heap
* @handle: pointer that will be populated with a cookie to use to
* refer to this allocation
*
* Provided by userspace as an argument to the ioctl
*/
struct ion_allocation_data {
size_t len;
size_t align;
unsigned int heap_id_mask;
unsigned int flags;
ion_user_handle_t handle;
};
/**
* struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
* @handle: a handle
* @fd: a file descriptor representing that handle
*
* For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
* the handle returned from ion alloc, and the kernel returns the file
* descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
ion_user_handle_t handle;
int fd;
};
/**
* struct ion_handle_data - a handle passed to/from the kernel
* @handle: a handle
*/
struct ion_handle_data {
ion_user_handle_t handle;
};
/**
* struct ion_custom_data - metadata passed to/from userspace for a custom ioctl
* @cmd: the custom ioctl function to call
* @arg: additional data to pass to the custom ioctl, typically a user
* pointer to a predefined structure
*
* This works just like the regular cmd and arg fields of an ioctl.
*/
struct ion_custom_data {
unsigned int cmd;
unsigned long arg;
};
#define ION_IOC_MAGIC 'I'
/**
* DOC: ION_IOC_ALLOC - allocate memory
*
* Takes an ion_allocation_data struct and returns it with the handle field
* populated with the opaque handle for the allocation.
*/
#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
struct ion_allocation_data)
/**
* DOC: ION_IOC_FREE - free memory
*
* Takes an ion_handle_data struct and frees the handle.
*/
#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
/**
* DOC: ION_IOC_MAP - get a file descriptor to mmap
*
* Takes an ion_fd_data struct with the handle field populated with a valid
* opaque handle. Returns the struct with the fd field set to a file
* descriptor open in the current address space. This file descriptor
* can then be used as an argument to mmap.
*/
#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
/**
* DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
*
* Takes an ion_fd_data struct with the handle field populated with a valid
* opaque handle. Returns the struct with the fd field set to a file
* descriptor open in the current address space. This file descriptor
* can then be passed to another process. The corresponding opaque handle can
* be retrieved via ION_IOC_IMPORT.
*/
#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
/**
* DOC: ION_IOC_IMPORT - imports a shared file descriptor
*
* Takes an ion_fd_data struct with the fd field populated with a valid file
* descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
* filed set to the corresponding opaque handle.
*/
#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
/**
* DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory
*
* Deprecated in favor of using the dma_buf api's correctly (syncing
* will happen automatically when the buffer is mapped to a device).
* If necessary should be used after touching a cached buffer from the cpu,
* this will make the buffer in memory coherent.
*/
#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data)
/**
* DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl
*
* Takes the argument of the architecture specific ioctl to call and
* passes appropriate userdata for that ioctl
*/
#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
#endif /* _UAPI_LINUX_ION_H */

211
extra/dsp/include/msm_ion.h Normal file
View File

@ -0,0 +1,211 @@
#ifndef _UAPI_MSM_ION_H
#define _UAPI_MSM_ION_H
#include "ion.h"
enum msm_ion_heap_types {
ION_HEAP_TYPE_MSM_START = ION_HEAP_TYPE_CUSTOM + 1,
ION_HEAP_TYPE_SECURE_DMA = ION_HEAP_TYPE_MSM_START,
ION_HEAP_TYPE_SYSTEM_SECURE,
ION_HEAP_TYPE_HYP_CMA,
/*
* if you add a heap type here you should also add it to
* heap_types_info[] in msm_ion.c
*/
};
/**
* These are the only ids that should be used for Ion heap ids.
* The ids listed are the order in which allocation will be attempted
* if specified. Don't swap the order of heap ids unless you know what
* you are doing!
* Id's are spaced by purpose to allow new Id's to be inserted in-between (for
* possible fallbacks)
*/
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_CP_WB_HEAP_ID = 16, /* 8660 only */
ION_CAMERA_HEAP_ID = 20, /* 8660 only */
ION_SYSTEM_CONTIG_HEAP_ID = 21,
ION_ADSP_HEAP_ID = 22,
ION_PIL1_HEAP_ID = 23, /* Currently used for other PIL images */
ION_SF_HEAP_ID = 24,
ION_SYSTEM_HEAP_ID = 25,
ION_PIL2_HEAP_ID = 26, /* Currently used for modem firmware images */
ION_QSECOM_HEAP_ID = 27,
ION_AUDIO_HEAP_ID = 28,
ION_MM_FIRMWARE_HEAP_ID = 29,
ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_FLAG_SECURE flag */
};
/*
* The IOMMU heap is deprecated! Here are some aliases for backwards
* compatibility:
*/
#define ION_IOMMU_HEAP_ID ION_SYSTEM_HEAP_ID
#define ION_HEAP_TYPE_IOMMU ION_HEAP_TYPE_SYSTEM
enum ion_fixed_position {
NOT_FIXED,
FIXED_LOW,
FIXED_MIDDLE,
FIXED_HIGH,
};
enum cp_mem_usage {
VIDEO_BITSTREAM = 0x1,
VIDEO_PIXEL = 0x2,
VIDEO_NONPIXEL = 0x3,
DISPLAY_SECURE_CP_USAGE = 0x4,
CAMERA_SECURE_CP_USAGE = 0x5,
MAX_USAGE = 0x6,
UNKNOWN = 0x7FFFFFFF,
};
/**
* Flags to be used when allocating from the secure heap for
* content protection
*/
#define ION_FLAG_CP_TOUCH (1 << 17)
#define ION_FLAG_CP_BITSTREAM (1 << 18)
#define ION_FLAG_CP_PIXEL (1 << 19)
#define ION_FLAG_CP_NON_PIXEL (1 << 20)
#define ION_FLAG_CP_CAMERA (1 << 21)
#define ION_FLAG_CP_HLOS (1 << 22)
#define ION_FLAG_CP_HLOS_FREE (1 << 23)
#define ION_FLAG_CP_SEC_DISPLAY (1 << 25)
#define ION_FLAG_CP_APP (1 << 26)
/**
* Flag to allow non continguous allocation of memory from secure
* heap
*/
#define ION_FLAG_ALLOW_NON_CONTIG (1 << 24)
/**
* Flag to use when allocating to indicate that a heap is secure.
*/
#define ION_FLAG_SECURE (1 << ION_HEAP_ID_RESERVED)
/**
* Flag for clients to force contiguous memort allocation
*
* Use of this flag is carefully monitored!
*/
#define ION_FLAG_FORCE_CONTIGUOUS (1 << 30)
/*
* Used in conjunction with heap which pool memory to force an allocation
* to come from the page allocator directly instead of from the pool allocation
*/
#define ION_FLAG_POOL_FORCE_ALLOC (1 << 16)
#define ION_FLAG_POOL_PREFETCH (1 << 27)
/**
* Deprecated! Please use the corresponding ION_FLAG_*
*/
#define ION_SECURE ION_FLAG_SECURE
#define ION_FORCE_CONTIGUOUS ION_FLAG_FORCE_CONTIGUOUS
/**
* Macro should be used with ion_heap_ids defined above.
*/
#define ION_HEAP(bit) (1 << (bit))
#define ION_ADSP_HEAP_NAME "adsp"
#define ION_SYSTEM_HEAP_NAME "system"
#define ION_VMALLOC_HEAP_NAME ION_SYSTEM_HEAP_NAME
#define ION_KMALLOC_HEAP_NAME "kmalloc"
#define ION_AUDIO_HEAP_NAME "audio"
#define ION_SF_HEAP_NAME "sf"
#define ION_MM_HEAP_NAME "mm"
#define ION_CAMERA_HEAP_NAME "camera_preview"
#define ION_IOMMU_HEAP_NAME "iommu"
#define ION_MFC_HEAP_NAME "mfc"
#define ION_WB_HEAP_NAME "wb"
#define ION_MM_FIRMWARE_HEAP_NAME "mm_fw"
#define ION_PIL1_HEAP_NAME "pil_1"
#define ION_PIL2_HEAP_NAME "pil_2"
#define ION_QSECOM_HEAP_NAME "qsecom"
#define ION_SECURE_HEAP_NAME "secure_heap"
#define ION_SECURE_DISPLAY_HEAP_NAME "secure_display"
#define ION_SET_CACHED(__cache) (__cache | ION_FLAG_CACHED)
#define ION_SET_UNCACHED(__cache) (__cache & ~ION_FLAG_CACHED)
#define ION_IS_CACHED(__flags) ((__flags) & ION_FLAG_CACHED)
/* struct ion_flush_data - data passed to ion for flushing caches
*
* @handle: handle with data to flush
* @fd: fd to flush
* @vaddr: userspace virtual address mapped with mmap
* @offset: offset into the handle to flush
* @length: length of handle to flush
*
* Performs cache operations on the handle. If p is the start address
* of the handle, p + offset through p + offset + length will have
* the cache operations performed
*/
struct ion_flush_data {
ion_user_handle_t handle;
int fd;
void *vaddr;
unsigned int offset;
unsigned int length;
};
struct ion_prefetch_regions {
unsigned int vmid;
size_t *sizes;
unsigned int nr_sizes;
};
struct ion_prefetch_data {
int heap_id;
unsigned long len;
/* Is unsigned long bad? 32bit compiler vs 64 bit compiler*/
struct ion_prefetch_regions *regions;
unsigned int nr_regions;
};
#define ION_IOC_MSM_MAGIC 'M'
/**
* DOC: ION_IOC_CLEAN_CACHES - clean the caches
*
* Clean the caches of the handle specified.
*/
#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MSM_MAGIC, 0, \
struct ion_flush_data)
/**
* DOC: ION_IOC_INV_CACHES - invalidate the caches
*
* Invalidate the caches of the handle specified.
*/
#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MSM_MAGIC, 1, \
struct ion_flush_data)
/**
* DOC: ION_IOC_CLEAN_INV_CACHES - clean and invalidate the caches
*
* Clean and invalidate the caches of the handle specified.
*/
#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MSM_MAGIC, 2, \
struct ion_flush_data)
#define ION_IOC_PREFETCH _IOWR(ION_IOC_MSM_MAGIC, 3, \
struct ion_prefetch_data)
#define ION_IOC_DRAIN _IOWR(ION_IOC_MSM_MAGIC, 4, \
struct ion_prefetch_data)
#endif

File diff suppressed because it is too large Load Diff

326
extra/dsp/invoke_bug.py Normal file
View File

@ -0,0 +1,326 @@
from tinygrad.runtime.ops_dsp import DSPDevice
kernel = """__attribute__((noinline)) void r_6_10_13_4_4_29(float* restrict __attribute__((align_value(128))) data0, const float* restrict __attribute__((align_value(128))) data1, const float* restrict __attribute__((align_value(128))) data2, const float* restrict __attribute__((align_value(128))) data3) {
float val0 = data1[0];
float val1 = data1[1];
float val2 = data1[2];
float val3 = data1[3];
float val4 = data1[4];
float val5 = data1[5];
float val6 = data1[6];
float val7 = data1[7];
float val8 = data1[8];
float val9 = data1[9];
float val10 = data1[10];
float val11 = data1[11];
float val12 = data1[12];
float val13 = data1[13];
float val14 = data1[14];
float val15 = data1[15];
float val16 = data1[16];
float val17 = data1[17];
float val18 = data1[18];
float val19 = data1[19];
float val20 = data1[20];
float val21 = data1[21];
float val22 = data1[22];
float val23 = data1[23];
float val24 = data1[24];
float val25 = data1[25];
float val26 = data1[26];
float val27 = data1[27];
float val28 = data1[28];
for (int ridx0 = 0; ridx0 < 6; ridx0++) {
for (int ridx1 = 0; ridx1 < 10; ridx1++) {
int alu0 = ((ridx0*1160)+(ridx1*4));
float val29 = data3[alu0+1];
float val30 = data3[alu0+2];
float val31 = data3[alu0+3];
float val32 = data3[alu0+40];
float val33 = data3[alu0+41];
float val34 = data3[alu0+42];
float val35 = data3[alu0+43];
float val36 = data3[alu0+80];
float val37 = data3[alu0+81];
float val38 = data3[alu0+82];
float val39 = data3[alu0+83];
float val40 = data3[alu0+120];
float val41 = data3[alu0+121];
float val42 = data3[alu0+122];
float val43 = data3[alu0+123];
float val44 = data3[alu0+160];
float val45 = data3[alu0+161];
float val46 = data3[alu0+162];
float val47 = data3[alu0+163];
float val48 = data3[alu0+200];
float val49 = data3[alu0+201];
float val50 = data3[alu0+202];
float val51 = data3[alu0+203];
float val52 = data3[alu0+240];
float val53 = data3[alu0+241];
float val54 = data3[alu0+242];
float val55 = data3[alu0+243];
float val56 = data3[alu0+280];
float val57 = data3[alu0+281];
float val58 = data3[alu0+282];
float val59 = data3[alu0+283];
float val60 = data3[alu0+320];
float val61 = data3[alu0+321];
float val62 = data3[alu0+322];
float val63 = data3[alu0+323];
float val64 = data3[alu0+360];
float val65 = data3[alu0+361];
float val66 = data3[alu0+362];
float val67 = data3[alu0+363];
float val68 = data3[alu0+400];
float val69 = data3[alu0+401];
float val70 = data3[alu0+402];
float val71 = data3[alu0+403];
float val72 = data3[alu0+440];
float val73 = data3[alu0+441];
float val74 = data3[alu0+442];
float val75 = data3[alu0+443];
float val76 = data3[alu0+480];
float val77 = data3[alu0+481];
float val78 = data3[alu0+482];
float val79 = data3[alu0+483];
float val80 = data3[alu0+520];
float val81 = data3[alu0+521];
float val82 = data3[alu0+522];
float val83 = data3[alu0+523];
float val84 = data3[alu0+560];
float val85 = data3[alu0+561];
float val86 = data3[alu0+562];
float val87 = data3[alu0+563];
float val88 = data3[alu0+600];
float val89 = data3[alu0+601];
float val90 = data3[alu0+602];
float val91 = data3[alu0+603];
float val92 = data3[alu0+640];
float val93 = data3[alu0+641];
float val94 = data3[alu0+642];
float val95 = data3[alu0+643];
float val96 = data3[alu0+680];
float val97 = data3[alu0+681];
float val98 = data3[alu0+682];
float val99 = data3[alu0+683];
float val100 = data3[alu0+720];
float val101 = data3[alu0+721];
float val102 = data3[alu0+722];
float val103 = data3[alu0+723];
float val104 = data3[alu0+760];
float val105 = data3[alu0+761];
float val106 = data3[alu0+762];
float val107 = data3[alu0+763];
float val108 = data3[alu0+800];
float val109 = data3[alu0+801];
float val110 = data3[alu0+802];
float val111 = data3[alu0+803];
float val112 = data3[alu0+840];
float val113 = data3[alu0+841];
float val114 = data3[alu0+842];
float val115 = data3[alu0+843];
float val116 = data3[alu0+880];
float val117 = data3[alu0+881];
float val118 = data3[alu0+882];
float val119 = data3[alu0+883];
float val120 = data3[alu0+920];
float val121 = data3[alu0+921];
float val122 = data3[alu0+922];
float val123 = data3[alu0+923];
float val124 = data3[alu0+960];
float val125 = data3[alu0+961];
float val126 = data3[alu0+962];
float val127 = data3[alu0+963];
float val128 = data3[alu0+1000];
float val129 = data3[alu0+1001];
float val130 = data3[alu0+1002];
float val131 = data3[alu0+1003];
float val132 = data3[alu0+1040];
float val133 = data3[alu0+1041];
float val134 = data3[alu0+1042];
float val135 = data3[alu0+1043];
float val136 = data3[alu0+1080];
float val137 = data3[alu0+1081];
float val138 = data3[alu0+1082];
float val139 = data3[alu0+1083];
float val140 = data3[alu0+1120];
float val141 = data3[alu0+1121];
float val142 = data3[alu0+1122];
float val143 = data3[alu0+1123];
float val144 = data3[alu0];
for (int ridx2 = 0; ridx2 < 13; ridx2++) {
int alu1 = (ridx2*4);
int alu2 = ((ridx0*2080)+(ridx1*208)+alu1);
float val145 = data2[alu1+1];
float cast0 = (float)(((val0!=val145)!=1));
float cast1 = (float)(((val1!=val145)!=1));
float cast2 = (float)(((val2!=val145)!=1));
float cast3 = (float)(((val3!=val145)!=1));
float cast4 = (float)(((val4!=val145)!=1));
float cast5 = (float)(((val5!=val145)!=1));
float cast6 = (float)(((val6!=val145)!=1));
float cast7 = (float)(((val7!=val145)!=1));
float cast8 = (float)(((val8!=val145)!=1));
float cast9 = (float)(((val9!=val145)!=1));
float cast10 = (float)(((val10!=val145)!=1));
float cast11 = (float)(((val11!=val145)!=1));
float cast12 = (float)(((val12!=val145)!=1));
float cast13 = (float)(((val13!=val145)!=1));
float cast14 = (float)(((val14!=val145)!=1));
float cast15 = (float)(((val15!=val145)!=1));
float cast16 = (float)(((val16!=val145)!=1));
float cast17 = (float)(((val17!=val145)!=1));
float cast18 = (float)(((val18!=val145)!=1));
float cast19 = (float)(((val19!=val145)!=1));
float cast20 = (float)(((val20!=val145)!=1));
float cast21 = (float)(((val21!=val145)!=1));
float cast22 = (float)(((val22!=val145)!=1));
float cast23 = (float)(((val23!=val145)!=1));
float cast24 = (float)(((val24!=val145)!=1));
float cast25 = (float)(((val25!=val145)!=1));
float cast26 = (float)(((val26!=val145)!=1));
float cast27 = (float)(((val27!=val145)!=1));
float cast28 = (float)(((val28!=val145)!=1));
data0[alu2+1] = ((cast0*val144)+(cast1*val32)+(cast2*val36)+(cast3*val40)+(cast4*val44)+(cast5*val48)+(cast6*val52)+(cast7*val56)+(cast8*val60)+(cast9*val64)+(cast10*val68)+(cast11*val72)+(cast12*val76)+(cast13*val80)+(cast14*val84)+(cast15*val88)+(cast16*val92)+(cast17*val96)+(cast18*val100)+(cast19*val104)+(cast20*val108)+(cast21*val112)+(cast22*val116)+(cast23*val120)+(cast24*val124)+(cast25*val128)+(cast26*val132)+(cast27*val136)+(cast28*val140));
data0[alu2+53] = ((cast0*val29)+(cast1*val33)+(cast2*val37)+(cast3*val41)+(cast4*val45)+(cast5*val49)+(cast6*val53)+(cast7*val57)+(cast8*val61)+(cast9*val65)+(cast10*val69)+(cast11*val73)+(cast12*val77)+(cast13*val81)+(cast14*val85)+(cast15*val89)+(cast16*val93)+(cast17*val97)+(cast18*val101)+(cast19*val105)+(cast20*val109)+(cast21*val113)+(cast22*val117)+(cast23*val121)+(cast24*val125)+(cast25*val129)+(cast26*val133)+(cast27*val137)+(cast28*val141));
data0[alu2+105] = ((cast0*val30)+(cast1*val34)+(cast2*val38)+(cast3*val42)+(cast4*val46)+(cast5*val50)+(cast6*val54)+(cast7*val58)+(cast8*val62)+(cast9*val66)+(cast10*val70)+(cast11*val74)+(cast12*val78)+(cast13*val82)+(cast14*val86)+(cast15*val90)+(cast16*val94)+(cast17*val98)+(cast18*val102)+(cast19*val106)+(cast20*val110)+(cast21*val114)+(cast22*val118)+(cast23*val122)+(cast24*val126)+(cast25*val130)+(cast26*val134)+(cast27*val138)+(cast28*val142));
data0[alu2+157] = ((cast0*val31)+(cast1*val35)+(cast2*val39)+(cast3*val43)+(cast4*val47)+(cast5*val51)+(cast6*val55)+(cast7*val59)+(cast8*val63)+(cast9*val67)+(cast10*val71)+(cast11*val75)+(cast12*val79)+(cast13*val83)+(cast14*val87)+(cast15*val91)+(cast16*val95)+(cast17*val99)+(cast18*val103)+(cast19*val107)+(cast20*val111)+(cast21*val115)+(cast22*val119)+(cast23*val123)+(cast24*val127)+(cast25*val131)+(cast26*val135)+(cast27*val139)+(cast28*val143));
float val146 = data2[alu1+2];
float cast29 = (float)(((val0!=val146)!=1));
float cast30 = (float)(((val1!=val146)!=1));
float cast31 = (float)(((val2!=val146)!=1));
float cast32 = (float)(((val3!=val146)!=1));
float cast33 = (float)(((val4!=val146)!=1));
float cast34 = (float)(((val5!=val146)!=1));
float cast35 = (float)(((val6!=val146)!=1));
float cast36 = (float)(((val7!=val146)!=1));
float cast37 = (float)(((val8!=val146)!=1));
float cast38 = (float)(((val9!=val146)!=1));
float cast39 = (float)(((val10!=val146)!=1));
float cast40 = (float)(((val11!=val146)!=1));
float cast41 = (float)(((val12!=val146)!=1));
float cast42 = (float)(((val13!=val146)!=1));
float cast43 = (float)(((val14!=val146)!=1));
float cast44 = (float)(((val15!=val146)!=1));
float cast45 = (float)(((val16!=val146)!=1));
float cast46 = (float)(((val17!=val146)!=1));
float cast47 = (float)(((val18!=val146)!=1));
float cast48 = (float)(((val19!=val146)!=1));
float cast49 = (float)(((val20!=val146)!=1));
float cast50 = (float)(((val21!=val146)!=1));
float cast51 = (float)(((val22!=val146)!=1));
float cast52 = (float)(((val23!=val146)!=1));
float cast53 = (float)(((val24!=val146)!=1));
float cast54 = (float)(((val25!=val146)!=1));
float cast55 = (float)(((val26!=val146)!=1));
float cast56 = (float)(((val27!=val146)!=1));
float cast57 = (float)(((val28!=val146)!=1));
data0[alu2+2] = ((cast29*val144)+(cast30*val32)+(cast31*val36)+(cast32*val40)+(cast33*val44)+(cast34*val48)+(cast35*val52)+(cast36*val56)+(cast37*val60)+(cast38*val64)+(cast39*val68)+(cast40*val72)+(cast41*val76)+(cast42*val80)+(cast43*val84)+(cast44*val88)+(cast45*val92)+(cast46*val96)+(cast47*val100)+(cast48*val104)+(cast49*val108)+(cast50*val112)+(cast51*val116)+(cast52*val120)+(cast53*val124)+(cast54*val128)+(cast55*val132)+(cast56*val136)+(cast57*val140));
data0[alu2+54] = ((cast29*val29)+(cast30*val33)+(cast31*val37)+(cast32*val41)+(cast33*val45)+(cast34*val49)+(cast35*val53)+(cast36*val57)+(cast37*val61)+(cast38*val65)+(cast39*val69)+(cast40*val73)+(cast41*val77)+(cast42*val81)+(cast43*val85)+(cast44*val89)+(cast45*val93)+(cast46*val97)+(cast47*val101)+(cast48*val105)+(cast49*val109)+(cast50*val113)+(cast51*val117)+(cast52*val121)+(cast53*val125)+(cast54*val129)+(cast55*val133)+(cast56*val137)+(cast57*val141));
data0[alu2+106] = ((cast29*val30)+(cast30*val34)+(cast31*val38)+(cast32*val42)+(cast33*val46)+(cast34*val50)+(cast35*val54)+(cast36*val58)+(cast37*val62)+(cast38*val66)+(cast39*val70)+(cast40*val74)+(cast41*val78)+(cast42*val82)+(cast43*val86)+(cast44*val90)+(cast45*val94)+(cast46*val98)+(cast47*val102)+(cast48*val106)+(cast49*val110)+(cast50*val114)+(cast51*val118)+(cast52*val122)+(cast53*val126)+(cast54*val130)+(cast55*val134)+(cast56*val138)+(cast57*val142));
data0[alu2+158] = ((cast29*val31)+(cast30*val35)+(cast31*val39)+(cast32*val43)+(cast33*val47)+(cast34*val51)+(cast35*val55)+(cast36*val59)+(cast37*val63)+(cast38*val67)+(cast39*val71)+(cast40*val75)+(cast41*val79)+(cast42*val83)+(cast43*val87)+(cast44*val91)+(cast45*val95)+(cast46*val99)+(cast47*val103)+(cast48*val107)+(cast49*val111)+(cast50*val115)+(cast51*val119)+(cast52*val123)+(cast53*val127)+(cast54*val131)+(cast55*val135)+(cast56*val139)+(cast57*val143));
float val147 = data2[alu1+3];
float cast58 = (float)(((val0!=val147)!=1));
float cast59 = (float)(((val1!=val147)!=1));
float cast60 = (float)(((val2!=val147)!=1));
float cast61 = (float)(((val3!=val147)!=1));
float cast62 = (float)(((val4!=val147)!=1));
float cast63 = (float)(((val5!=val147)!=1));
float cast64 = (float)(((val6!=val147)!=1));
float cast65 = (float)(((val7!=val147)!=1));
float cast66 = (float)(((val8!=val147)!=1));
float cast67 = (float)(((val9!=val147)!=1));
float cast68 = (float)(((val10!=val147)!=1));
float cast69 = (float)(((val11!=val147)!=1));
float cast70 = (float)(((val12!=val147)!=1));
float cast71 = (float)(((val13!=val147)!=1));
float cast72 = (float)(((val14!=val147)!=1));
float cast73 = (float)(((val15!=val147)!=1));
float cast74 = (float)(((val16!=val147)!=1));
float cast75 = (float)(((val17!=val147)!=1));
float cast76 = (float)(((val18!=val147)!=1));
float cast77 = (float)(((val19!=val147)!=1));
float cast78 = (float)(((val20!=val147)!=1));
float cast79 = (float)(((val21!=val147)!=1));
float cast80 = (float)(((val22!=val147)!=1));
float cast81 = (float)(((val23!=val147)!=1));
float cast82 = (float)(((val24!=val147)!=1));
float cast83 = (float)(((val25!=val147)!=1));
float cast84 = (float)(((val26!=val147)!=1));
float cast85 = (float)(((val27!=val147)!=1));
float cast86 = (float)(((val28!=val147)!=1));
data0[alu2+3] = ((cast58*val144)+(cast59*val32)+(cast60*val36)+(cast61*val40)+(cast62*val44)+(cast63*val48)+(cast64*val52)+(cast65*val56)+(cast66*val60)+(cast67*val64)+(cast68*val68)+(cast69*val72)+(cast70*val76)+(cast71*val80)+(cast72*val84)+(cast73*val88)+(cast74*val92)+(cast75*val96)+(cast76*val100)+(cast77*val104)+(cast78*val108)+(cast79*val112)+(cast80*val116)+(cast81*val120)+(cast82*val124)+(cast83*val128)+(cast84*val132)+(cast85*val136)+(cast86*val140));
data0[alu2+55] = ((cast58*val29)+(cast59*val33)+(cast60*val37)+(cast61*val41)+(cast62*val45)+(cast63*val49)+(cast64*val53)+(cast65*val57)+(cast66*val61)+(cast67*val65)+(cast68*val69)+(cast69*val73)+(cast70*val77)+(cast71*val81)+(cast72*val85)+(cast73*val89)+(cast74*val93)+(cast75*val97)+(cast76*val101)+(cast77*val105)+(cast78*val109)+(cast79*val113)+(cast80*val117)+(cast81*val121)+(cast82*val125)+(cast83*val129)+(cast84*val133)+(cast85*val137)+(cast86*val141));
data0[alu2+107] = ((cast58*val30)+(cast59*val34)+(cast60*val38)+(cast61*val42)+(cast62*val46)+(cast63*val50)+(cast64*val54)+(cast65*val58)+(cast66*val62)+(cast67*val66)+(cast68*val70)+(cast69*val74)+(cast70*val78)+(cast71*val82)+(cast72*val86)+(cast73*val90)+(cast74*val94)+(cast75*val98)+(cast76*val102)+(cast77*val106)+(cast78*val110)+(cast79*val114)+(cast80*val118)+(cast81*val122)+(cast82*val126)+(cast83*val130)+(cast84*val134)+(cast85*val138)+(cast86*val142));
data0[alu2+159] = ((cast58*val31)+(cast59*val35)+(cast60*val39)+(cast61*val43)+(cast62*val47)+(cast63*val51)+(cast64*val55)+(cast65*val59)+(cast66*val63)+(cast67*val67)+(cast68*val71)+(cast69*val75)+(cast70*val79)+(cast71*val83)+(cast72*val87)+(cast73*val91)+(cast74*val95)+(cast75*val99)+(cast76*val103)+(cast77*val107)+(cast78*val111)+(cast79*val115)+(cast80*val119)+(cast81*val123)+(cast82*val127)+(cast83*val131)+(cast84*val135)+(cast85*val139)+(cast86*val143));
float val148 = data2[alu1];
float cast87 = (float)(((val0!=val148)!=1));
float cast88 = (float)(((val1!=val148)!=1));
float cast89 = (float)(((val2!=val148)!=1));
float cast90 = (float)(((val3!=val148)!=1));
float cast91 = (float)(((val4!=val148)!=1));
float cast92 = (float)(((val5!=val148)!=1));
float cast93 = (float)(((val6!=val148)!=1));
float cast94 = (float)(((val7!=val148)!=1));
float cast95 = (float)(((val8!=val148)!=1));
float cast96 = (float)(((val9!=val148)!=1));
float cast97 = (float)(((val10!=val148)!=1));
float cast98 = (float)(((val11!=val148)!=1));
float cast99 = (float)(((val12!=val148)!=1));
float cast100 = (float)(((val13!=val148)!=1));
float cast101 = (float)(((val14!=val148)!=1));
float cast102 = (float)(((val15!=val148)!=1));
float cast103 = (float)(((val16!=val148)!=1));
float cast104 = (float)(((val17!=val148)!=1));
float cast105 = (float)(((val18!=val148)!=1));
float cast106 = (float)(((val19!=val148)!=1));
float cast107 = (float)(((val20!=val148)!=1));
float cast108 = (float)(((val21!=val148)!=1));
float cast109 = (float)(((val22!=val148)!=1));
float cast110 = (float)(((val23!=val148)!=1));
float cast111 = (float)(((val24!=val148)!=1));
float cast112 = (float)(((val25!=val148)!=1));
float cast113 = (float)(((val26!=val148)!=1));
float cast114 = (float)(((val27!=val148)!=1));
float cast115 = (float)(((val28!=val148)!=1));
data0[alu2+52] = ((cast87*val29)+(cast88*val33)+(cast89*val37)+(cast90*val41)+(cast91*val45)+(cast92*val49)+(cast93*val53)+(cast94*val57)+(cast95*val61)+(cast96*val65)+(cast97*val69)+(cast98*val73)+(cast99*val77)+(cast100*val81)+(cast101*val85)+(cast102*val89)+(cast103*val93)+(cast104*val97)+(cast105*val101)+(cast106*val105)+(cast107*val109)+(cast108*val113)+(cast109*val117)+(cast110*val121)+(cast111*val125)+(cast112*val129)+(cast113*val133)+(cast114*val137)+(cast115*val141));
data0[alu2+104] = ((cast87*val30)+(cast88*val34)+(cast89*val38)+(cast90*val42)+(cast91*val46)+(cast92*val50)+(cast93*val54)+(cast94*val58)+(cast95*val62)+(cast96*val66)+(cast97*val70)+(cast98*val74)+(cast99*val78)+(cast100*val82)+(cast101*val86)+(cast102*val90)+(cast103*val94)+(cast104*val98)+(cast105*val102)+(cast106*val106)+(cast107*val110)+(cast108*val114)+(cast109*val118)+(cast110*val122)+(cast111*val126)+(cast112*val130)+(cast113*val134)+(cast114*val138)+(cast115*val142));
data0[alu2+156] = ((cast87*val31)+(cast88*val35)+(cast89*val39)+(cast90*val43)+(cast91*val47)+(cast92*val51)+(cast93*val55)+(cast94*val59)+(cast95*val63)+(cast96*val67)+(cast97*val71)+(cast98*val75)+(cast99*val79)+(cast100*val83)+(cast101*val87)+(cast102*val91)+(cast103*val95)+(cast104*val99)+(cast105*val103)+(cast106*val107)+(cast107*val111)+(cast108*val115)+(cast109*val119)+(cast110*val123)+(cast111*val127)+(cast112*val131)+(cast113*val135)+(cast114*val139)+(cast115*val143));
data0[alu2] = ((cast87*val144)+(cast88*val32)+(cast89*val36)+(cast90*val40)+(cast91*val44)+(cast92*val48)+(cast93*val52)+(cast94*val56)+(cast95*val60)+(cast96*val64)+(cast97*val68)+(cast98*val72)+(cast99*val76)+(cast100*val80)+(cast101*val84)+(cast102*val88)+(cast103*val92)+(cast104*val96)+(cast105*val100)+(cast106*val104)+(cast107*val108)+(cast108*val112)+(cast109*val116)+(cast110*val120)+(cast111*val124)+(cast112*val128)+(cast113*val132)+(cast114*val136)+(cast115*val140));
}
}
}
}"""
entry = """typedef union { struct { void *pv; unsigned int len; } buf; struct { int fd; unsigned int offset; } dma; } remote_arg;
void* HAP_mmap(void *addr, int len, int prot, int flags, int fd, long offset);
int HAP_munmap(void *addr, int len);
int HAP_mmap_get(int fd, void **vaddr, void **paddr);
int HAP_mmap_put(int fd);
unsigned long long HAP_perf_get_time_us(void);
int entry(unsigned long long handle, unsigned int sc, remote_arg* pra) {
if ((sc>>24) != 2) return 0;
unsigned long long start = HAP_perf_get_time_us();
for (int i = 0; i < 50; i++) {
void* buf = HAP_mmap(0, 1, 3, 0, pra[2].dma.fd, 0);
HAP_munmap(buf, 1);
}
*(unsigned long long *)(pra[1].buf.pv) = HAP_perf_get_time_us() - start;
return 0; }
"""
if __name__ == "__main__":
dev = DSPDevice()
bufs = [dev.allocator.alloc(0x60000) for _ in range(4)]
only_entry = dev.compiler.compile(entry)
app1 = dev.runtime("test", only_entry)
x = app1(*bufs)
entry_n_unsued_code = dev.compiler.compile(kernel + "\n" + entry)
app2 = dev.runtime("test", entry_n_unsued_code)
x = app2(*bufs)

279
extra/dsp/invoke_bug_2.py Normal file
View File

@ -0,0 +1,279 @@
from tinygrad.runtime.ops_dsp import DSPDevice
kernel = """__attribute__((noinline)) void r_64_4_4_64_4_4_4(float* restrict __attribute__((align_value(128))) data0, const float* restrict __attribute__((align_value(128))) data1, const float* restrict __attribute__((align_value(128))) data2, const float* restrict __attribute__((align_value(128))) data3) {
for (int ridx0 = 0; ridx0 < 64; ridx0++) {
int alu0 = (ridx0*4096);
for (int ridx1 = 0; ridx1 < 4; ridx1++) {
int alu1 = (ridx1*64);
for (int ridx2 = 0; ridx2 < 4; ridx2++) {
int alu2 = (ridx2*4);
int alu3 = ((ridx0*1024)+alu1+alu2);
int alu4 = (alu1+alu2);
float val0 = data3[alu4+1];
float val1 = data3[alu4+2];
float val2 = data3[alu4+3];
float val3 = data3[alu4+16];
float val4 = data3[alu4+17];
float val5 = data3[alu4+18];
float val6 = data3[alu4+19];
float val7 = data3[alu4+32];
float val8 = data3[alu4+33];
float val9 = data3[alu4+34];
float val10 = data3[alu4+35];
float val11 = data3[alu4+48];
float val12 = data3[alu4+49];
float val13 = data3[alu4+50];
float val14 = data3[alu4+51];
float val15 = data3[alu4];
float acc0 = 0.0f;
float acc1 = 0.0f;
float acc2 = 0.0f;
float acc3 = 0.0f;
float acc4 = 0.0f;
float acc5 = 0.0f;
float acc6 = 0.0f;
float acc7 = 0.0f;
float acc8 = 0.0f;
float acc9 = 0.0f;
float acc10 = 0.0f;
float acc11 = 0.0f;
float acc12 = 0.0f;
float acc13 = 0.0f;
float acc14 = 0.0f;
float acc15 = 0.0f;
float acc16 = 0.0f;
float acc17 = 0.0f;
float acc18 = 0.0f;
float acc19 = 0.0f;
float acc20 = 0.0f;
float acc21 = 0.0f;
float acc22 = 0.0f;
float acc23 = 0.0f;
float acc24 = 0.0f;
float acc25 = 0.0f;
float acc26 = 0.0f;
float acc27 = 0.0f;
float acc28 = 0.0f;
float acc29 = 0.0f;
float acc30 = 0.0f;
float acc31 = 0.0f;
float acc32 = 0.0f;
float acc33 = 0.0f;
float acc34 = 0.0f;
float acc35 = 0.0f;
float acc36 = 0.0f;
float acc37 = 0.0f;
float acc38 = 0.0f;
float acc39 = 0.0f;
float acc40 = 0.0f;
float acc41 = 0.0f;
float acc42 = 0.0f;
float acc43 = 0.0f;
float acc44 = 0.0f;
float acc45 = 0.0f;
float acc46 = 0.0f;
float acc47 = 0.0f;
float acc48 = 0.0f;
float acc49 = 0.0f;
float acc50 = 0.0f;
float acc51 = 0.0f;
float acc52 = 0.0f;
float acc53 = 0.0f;
float acc54 = 0.0f;
float acc55 = 0.0f;
float acc56 = 0.0f;
float acc57 = 0.0f;
float acc58 = 0.0f;
float acc59 = 0.0f;
float acc60 = 0.0f;
float acc61 = 0.0f;
float acc62 = 0.0f;
float acc63 = 0.0f;
for (int ridx3 = 0; ridx3 < 64; ridx3++) {
int alu5 = (alu0+(ridx2*256)+ridx3);
float val16 = data2[alu5+64];
float val17 = data2[alu5+128];
float val18 = data2[alu5+192];
float val19 = data2[alu5+1024];
float val20 = data2[alu5+1088];
float val21 = data2[alu5+1152];
float val22 = data2[alu5+1216];
float val23 = data2[alu5+2048];
float val24 = data2[alu5+2112];
float val25 = data2[alu5+2176];
float val26 = data2[alu5+2240];
float val27 = data2[alu5+3072];
float val28 = data2[alu5+3136];
float val29 = data2[alu5+3200];
float val30 = data2[alu5+3264];
float val31 = data2[alu5];
int alu6 = (alu0+(ridx1*256)+ridx3);
float val32 = data1[alu6+64];
float val33 = data1[alu6+128];
float val34 = data1[alu6+192];
float val35 = data1[alu6+1024];
float val36 = data1[alu6+1088];
float val37 = data1[alu6+1152];
float val38 = data1[alu6+1216];
float val39 = data1[alu6+2048];
float val40 = data1[alu6+2112];
float val41 = data1[alu6+2176];
float val42 = data1[alu6+2240];
float val43 = data1[alu6+3072];
float val44 = data1[alu6+3136];
float val45 = data1[alu6+3200];
float val46 = data1[alu6+3264];
float val47 = data1[alu6];
acc0 = (acc0+(val47*val31));
acc1 = (acc1+(val35*val19));
acc2 = (acc2+(val39*val23));
acc3 = (acc3+(val43*val27));
acc4 = (acc4+(val32*val31));
acc5 = (acc5+(val36*val19));
acc6 = (acc6+(val40*val23));
acc7 = (acc7+(val44*val27));
acc8 = (acc8+(val33*val31));
acc9 = (acc9+(val37*val19));
acc10 = (acc10+(val41*val23));
acc11 = (acc11+(val45*val27));
acc12 = (acc12+(val34*val31));
acc13 = (acc13+(val38*val19));
acc14 = (acc14+(val42*val23));
acc15 = (acc15+(val46*val27));
acc16 = (acc16+(val47*val16));
acc17 = (acc17+(val35*val20));
acc18 = (acc18+(val39*val24));
acc19 = (acc19+(val43*val28));
acc20 = (acc20+(val32*val16));
acc21 = (acc21+(val36*val20));
acc22 = (acc22+(val40*val24));
acc23 = (acc23+(val44*val28));
acc24 = (acc24+(val33*val16));
acc25 = (acc25+(val37*val20));
acc26 = (acc26+(val41*val24));
acc27 = (acc27+(val45*val28));
acc28 = (acc28+(val34*val16));
acc29 = (acc29+(val38*val20));
acc30 = (acc30+(val42*val24));
acc31 = (acc31+(val46*val28));
acc32 = (acc32+(val47*val17));
acc33 = (acc33+(val35*val21));
acc34 = (acc34+(val39*val25));
acc35 = (acc35+(val43*val29));
acc36 = (acc36+(val32*val17));
acc37 = (acc37+(val36*val21));
acc38 = (acc38+(val40*val25));
acc39 = (acc39+(val44*val29));
acc40 = (acc40+(val33*val17));
acc41 = (acc41+(val37*val21));
acc42 = (acc42+(val41*val25));
acc43 = (acc43+(val45*val29));
acc44 = (acc44+(val34*val17));
acc45 = (acc45+(val38*val21));
acc46 = (acc46+(val42*val25));
acc47 = (acc47+(val46*val29));
acc48 = (acc48+(val47*val18));
acc49 = (acc49+(val35*val22));
acc50 = (acc50+(val39*val26));
acc51 = (acc51+(val43*val30));
acc52 = (acc52+(val32*val18));
acc53 = (acc53+(val36*val22));
acc54 = (acc54+(val40*val26));
acc55 = (acc55+(val44*val30));
acc56 = (acc56+(val33*val18));
acc57 = (acc57+(val37*val22));
acc58 = (acc58+(val41*val26));
acc59 = (acc59+(val45*val30));
acc60 = (acc60+(val34*val18));
acc61 = (acc61+(val38*val22));
acc62 = (acc62+(val42*val26));
acc63 = (acc63+(val46*val30));
}
data0[alu3] = ((acc0*0.125f)+val15);
data0[alu3+256] = ((acc1*0.125f)+val15);
data0[alu3+512] = ((acc2*0.125f)+val15);
data0[alu3+768] = ((acc3*0.125f)+val15);
data0[alu3+16] = ((acc4*0.125f)+val3);
data0[alu3+272] = ((acc5*0.125f)+val3);
data0[alu3+528] = ((acc6*0.125f)+val3);
data0[alu3+784] = ((acc7*0.125f)+val3);
data0[alu3+32] = ((acc8*0.125f)+val7);
data0[alu3+288] = ((acc9*0.125f)+val7);
data0[alu3+544] = ((acc10*0.125f)+val7);
data0[alu3+800] = ((acc11*0.125f)+val7);
data0[alu3+48] = ((acc12*0.125f)+val11);
data0[alu3+304] = ((acc13*0.125f)+val11);
data0[alu3+560] = ((acc14*0.125f)+val11);
data0[alu3+816] = ((acc15*0.125f)+val11);
data0[alu3+1] = ((acc16*0.125f)+val0);
data0[alu3+257] = ((acc17*0.125f)+val0);
data0[alu3+513] = ((acc18*0.125f)+val0);
data0[alu3+769] = ((acc19*0.125f)+val0);
data0[alu3+17] = ((acc20*0.125f)+val4);
data0[alu3+273] = ((acc21*0.125f)+val4);
data0[alu3+529] = ((acc22*0.125f)+val4);
data0[alu3+785] = ((acc23*0.125f)+val4);
data0[alu3+33] = ((acc24*0.125f)+val8);
data0[alu3+289] = ((acc25*0.125f)+val8);
data0[alu3+545] = ((acc26*0.125f)+val8);
data0[alu3+801] = ((acc27*0.125f)+val8);
data0[alu3+49] = ((acc28*0.125f)+val12);
data0[alu3+305] = ((acc29*0.125f)+val12);
data0[alu3+561] = ((acc30*0.125f)+val12);
data0[alu3+817] = ((acc31*0.125f)+val12);
data0[alu3+2] = ((acc32*0.125f)+val1);
data0[alu3+258] = ((acc33*0.125f)+val1);
data0[alu3+514] = ((acc34*0.125f)+val1);
data0[alu3+770] = ((acc35*0.125f)+val1);
data0[alu3+18] = ((acc36*0.125f)+val5);
data0[alu3+274] = ((acc37*0.125f)+val5);
data0[alu3+530] = ((acc38*0.125f)+val5);
data0[alu3+786] = ((acc39*0.125f)+val5);
data0[alu3+34] = ((acc40*0.125f)+val9);
data0[alu3+290] = ((acc41*0.125f)+val9);
data0[alu3+546] = ((acc42*0.125f)+val9);
data0[alu3+802] = ((acc43*0.125f)+val9);
data0[alu3+50] = ((acc44*0.125f)+val13);
data0[alu3+306] = ((acc45*0.125f)+val13);
data0[alu3+562] = ((acc46*0.125f)+val13);
data0[alu3+818] = ((acc47*0.125f)+val13);
data0[alu3+3] = ((acc48*0.125f)+val2);
data0[alu3+259] = ((acc49*0.125f)+val2);
data0[alu3+515] = ((acc50*0.125f)+val2);
data0[alu3+771] = ((acc51*0.125f)+val2);
data0[alu3+19] = ((acc52*0.125f)+val6);
data0[alu3+275] = ((acc53*0.125f)+val6);
data0[alu3+531] = ((acc54*0.125f)+val6);
data0[alu3+787] = ((acc55*0.125f)+val6);
data0[alu3+35] = ((acc56*0.125f)+val10);
data0[alu3+291] = ((acc57*0.125f)+val10);
data0[alu3+547] = ((acc58*0.125f)+val10);
data0[alu3+803] = ((acc59*0.125f)+val10);
data0[alu3+51] = ((acc60*0.125f)+val14);
data0[alu3+307] = ((acc61*0.125f)+val14);
data0[alu3+563] = ((acc62*0.125f)+val14);
data0[alu3+819] = ((acc63*0.125f)+val14);
}
}
}
}
"""
entry = """unsigned long long HAP_perf_get_time_us(void);
int entry(unsigned long long handle, unsigned int sc, void* pra) {
return HAP_perf_get_time_us() == 1 ? 4 : 0;
}
"""
if __name__ == "__main__":
dev = DSPDevice()
bufs = [dev.allocator.alloc(0x60000) for _ in range(4)]
only_entry = dev.compiler.compile(entry)
app1 = dev.runtime("test", only_entry)
x = app1(*bufs)
entry_n_unsued_code = dev.compiler.compile(kernel + "\n" + entry)
app2 = dev.runtime("test", entry_n_unsued_code)
x = app2(*bufs)

151
extra/dsp/run.py Executable file
View File

@ -0,0 +1,151 @@
#!/usr/bin/env python3
import os, ctypes, ctypes.util, struct, platform, time
from tinygrad.runtime.autogen import libc, qcom_dsp
def to_mv(ptr, sz) -> memoryview: return memoryview(ctypes.cast(ptr, ctypes.POINTER(ctypes.c_uint8 * sz)).contents).cast("B")
from hexdump import hexdump
def get_struct(argp, stype):
return ctypes.cast(ctypes.c_void_p(argp), ctypes.POINTER(stype)).contents
def format_struct(s):
sdats = []
for field in s._fields_:
dat = getattr(s, field[0])
if isinstance(dat, int): sdats.append(f"{field[0]}:0x{dat:X}")
elif hasattr(dat, "_fields_"): sdats.append((field[0], format_struct(dat)))
elif field[0] == "PADDING_0": pass
else: sdats.append(f"{field[0]}:{dat}")
return sdats
@ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulong, ctypes.c_void_p)
def ioctl(fd, request, argp):
fn = os.readlink(f"/proc/self/fd/{fd}")
idir, size, itype, nr = (request>>30), (request>>16)&0x3FFF, (request>>8)&0xFF, request&0xFF
if fn == "/dev/adsprpc-smd":
if nr == 1:
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke)
method = (st.sc>>24) & 0xFF
in_args = (st.sc>>16) & 0xFF
out_args = (st.sc>>8) & 0xFF
if out_args:
for arg in range(in_args, in_args+out_args):
ctypes.memset(st.pra[arg].buf.pv, 0, st.pra[arg].buf.len)
# print("enter", libc.gettid())
ret = libc.syscall(0x1d, ctypes.c_int(fd), ctypes.c_ulong(request), ctypes.c_void_p(argp))
# print("done", libc.gettid())
if fn == "/dev/ion":
if nr == 0:
st = get_struct(argp, qcom_dsp.struct_ion_allocation_data)
print(ret, "ION_IOC_ALLOC", format_struct(st))
elif nr == 1:
st = get_struct(argp, qcom_dsp.struct_ion_handle_data)
print(ret, "ION_IOC_FREE", format_struct(st))
elif nr == 2:
st = get_struct(argp, qcom_dsp.struct_ion_fd_data)
print(ret, "ION_IOC_MAP", format_struct(st))
elif fn == "/dev/adsprpc-smd":
assert chr(itype) == 'R'
if nr == 8:
st = ctypes.c_uint32.from_address(argp)
print(ret, "FASTRPC_IOCTL_GETINFO", st.value)
elif nr == 2:
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_mmap)
print(ret, "FASTRPC_IOCTL_MMAP", format_struct(st))
elif nr == 1:
# https://research.checkpoint.com/2021/pwn2own-qualcomm-dsp/
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke)
print(ret, "FASTRPC_IOCTL_INVOKE", format_struct(st))
# 0xFF000000 = Method index and attribute (the highest byte)
# 0x00FF0000 = Number of input arguments
# 0x0000FF00 = Number of output arguments
# 0x000000F0 = Number of input handles
# 0x0000000F = Number of output handles
method = (st.sc>>24) & 0xFF
in_args = (st.sc>>16) & 0xFF
out_args = (st.sc>>8) & 0xFF
in_h = (st.sc>>4) & 0xF
out_h = (st.sc>>0) & 0xF
print(f"\tm:{method} ia:{in_args} oa:{out_args} ih:{in_h} oh:{out_h}")
if in_args or out_args:
for arg in range(in_args+out_args):
print(arg, format_struct(st.pra[arg]))
if st.pra[arg].buf.pv is not None:
ww = to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)
hexdump(to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)[:0x40])
elif nr == 6:
print(ret, "FASTRPC_IOCTL_INIT", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_init)))
print(os.readlink(f"/proc/self/fd/{ini.filefd}"))
# print(bytearray(to_mv(ini.file, ini.filelen)))
elif nr == 7:
print(ret, "FASTRPC_IOCTL_INVOKE_ATTRS", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke_attrs)))
elif nr == 12: print(ret, "FASTRPC_IOCTL_CONTROL", format_struct(get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_control)))
else:
print(f"{ret} UNPARSED {nr}")
else:
print("ioctl", f"{idir=} {size=} {itype=} {nr=} {fd=} {ret=}", fn)
return ret
def install_hook(c_function, python_function):
orig_func = (ctypes.c_char*4096)()
python_function_addr = ctypes.cast(ctypes.byref(python_function), ctypes.POINTER(ctypes.c_ulong)).contents.value
# AARCH64 trampoline to ioctl
# 0x0000000000000000: 70 00 00 10 adr x16, #0xc
# 0x0000000000000004: 10 02 40 F9 ldr x16, [x16]
# 0x0000000000000008: 00 02 1F D6 br x16
tramp = b"\x70\x00\x00\x10\x10\x02\x40\xf9\x00\x02\x1f\xd6"
tramp += struct.pack("Q", python_function_addr)
# get real ioctl address
ioctl_address = ctypes.cast(ctypes.byref(c_function), ctypes.POINTER(ctypes.c_ulong))
# hook ioctl
ret = libc.mprotect(ctypes.c_ulong((ioctl_address.contents.value//0x1000)*0x1000), 0x2000, 7)
assert ret == 0
ret = libc.mprotect(ctypes.c_ulong((ctypes.addressof(orig_func)//0x1000)*0x1000), 0x3000, 7)
assert ret == 0
libc.memcpy(orig_func, ioctl_address.contents, 0x1000)
libc.memcpy(ioctl_address.contents, ctypes.create_string_buffer(tramp), len(tramp))
return orig_func
libc = ctypes.CDLL(ctypes.util.find_library("libc"))
install_hook(libc.ioctl, ioctl)
adsp = ctypes.CDLL(ctypes.util.find_library("adsprpc"))
def send_rpc_invoke(filename):
pass
if __name__ == "__main__":
print("calculator_open")
# /dsp/cdsp/fastrpc_shell_3
handle = ctypes.c_int64(-1)
z = adsp.remote_handle64_open(ctypes.create_string_buffer(b"file:///libcalculator_skel.so?calculator_skel_handle_invoke&_modver=1.0&_dom=cdsp"),
ctypes.byref(handle))
print("handle", z, hex(handle.value))
assert handle.value != -1
test = (ctypes.c_int32 * 100)()
for i in range(100): test[i] = i
print("calculator_sum")
pra = (qcom_dsp.union_remote_arg64 * 3)()
#arg_0 = ctypes.c_int32(100)
arg_0 = ctypes.c_int32(100)
arg_2 = ctypes.c_int64(-1)
pra[0].buf.pv = ctypes.addressof(arg_0)
pra[0].buf.len = 4
pra[1].buf.pv = ctypes.addressof(test)
pra[1].buf.len = 0x190
pra[2].buf.pv = ctypes.addressof(arg_2)
pra[2].buf.len = 8
adsp.remote_handle64_invoke(handle, (2<<24) | (2<<16) | (1<<8), pra)
print(arg_2.value)
print("done")
print("closing")
x = adsp.remote_handle64_close(handle)
print(x)
print("dun")
os._exit(0)

312
extra/dsp/run_3.py Executable file
View File

@ -0,0 +1,312 @@
#!/usr/bin/env python3
import os, ctypes, ctypes.util, struct, platform, pathlib, contextlib, mmap, array
from threading import Thread
from tinygrad.runtime.autogen import qcom_dsp
from tinygrad.helpers import round_up, mv_address, to_mv
from hexdump import hexdump
def get_struct(argp, stype):
return ctypes.cast(ctypes.c_void_p(argp), ctypes.POINTER(stype)).contents
def format_struct(s):
sdats = []
for field in s._fields_:
dat = getattr(s, field[0])
if isinstance(dat, int): sdats.append(f"{field[0]}:0x{dat:X}")
elif hasattr(dat, "_fields_"): sdats.append((field[0], format_struct(dat)))
elif field[0] == "PADDING_0": pass
else: sdats.append(f"{field[0]}:{dat}")
return sdats
@ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulong, ctypes.c_void_p)
def ioctl(fd, request, argp):
fn = os.readlink(f"/proc/self/fd/{fd}")
idir, size, itype, nr = (request>>30), (request>>16)&0x3FFF, (request>>8)&0xFF, request&0xFF
# print("enter", libc.gettid())
ret = libc.syscall(0x1d, ctypes.c_int(fd), ctypes.c_ulong(request), ctypes.c_void_p(argp))
# print("done", libc.gettid())
if fn == "/dev/ion":
if nr == 0:
st = get_struct(argp, qcom_dsp.struct_ion_allocation_data)
print(ret, "ION_IOC_ALLOC", format_struct(st))
elif nr == 1:
st = get_struct(argp, qcom_dsp.struct_ion_handle_data)
print(ret, "ION_IOC_FREE", format_struct(st))
elif nr == 2:
st = get_struct(argp, qcom_dsp.struct_ion_fd_data)
print(ret, "ION_IOC_MAP", format_struct(st))
elif fn == "/dev/adsprpc-smd":
assert chr(itype) == 'R'
if nr == 8:
st = ctypes.c_uint32.from_address(argp)
print(ret, "FASTRPC_IOCTL_GETINFO", st.value)
elif nr == 2:
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_mmap)
print(ret, "FASTRPC_IOCTL_MMAP", format_struct(st))
elif nr == 1:
# https://research.checkpoint.com/2021/pwn2own-qualcomm-dsp/
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke)
print(ret, "FASTRPC_IOCTL_INVOKE", format_struct(st))
# 0xFF000000 = Method index and attribute (the highest byte)
# 0x00FF0000 = Number of input arguments
# 0x0000FF00 = Number of output arguments
# 0x000000F0 = Number of input handles
# 0x0000000F = Number of output handles
method = (st.sc>>24) & 0xFF
in_args = (st.sc>>16) & 0xFF
out_args = (st.sc>>8) & 0xFF
in_h = (st.sc>>4) & 0xF
out_h = (st.sc>>0) & 0xF
print(f"\tm:{method} ia:{in_args} oa:{out_args} ih:{in_h} oh:{out_h}")
if in_args or out_args:
for arg in range(in_args+out_args):
print(arg, format_struct(st.pra[arg]))
# print(arg, f"arg (0x{st.pra[arg].buf.pv:X} len=0x{st.pra[arg].buf.len:X})")
# print("input" if arg < in_args else "output", f"arg (0x{st.pra[arg].buf.pv:X} len=0x{st.pra[arg].buf.len:X})")
if st.pra[arg].buf.pv is not None:
# if st.pra[arg].buf.len == 0x258:
# print(bytearray(to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)))
if st.pra[arg].buf.len == 0x68:
print(bytearray(to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)))
cut = 0x2000 if st.pra[arg].buf.len == 0x2000 or st.pra[arg].buf.len == 0x258 else 0x100
ww = to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)
hexdump(to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)[:cut])
# if st.pra[arg].buf.len == 0x1000 and ww[0x30] == 0x6e:
# z = ww.cast('Q')[1] + 0x7F00000000
# print("DOO")
# hexdump(to_mv(z, 0x200))
#print(format_struct(st.pra)))
elif nr == 6:
print(ret, "FASTRPC_IOCTL_INIT", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_init)))
print(os.readlink(f"/proc/self/fd/{ini.filefd}"))
# print(bytearray(to_mv(ini.file, ini.filelen)))
elif nr == 7:
print(ret, "FASTRPC_IOCTL_INVOKE_ATTRS", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke_attrs)))
elif nr == 12: print(ret, "FASTRPC_IOCTL_CONTROL", format_struct(get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_control)))
else:
print(f"{ret} UNPARSED {nr}")
else:
print("ioctl", f"{idir=} {size=} {itype=} {nr=} {fd=} {ret=}", fn)
return ret
def install_hook(c_function, python_function):
orig_func = (ctypes.c_char*4096)()
python_function_addr = ctypes.cast(ctypes.byref(python_function), ctypes.POINTER(ctypes.c_ulong)).contents.value
# AARCH64 trampoline to ioctl
# 0x0000000000000000: 70 00 00 10 adr x16, #0xc
# 0x0000000000000004: 10 02 40 F9 ldr x16, [x16]
# 0x0000000000000008: 00 02 1F D6 br x16
tramp = b"\x70\x00\x00\x10\x10\x02\x40\xf9\x00\x02\x1f\xd6"
tramp += struct.pack("Q", python_function_addr)
# get real ioctl address
ioctl_address = ctypes.cast(ctypes.byref(c_function), ctypes.POINTER(ctypes.c_ulong))
# hook ioctl
ret = libc.mprotect(ctypes.c_ulong((ioctl_address.contents.value//0x1000)*0x1000), 0x2000, 7)
assert ret == 0
ret = libc.mprotect(ctypes.c_ulong((ctypes.addressof(orig_func)//0x1000)*0x1000), 0x3000, 7)
assert ret == 0
libc.memcpy(orig_func, ioctl_address.contents, 0x1000)
libc.memcpy(ioctl_address.contents, ctypes.create_string_buffer(tramp), len(tramp))
return orig_func
libc = ctypes.CDLL(ctypes.util.find_library("libc"))
install_hook(libc.ioctl, ioctl)
from tinygrad.runtime.autogen import libc
# adsp = ctypes.CDLL(ctypes.util.find_library("adsprpc"))
# print(adsp)
def rpc_invoke(rpcfd, handle, method, ins=None, outs=None):
if ins or outs:
ins = ins or list()
outs = outs or list()
pra = (qcom_dsp.union_remote_arg * (len(ins) + len(outs)))()
for i,mv in enumerate(ins + outs):
if isinstance(mv, memoryview):
pra[i].buf.pv = mv_address(mv) if mv.nbytes > 0 else 0
pra[i].buf.len = mv.nbytes
else: assert False, "not supported"
# pra = (qcom_dsp.union_remote_arg * (len(ins) + len(outs))).from_address(ctypes.addressof(pra))
else:
pra = None
ins = ins or list()
outs = outs or list()
sc = (method << 24) | (len(ins) << 16) | (len(outs) << 8)
return qcom_dsp.FASTRPC_IOCTL_INVOKE(rpcfd, handle=handle, sc=sc, pra=pra)
def listner_worker():
context = 0
handle = 0xffffffff
msg_send = memoryview(bytearray(0x10)).cast('I')
msg_recv = memoryview(bytearray(0x10)).cast('I')
out_buf = memoryview(bytearray(0x1000)).cast('I')
in_buf = memoryview(bytearray(0x1000)).cast('I')
prev_res = 0xffffffff
out_buf_size = 0
req_args = (qcom_dsp.union_remote_arg * 4)()
req_args[0].buf = qcom_dsp.struct_remote_buf(pv=mv_address(msg_send), len=0x10)
req_args[1].buf = qcom_dsp.struct_remote_buf(pv=mv_address(out_buf), len=0x1000)
req_args[2].buf = qcom_dsp.struct_remote_buf(pv=mv_address(msg_recv), len=0x10)
req_args[3].buf = qcom_dsp.struct_remote_buf(pv=mv_address(in_buf), len=0x1000)
while True:
msg_send[0] = context
msg_send[1] = prev_res
msg_send[2] = out_buf_size
msg_send[3] = 0x1000
req_args[1].buf.len = out_buf_size
qcom_dsp.FASTRPC_IOCTL_INVOKE(rpcfd, handle=0x3, sc=0x04020200, pra=req_args) # listener
context = msg_recv[0]
handle = msg_recv[1]
sc = msg_recv[2]
inbufs = (sc >> 16) & 0xff
outbufs = (sc >> 8) & 0xff
in_args, out_args = [], []
ptr = mv_address(in_buf)
for i in range(inbufs):
sz = to_mv(ptr, 4).cast('I')[0]
obj_ptr = round_up(ptr + 4, 8)
in_args.append(to_mv(obj_ptr, sz))
ptr = obj_ptr + sz
ctypes.memset(mv_address(out_buf), 0, 0x1000)
ptr_out = mv_address(out_buf)
for i in range(outbufs):
sz = to_mv(ptr, 4).cast('I')[0]
ptr += 4
to_mv(ptr_out, 4).cast('I')[0] = sz
obj_ptr = round_up(ptr_out + 4, 8)
out_args.append(to_mv(obj_ptr, sz))
ptr_out = obj_ptr + sz
out_buf_size = ptr_out - mv_address(out_buf)
if sc == 0x20200: # greating?
prev_res = 0
elif sc == 0x13050100: # open
# for a in in_args: hexdump(a)
try:
fd = os.open(in_args[3].tobytes()[:-1].decode(), os.O_RDONLY)
out_args[0].cast('I')[0] = fd
prev_res = 0
except: prev_res = 2
elif sc == 0x9010000: # seek
res = os.lseek(in_args[0].cast('I')[0], in_args[0].cast('I')[1], in_args[0].cast('I')[2])
prev_res = 0 if res >= 0 else res
elif sc == 0x4010200: # read
buf = os.read(in_args[0].cast('I')[0], in_args[0].cast('I')[1])
out_args[1][:len(buf)] = buf
out_args[0].cast('I')[0] = len(buf)
out_args[0].cast('I')[1] = int(len(buf) == 0)
prev_res = 0
elif sc == 0x3010000: # close
os.close(in_args[0].cast('I')[0])
prev_res = 0
elif sc == 0x1f020100: # stat
# try:
stat = os.stat(in_args[1].tobytes()[:-1].decode())
out_stat = out_args[0].cast('Q')
out_stat[1] = stat.st_dev
out_stat[2] = stat.st_ino
out_stat[3] = stat.st_mode | (stat.st_nlink << 32)
out_stat[4] = stat.st_rdev
out_stat[5] = stat.st_size
# print(stat, stat.st_rdev)
# assert False
prev_res = 0
# except: prev_res = 2
elif sc == 0x2010100:
heapid = in_args[0].cast('I')[0]
lflags = in_args[0].cast('I')[1]
rflags = in_args[0].cast('I')[2]
assert rflags == 0x1000
# print(in_args[0])
# print("WOOW", in_args[0].cast('Q')[2])
# print("WOOW2", in_args[0].cast('Q')[2])
# print("WOOW3", in_args[0].cast('Q')[3])
# print("WOOW3", in_args[0].cast('Q')[3])
vin = in_args[0].cast('Q')[2]
sz = in_args[0].cast('Q')[3]
# vin = to_mv(in_args[0].cast('Q')[2], 8).cast('Q')[0]
# sz = to_mv(in_args[0].cast('Q')[3], 8).cast('Q')[0]
st = qcom_dsp.FASTRPC_IOCTL_MMAP(rpcfd, fd=-1, flags=rflags, vaddrin=0, size=sz)
out_args[0].cast('Q')[0] = 0
out_args[0].cast('Q')[1] = st.vaddrout
prev_res = 0
else: raise RuntimeError(f"Unknown {sc=:X}")
if __name__ == "__main__":
ionfd = os.open('/dev/ion', os.O_RDONLY)
rpcfd = os.open('/dev/adsprpc-smd', os.O_RDONLY | os.O_NONBLOCK)
with contextlib.suppress(RuntimeError, OSError): qcom_dsp.ION_IOC_FREE(ionfd, handle=0)
info = qcom_dsp.FASTRPC_IOCTL_GETINFO(rpcfd, 3)
# x = qcom_dsp.FASTRPC_IOCTL_SETMODE(rpcfd, 0, __force_as_val=True)
# init shell?
fastrpc_shell = memoryview(bytearray(pathlib.Path('/vendor/dsp/cdsp/fastrpc_shell_3').read_bytes()))
shell_mem = qcom_dsp.ION_IOC_ALLOC(ionfd, len=round_up(fastrpc_shell.nbytes, 0x1000), align=0x1000, heap_id_mask=0x2000000, flags=0x1)
shell_mapped = qcom_dsp.ION_IOC_MAP(ionfd, handle=shell_mem.handle)
fastrpc_shell_addr = libc.mmap(0, shell_mem.len, mmap.PROT_READ|mmap.PROT_WRITE, mmap.MAP_SHARED, shell_mapped.fd, 0)
ctypes.memmove(fastrpc_shell_addr, mv_address(fastrpc_shell), fastrpc_shell.nbytes)
# ctypes.memset(fastrpc_shell_addr, 0x0, 0xd6000)
# print(hex(fastrpc_shell_addr))
ctrls = qcom_dsp.FASTRPC_IOCTL_CONTROL(rpcfd, req=0x3)
init = qcom_dsp.FASTRPC_IOCTL_INIT(rpcfd, flags=0x1, file=fastrpc_shell_addr, filelen=fastrpc_shell.nbytes, filefd=shell_mapped.fd)
print("init shell done", shell_mapped.fd)
# TODO: unmap here
# qcom_dsp.ION_IOC_FREE(ionfd, handle=shell_mem.handle)
rpc_invoke(rpcfd, handle=3, method=3)
thread = Thread(target=listner_worker)
thread.start()
a1 = memoryview(bytearray(b'\x52\x00\x00\x00\xFF\x00\x00\x00'))
a2 = memoryview(bytearray(b"file:///libcalculator_skel.so?calculator_skel_handle_invoke&_modver=1.0&_dom=cdsp\0"))
o1 = memoryview(bytearray(0x8))
o2 = memoryview(bytearray(0xff))
z = rpc_invoke(rpcfd, handle=0, method=0, ins=[a1, a2], outs=[o1, o2])
prg_handle = o1.cast('I')[0]
# test
test = (ctypes.c_int32 * 100)()
for i in range(100): test[i] = i
print("calculator_sum")
pra = (qcom_dsp.union_remote_arg * 3)()
#arg_0 = ctypes.c_int32(100)
arg_0 = ctypes.c_int32(100)
arg_2 = ctypes.c_int64(-1)
pra[0].buf.pv = ctypes.addressof(arg_0)
pra[0].buf.len = 4
pra[1].buf.pv = ctypes.addressof(test)
pra[1].buf.len = 0x190
pra[2].buf.pv = ctypes.addressof(arg_2)
pra[2].buf.len = 8
qcom_dsp.FASTRPC_IOCTL_INVOKE(rpcfd, handle=prg_handle, sc=(2<<24) | (2<<16) | (1<<8), pra=pra)
print(arg_2.value)
print("done")
os._exit(0)

View File

@ -3,6 +3,9 @@ from tinygrad.helpers import getenv
from tinygrad import dtypes, Tensor
dtype_in = dtypes.half if getenv("HALF") else dtypes.bfloat16 if getenv("BFLOAT16") else dtypes.float
acc_dtype = dtypes.half if getenv("ACC_HALF") else dtypes.bfloat16 if getenv("ACC_BFLOAT16") else None
if getenv("INT"):
dtype_in = dtypes.int8
acc_dtype = dtypes.int32
N = getenv("N", 4096)
M = getenv("M", N)
K = getenv("K", N)

View File

@ -435,6 +435,32 @@ static inline __attribute__((device)) bool operator==(hip_bfloat16 a, hip_bfloat
# NOTE: this makes hlb_cifar10 twice as fast, there may be more gains in tweaking these parameters
return f"__attribute__((amdgpu_flat_work_group_size(1, {requiredMaxThreadsPerBlock})))"
class DSPRenderer(ClangRenderer):
device = "DSP"
supports_float4 = False
buffer_suffix = " restrict __attribute__((align_value(128)))"
kernel_prefix = "__attribute__((noinline)) "
type_map = { **ClangRenderer().type_map, dtypes.uint64: "unsigned long long", dtypes.int64: "long long" }
code_for_op = {**ClangRenderer().code_for_op, UnaryOps.SIN: lambda x,dtype: f"__builtin_sin({x})",
UnaryOps.LOG2: lambda x,dtype: f"__builtin_log2l({x})" if dtype == dtypes.float64 else f"__builtin_log2f({x})",
UnaryOps.EXP2: lambda x,dtype: f"__builtin_exp2l({x})" if dtype == dtypes.float64 else f"__builtin_exp2f({x})"}
def render_kernel(self, function_name:str, kernel:List[str], bufs:List[Tuple[str,Tuple[DType,bool]]], uops:List[UOp], prefix=None) -> str:
ret = super().render_kernel(function_name, kernel, bufs, uops, prefix)
msrc = ['typedef union { struct { void *pv; unsigned int len; } buf; struct { int fd; unsigned int offset; } dma; } remote_arg;',
'void* HAP_mmap(void *addr, int len, int prot, int flags, int fd, long offset);', 'int HAP_munmap(void *addr, int len);',
'unsigned long long HAP_perf_get_time_us(void);',
'int entry(unsigned long long handle, unsigned int sc, remote_arg* pra) {']
msrc += ['if ((sc>>24) != 2) return 0;']
msrc += [f'int sz_or_val_{i} = ((int*)pra[0].buf.pv)[{i}];' for i,b in enumerate(bufs)]
msrc += [f'void *buf_{i} = HAP_mmap(0, sz_or_val_{i}, 3, 0, pra[{i+2}].dma.fd, 0);' for i,b in enumerate(bufs) if isinstance(b[1][0], PtrDType)]
msrc += ["unsigned long long start = HAP_perf_get_time_us();"]
msrc += [f"{function_name}({', '.join([(f'buf_{i}' if isinstance(b[1][0], PtrDType) else f'sz_or_val_{i}') for i,b in enumerate(bufs)])});"]
msrc += ["*(unsigned long long *)(pra[1].buf.pv) = HAP_perf_get_time_us() - start;"]
msrc += [f'HAP_munmap(buf_{i}, sz_or_val_{i});' for i,b in enumerate(bufs) if isinstance(b[1][0], PtrDType)]
msrc += ["return 0; }"]
return ret + '\n' + '\n'.join(msrc)
class NVRenderer(CUDARenderer): device = "NV"
class HIPRenderer(AMDRenderer): device = "HIP"
class QCOMRenderer(OpenCLRenderer): device = "QCOM"

File diff suppressed because it is too large Load Diff

174
tinygrad/runtime/ops_dsp.py Normal file
View File

@ -0,0 +1,174 @@
from __future__ import annotations
from typing import Tuple, Any
import ctypes, os, mmap, tempfile, pathlib, array, functools, threading, contextlib
from tinygrad.device import BufferOptions, Compiled, Allocator
from tinygrad.helpers import from_mv, getenv, DEBUG, round_up, mv_address, to_mv
from tinygrad.runtime.ops_clang import ClangCompiler
from tinygrad.renderer.cstyle import DSPRenderer
from tinygrad.runtime.autogen import libc, qcom_dsp
if getenv("IOCTL"): import extra.dsp.run # noqa: F401 # pylint: disable=unused-import
def rpc_sc(method=0, ins=0, outs=0, fd=0): return (method << 24) | (ins << 16) | (outs << 8)
def rpc_prep_args(ins=None, outs=None, in_fds=None):
ins, outs, in_fds = ins or list(), outs or list(), in_fds or list()
pra = (qcom_dsp.union_remote_arg * (len(ins) + len(outs) + len(in_fds)))()
fds = (ctypes.c_int32 * (len(ins) + len(outs) + len(in_fds)))(*([-1] * (len(ins) + len(outs))), *in_fds)
attrs = (ctypes.c_uint32 * (len(ins) + len(outs) + len(in_fds)))(*([0] * (len(ins) + len(outs))), *([1] * (len(in_fds))))
for i, mv in enumerate(ins + outs): pra[i].buf.pv, pra[i].buf.len = mv_address(mv) if mv.nbytes > 0 else 0, mv.nbytes
return pra, fds, attrs, (ins, outs)
class DSPProgram:
def __init__(self, device:DSPDevice, name:str, lib:bytes):
self.device, self.lib = device, lib
# TODO: Remove lib flush to FS.
with tempfile.NamedTemporaryFile(delete=False) as self.filepath:
self.filepath.write(lib)
self.filepath.flush()
if DEBUG >= 6: os.system(f"llvm-objdump -d {self.filepath.name}")
def __del__(self): os.remove(self.filepath.name)
def __call__(self, *bufs, vals:Tuple[int, ...]=(), wait=False):
pra, fds, attrs, _ = rpc_prep_args(ins=[var_vals_mv:=memoryview(bytearray((len(bufs) + len(vals)) * 4))],
outs=[timer:=memoryview(bytearray(8)).cast('Q')], in_fds=[b.share_info.fd for b in bufs])
var_vals_mv.cast('i')[:] = array.array('i', tuple(b.size for b in bufs) + vals)
self.device.exec_lib(self.filepath.name, (2<<24) | (1<<16) | (1<<8) | len(bufs), pra, fds, attrs)
return timer[0] / 1e6
class DSPBuffer:
def __init__(self, va_addr:int, size:int, share_info:Any): self.va_addr, self.size, self.share_info = va_addr, size, share_info
class DSPAllocator(Allocator):
def __init__(self, device:DSPDevice):
self.device = device
super().__init__()
def _alloc(self, size:int, options:BufferOptions):
b = qcom_dsp.ION_IOC_ALLOC(self.device.ion_fd, len=size, align=0x200, heap_id_mask=1<<qcom_dsp.ION_SYSTEM_HEAP_ID, flags=qcom_dsp.ION_FLAG_CACHED)
share_info = qcom_dsp.ION_IOC_SHARE(self.device.ion_fd, handle=b.handle)
va_addr = libc.mmap(0, size, mmap.PROT_READ|mmap.PROT_WRITE, mmap.MAP_SHARED, share_info.fd, 0)
return DSPBuffer(va_addr, size, share_info)
def _free(self, opaque:DSPBuffer, options:BufferOptions):
libc.munmap(opaque.va_addr, opaque.size)
os.close(opaque.share_info.fd)
qcom_dsp.ION_IOC_FREE(self.device.ion_fd, handle=opaque.share_info.handle)
def as_buffer(self, src:DSPBuffer) -> memoryview: return to_mv(src.va_addr, src.size)
def copyin(self, dest:DSPBuffer, src:memoryview): ctypes.memmove(dest.va_addr, from_mv(src), src.nbytes)
def copyout(self, dest:memoryview, src:DSPBuffer): ctypes.memmove(from_mv(dest), src.va_addr, dest.nbytes)
class DSPDevice(Compiled):
def __init__(self, device:str=""):
self.ion_fd = os.open('/dev/ion', os.O_RDONLY)
# Generate link script to pass into clang. Aligning all used sections to 4k fixes invoke problem.
sections = ['hash', 'text', 'rela.plt', 'got', 'got.plt', 'dynamic', 'dynsym', 'dynstr', 'plt', 'data', 'bss']
sections_link = '\n'.join([f'.{n} : ALIGN(4096) {{ *(.{n}) }}' for n in sections])
with tempfile.NamedTemporaryFile(delete=False) as self.link_ld:
self.link_ld.write(f"SECTIONS {{ . = 0x0; {sections_link}\n /DISCARD/ : {{ *(.note .note.* .gnu.hash .comment) }} }}".encode())
self.link_ld.flush()
compiler_args = ["--target=hexagon", "-mcpu=hexagonv65", "-fuse-ld=lld", "-nostdlib", "-mhvx=v65", "-mhvx-length=128b", f"-T{self.link_ld.name}"]
super().__init__(device, DSPAllocator(self), DSPRenderer(), ClangCompiler("compile_dsp", args=compiler_args), functools.partial(DSPProgram, self))
fastrpc_shell = memoryview(bytearray(pathlib.Path('/dsp/cdsp/fastrpc_shell_3').read_bytes()))
self.shell_buf = self.allocator.alloc(round_up(fastrpc_shell.nbytes, 0x1000), BufferOptions(nolru=True))
ctypes.memmove(self.shell_buf.va_addr, mv_address(fastrpc_shell), fastrpc_shell.nbytes)
self.init_dsp()
RPCListner(self).start()
def open_lib(self, filepath):
fp = f"file:///{filepath}?entry&_modver=1.0&_dom=cdsp\0"
pra, _, _, _ = rpc_prep_args(ins=[memoryview(array.array('I', [len(fp), 0xff])), memoryview(bytearray(f"{fp}".encode()))],
outs=[o1:=memoryview(bytearray(0x8)), o2:=memoryview(bytearray(0xff))])
qcom_dsp.FASTRPC_IOCTL_INVOKE(self.rpc_fd, handle=0, sc=rpc_sc(method=0, ins=2, outs=2), pra=pra)
if o1.cast('i')[1] < 0: raise RuntimeError(f"Cannot open lib: {o2.tobytes().decode()}")
return o1.cast('I')[0]
def close_lib(self, handle):
pra, _, _, _ = rpc_prep_args(ins=[memoryview(array.array('I', [handle, 0xff]))], outs=[memoryview(bytearray(0x8)), memoryview(bytearray(0xff))])
qcom_dsp.FASTRPC_IOCTL_INVOKE(self.rpc_fd, handle=0, sc=rpc_sc(method=1, ins=1, outs=2), pra=pra)
def exec_lib(self, filepath, sc, args, fds, attrs):
def _exec_lib():
handle = self.open_lib(filepath)
qcom_dsp.FASTRPC_IOCTL_INVOKE_ATTRS(self.rpc_fd, fds=fds, attrs=attrs, inv=qcom_dsp.struct_fastrpc_ioctl_invoke(handle=handle, sc=sc, pra=args))
self.close_lib(handle)
try: _exec_lib()
except (OSError, PermissionError):
# DSP might ask for a connection reset or just fail with operation not permitted, try to reset connection.
self.init_dsp()
_exec_lib()
def init_dsp(self):
if hasattr(self, 'rpc_fd'):
with contextlib.suppress(OSError):
qcom_dsp.FASTRPC_IOCTL_INVOKE(self.rpc_fd, handle=4, sc=rpc_sc(method=2, ins=0, outs=0)) # pylint: disable=access-member-before-definition
os.close(self.rpc_fd) # pylint: disable=access-member-before-definition
self.rpc_fd: int = os.open('/dev/adsprpc-smd', os.O_RDONLY | os.O_NONBLOCK)
qcom_dsp.FASTRPC_IOCTL_GETINFO(self.rpc_fd, 3)
qcom_dsp.FASTRPC_IOCTL_CONTROL(self.rpc_fd, req=0x3)
qcom_dsp.FASTRPC_IOCTL_INIT(self.rpc_fd, flags=0x1, file=self.shell_buf.va_addr, filelen=self.shell_buf.size, filefd=self.shell_buf.share_info.fd)
qcom_dsp.FASTRPC_IOCTL_INVOKE(self.rpc_fd, handle=3, sc=rpc_sc(method=3, ins=0, outs=0))
class RPCListner(threading.Thread):
def __init__(self, device:DSPDevice):
super().__init__()
self.device, self.daemon = device, True
def run(self):
# Setup initial request arguments.
context, status = 0, 0xffffffff
req_args, _, _, _ = rpc_prep_args(ins=[msg_send:=memoryview(bytearray(0x10)).cast('I'), out_buf:=memoryview(bytearray(0x10000)).cast('I')],
outs=[msg_recv:=memoryview(bytearray(0x10)).cast('I'), in_buf:=memoryview(bytearray(0x10000)).cast('I')])
req_args[1].buf.len = 0
while True:
# Update message request and send it.
msg_send[:] = array.array('I', [context, status, req_args[1].buf.len, in_buf.nbytes])
try: qcom_dsp.FASTRPC_IOCTL_INVOKE(self.device.rpc_fd, handle=0x3, sc=0x04020200, pra=req_args)
except OSError: continue # retry
context, inbufs, outbufs = msg_recv[0], ((sc:=msg_recv[2]) >> 16) & 0xff, (msg_recv[2] >> 8) & 0xff
in_ptr, out_ptr, objs = mv_address(in_buf), mv_address(out_buf), []
for i in range(inbufs + outbufs):
obj_ptr = round_up(in_ptr + 4, 8) if i < inbufs else round_up(out_ptr + 4, 8)
objs.append(to_mv(obj_ptr, obj_size:=to_mv(in_ptr, 4).cast('I')[0]))
if i < inbufs: in_ptr = obj_ptr + obj_size
else:
to_mv(out_ptr, 4).cast('I')[0] = obj_size
out_ptr = obj_ptr + obj_size
in_ptr += 4
in_args, out_args = objs[:inbufs], objs[inbufs:]
req_args[1].buf.len = out_ptr - mv_address(out_buf)
status = 0 # reset status, will set if error
if sc == 0x20200: pass # greating
elif sc == 0x13050100: # open
try: out_args[0].cast('I')[0] = os.open(in_args[3].tobytes()[:-1].decode(), os.O_RDONLY)
except OSError: status = 1
elif sc == 0x3010000: os.close(in_args[0].cast('I')[0])
elif sc == 0x9010000: # seek
res = os.lseek(in_args[0].cast('I')[0], in_args[0].cast('I')[1], in_args[0].cast('I')[2])
status = 0 if res >= 0 else res
elif sc == 0x4010200: # read
buf = os.read(in_args[0].cast('I')[0], in_args[0].cast('I')[1])
out_args[1][:len(buf)] = buf
out_args[0].cast('I')[0:2] = array.array('I', [len(buf), int(len(buf) == 0)])
elif sc == 0x1f020100: # stat
stat = os.stat(in_args[1].tobytes()[:-1].decode())
out_stat = qcom_dsp.struct_apps_std_STAT.from_address(mv_address(out_args[0]))
for f in out_stat._fields_: out_stat.__setattr__(f[0], int(getattr(stat, f"st_{f[0]}", 0)))
elif sc == 0x2010100: # mmap
st = qcom_dsp.FASTRPC_IOCTL_MMAP(self.device.rpc_fd, fd=-1, flags=in_args[0].cast('I')[2], vaddrin=0, size=in_args[0].cast('Q')[3])
out_args[0].cast('Q')[0:2] = array.array('Q', [0, st.vaddrout])
else: raise RuntimeError(f"Unknown op: {sc=:X}")