1#ifndef _CHRE_SLPI_SKEL_H 2#define _CHRE_SLPI_SKEL_H 3/** 4 * Defines the FastRPC interface between CHRE running on the SLPI and the host 5 * daemon running on the AP. 6 * 7 * Note that the interface name gets prefixed to the function names in the 8 * generated sources, with an underscore separating them. 9 * 10 * Refer to the implementations of these functions in the CHRE code that runs on 11 * the SLPI for documentation covering the parameters, return values, etc. 12 */ 13#include "chre_slpi.h" 14#ifndef _QAIC_ENV_H 15#define _QAIC_ENV_H 16 17#ifdef __GNUC__ 18#ifdef __clang__ 19#pragma GCC diagnostic ignored "-Wunknown-pragmas" 20#else 21#pragma GCC diagnostic ignored "-Wpragmas" 22#endif 23#pragma GCC diagnostic ignored "-Wuninitialized" 24#pragma GCC diagnostic ignored "-Wunused-parameter" 25#pragma GCC diagnostic ignored "-Wunused-function" 26#endif 27 28#ifndef _ATTRIBUTE_UNUSED 29 30#ifdef _WIN32 31#define _ATTRIBUTE_UNUSED 32#else 33#define _ATTRIBUTE_UNUSED __attribute__ ((unused)) 34#endif 35 36#endif // _ATTRIBUTE_UNUSED 37 38#ifndef __QAIC_REMOTE 39#define __QAIC_REMOTE(ff) ff 40#endif //__QAIC_REMOTE 41 42#ifndef __QAIC_HEADER 43#define __QAIC_HEADER(ff) ff 44#endif //__QAIC_HEADER 45 46#ifndef __QAIC_HEADER_EXPORT 47#define __QAIC_HEADER_EXPORT 48#endif // __QAIC_HEADER_EXPORT 49 50#ifndef __QAIC_HEADER_ATTRIBUTE 51#define __QAIC_HEADER_ATTRIBUTE 52#endif // __QAIC_HEADER_ATTRIBUTE 53 54#ifndef __QAIC_IMPL 55#define __QAIC_IMPL(ff) ff 56#endif //__QAIC_IMPL 57 58#ifndef __QAIC_IMPL_EXPORT 59#define __QAIC_IMPL_EXPORT 60#endif // __QAIC_IMPL_EXPORT 61 62#ifndef __QAIC_IMPL_ATTRIBUTE 63#define __QAIC_IMPL_ATTRIBUTE 64#endif // __QAIC_IMPL_ATTRIBUTE 65 66#ifndef __QAIC_STUB 67#define __QAIC_STUB(ff) ff 68#endif //__QAIC_STUB 69 70#ifndef __QAIC_STUB_EXPORT 71#define __QAIC_STUB_EXPORT 72#endif // __QAIC_STUB_EXPORT 73 74#ifndef __QAIC_STUB_ATTRIBUTE 75#define __QAIC_STUB_ATTRIBUTE 76#endif // __QAIC_STUB_ATTRIBUTE 77 78#ifndef __QAIC_SKEL 79#define __QAIC_SKEL(ff) ff 80#endif //__QAIC_SKEL__ 81 82#ifndef __QAIC_SKEL_EXPORT 83#define __QAIC_SKEL_EXPORT 84#endif // __QAIC_SKEL_EXPORT 85 86#ifndef __QAIC_SKEL_ATTRIBUTE 87#define __QAIC_SKEL_ATTRIBUTE 88#endif // __QAIC_SKEL_ATTRIBUTE 89 90#ifdef __QAIC_DEBUG__ 91 #ifndef __QAIC_DBG_PRINTF__ 92 #include <stdio.h> 93 #define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0) 94 #endif 95#else 96 #define __QAIC_DBG_PRINTF__( ee ) (void)0 97#endif 98 99 100#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof))) 101 102#define _COPY(dst, dof, src, sof, sz) \ 103 do {\ 104 struct __copy { \ 105 char ar[sz]; \ 106 };\ 107 *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\ 108 } while (0) 109 110#define _COPYIF(dst, dof, src, sof, sz) \ 111 do {\ 112 if(_OFFSET(dst, dof) != _OFFSET(src, sof)) {\ 113 _COPY(dst, dof, src, sof, sz); \ 114 } \ 115 } while (0) 116 117_ATTRIBUTE_UNUSED 118static __inline void _qaic_memmove(void* dst, void* src, int size) { 119 int i; 120 for(i = 0; i < size; ++i) { 121 ((char*)dst)[i] = ((char*)src)[i]; 122 } 123} 124 125#define _MEMMOVEIF(dst, src, sz) \ 126 do {\ 127 if(dst != src) {\ 128 _qaic_memmove(dst, src, sz);\ 129 } \ 130 } while (0) 131 132 133#define _ASSIGN(dst, src, sof) \ 134 do {\ 135 dst = OFFSET(src, sof); \ 136 } while (0) 137 138#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str)) 139 140#include "AEEStdErr.h" 141 142#define _TRY(ee, func) \ 143 do { \ 144 if (AEE_SUCCESS != ((ee) = func)) {\ 145 __QAIC_DBG_PRINTF__((__FILE__ ":%d:error:%d:%s\n", __LINE__, (int)(ee),#func));\ 146 goto ee##bail;\ 147 } \ 148 } while (0) 149 150#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS) 151 152#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS) 153 154#ifdef __QAIC_DEBUG__ 155#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv)) 156#else 157#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, 0, size, alignment, (void**)&pv)) 158#endif 159 160 161#endif // _QAIC_ENV_H 162 163#include "remote.h" 164#ifndef _ALLOCATOR_H 165#define _ALLOCATOR_H 166 167#include <stdlib.h> 168#include <stdint.h> 169 170typedef struct _heap _heap; 171struct _heap { 172 _heap* pPrev; 173 const char* loc; 174 uint64_t buf; 175}; 176 177typedef struct _allocator { 178 _heap* pheap; 179 uint8_t* stack; 180 uint8_t* stackEnd; 181 int nSize; 182} _allocator; 183 184_ATTRIBUTE_UNUSED 185static __inline int _heap_alloc(_heap** ppa, const char* loc, int size, void** ppbuf) { 186 _heap* pn = 0; 187 pn = malloc(size + sizeof(_heap) - sizeof(uint64_t)); 188 if(pn != 0) { 189 pn->pPrev = *ppa; 190 pn->loc = loc; 191 *ppa = pn; 192 *ppbuf = (void*)&(pn->buf); 193 return 0; 194 } else { 195 return -1; 196 } 197} 198#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1)) 199 200_ATTRIBUTE_UNUSED 201static __inline int _allocator_alloc(_allocator* me, 202 const char* loc, 203 int size, 204 unsigned int al, 205 void** ppbuf) { 206 if(size < 0) { 207 return -1; 208 } else if (size == 0) { 209 *ppbuf = 0; 210 return 0; 211 } 212 if((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize) { 213 *ppbuf = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al); 214 me->stackEnd = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size; 215 return 0; 216 } else { 217 return _heap_alloc(&me->pheap, loc, size, ppbuf); 218 } 219} 220 221_ATTRIBUTE_UNUSED 222static __inline void _allocator_deinit(_allocator* me) { 223 _heap* pa = me->pheap; 224 while(pa != 0) { 225 _heap* pn = pa; 226 const char* loc = pn->loc; 227 (void)loc; 228 pa = pn->pPrev; 229 free(pn); 230 } 231} 232 233_ATTRIBUTE_UNUSED 234static __inline void _allocator_init(_allocator* me, uint8_t* stack, int stackSize) { 235 me->stack = stack; 236 me->stackEnd = stack + stackSize; 237 me->nSize = stackSize; 238 me->pheap = 0; 239} 240 241 242#endif // _ALLOCATOR_H 243 244#ifndef SLIM_H 245#define SLIM_H 246 247#include <stdint.h> 248 249//a C data structure for the idl types that can be used to implement 250//static and dynamic language bindings fairly efficiently. 251// 252//the goal is to have a minimal ROM and RAM footprint and without 253//doing too many allocations. A good way to package these things seemed 254//like the module boundary, so all the idls within one module can share 255//all the type references. 256 257 258#define PARAMETER_IN 0x0 259#define PARAMETER_OUT 0x1 260#define PARAMETER_INOUT 0x2 261#define PARAMETER_ROUT 0x3 262#define PARAMETER_INROUT 0x4 263 264//the types that we get from idl 265#define TYPE_OBJECT 0x0 266#define TYPE_INTERFACE 0x1 267#define TYPE_PRIMITIVE 0x2 268#define TYPE_ENUM 0x3 269#define TYPE_STRING 0x4 270#define TYPE_WSTRING 0x5 271#define TYPE_STRUCTURE 0x6 272#define TYPE_UNION 0x7 273#define TYPE_ARRAY 0x8 274#define TYPE_SEQUENCE 0x9 275 276//these require the pack/unpack to recurse 277//so it's a hint to those languages that can optimize in cases where 278//recursion isn't necessary. 279#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE) 280#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION) 281#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY) 282#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE) 283 284 285typedef struct Type Type; 286 287#define INHERIT_TYPE\ 288 int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\ 289 union {\ 290 struct {\ 291 const uintptr_t p1;\ 292 const uintptr_t p2;\ 293 } _cast;\ 294 struct {\ 295 uint32_t iid;\ 296 uint32_t bNotNil;\ 297 } object;\ 298 struct {\ 299 const Type *arrayType;\ 300 int32_t nItems;\ 301 } array;\ 302 struct {\ 303 const Type *seqType;\ 304 int32_t nMaxLen;\ 305 } seqSimple; \ 306 struct {\ 307 uint32_t bFloating;\ 308 uint32_t bSigned;\ 309 } prim; \ 310 const SequenceType* seqComplex;\ 311 const UnionType *unionType;\ 312 const StructType *structType;\ 313 int32_t stringMaxLen;\ 314 uint8_t bInterfaceNotNil;\ 315 } param;\ 316 uint8_t type;\ 317 uint8_t nativeAlignment\ 318 319typedef struct UnionType UnionType; 320typedef struct StructType StructType; 321typedef struct SequenceType SequenceType; 322struct Type { 323 INHERIT_TYPE; 324}; 325 326struct SequenceType { 327 const Type * seqType; 328 uint32_t nMaxLen; 329 uint32_t inSize; 330 uint32_t routSizePrimIn; 331 uint32_t routSizePrimROut; 332}; 333 334//byte offset from the start of the case values for 335//this unions case value array. it MUST be aligned 336//at the alignment requrements for the descriptor 337// 338//if negative it means that the unions cases are 339//simple enumerators, so the value read from the descriptor 340//can be used directly to find the correct case 341typedef union CaseValuePtr CaseValuePtr; 342union CaseValuePtr { 343 const uint8_t* value8s; 344 const uint16_t* value16s; 345 const uint32_t* value32s; 346 const uint64_t* value64s; 347}; 348 349//these are only used in complex cases 350//so I pulled them out of the type definition as references to make 351//the type smaller 352struct UnionType { 353 const Type *descriptor; 354 uint32_t nCases; 355 const CaseValuePtr caseValues; 356 const Type * const *cases; 357 int32_t inSize; 358 int32_t routSizePrimIn; 359 int32_t routSizePrimROut; 360 uint8_t inAlignment; 361 uint8_t routAlignmentPrimIn; 362 uint8_t routAlignmentPrimROut; 363 uint8_t inCaseAlignment; 364 uint8_t routCaseAlignmentPrimIn; 365 uint8_t routCaseAlignmentPrimROut; 366 uint8_t nativeCaseAlignment; 367 uint8_t bDefaultCase; 368}; 369 370struct StructType { 371 uint32_t nMembers; 372 const Type * const *members; 373 int32_t inSize; 374 int32_t routSizePrimIn; 375 int32_t routSizePrimROut; 376 uint8_t inAlignment; 377 uint8_t routAlignmentPrimIn; 378 uint8_t routAlignmentPrimROut; 379}; 380 381typedef struct Parameter Parameter; 382struct Parameter { 383 INHERIT_TYPE; 384 uint8_t mode; 385 uint8_t bNotNil; 386}; 387 388#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64)) 389#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff) 390 391typedef struct Method Method; 392struct Method { 393 uint32_t uScalars; //no method index 394 int32_t primInSize; 395 int32_t primROutSize; 396 int maxArgs; 397 int numParams; 398 const Parameter * const *params; 399 uint8_t primInAlignment; 400 uint8_t primROutAlignment; 401}; 402 403typedef struct Interface Interface; 404 405struct Interface { 406 int nMethods; 407 const Method * const *methodArray; 408 int nIIds; 409 const uint32_t *iids; 410 const uint16_t* methodStringArray; 411 const uint16_t* methodStrings; 412 const char* strings; 413}; 414 415 416#endif //SLIM_H 417 418 419#ifndef _CHRE_SLPI_SLIM_H 420#define _CHRE_SLPI_SLIM_H 421#include "remote.h" 422#include <stdint.h> 423 424#ifndef __QAIC_SLIM 425#define __QAIC_SLIM(ff) ff 426#endif 427#ifndef __QAIC_SLIM_EXPORT 428#define __QAIC_SLIM_EXPORT 429#endif 430 431static const Type types[1]; 432static const Type types[1] = {{0x1,{{(const uintptr_t)0,(const uintptr_t)0}}, 2,0x1}}; 433static const Parameter parameters[3] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)0}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0}}; 434static const Parameter* const parameterArrays[3] = {(&(parameters[0])),(&(parameters[1])),(&(parameters[2]))}; 435static const Method methods[3] = {{REMOTE_SCALARS_MAKEX(0,0,0x0,0x0,0x0,0x0),0x0,0x0,0,0,0,0x0,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x2,0x0,0x0),0x4,0x4,4,2,(&(parameterArrays[0])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x0),0x4,0x0,2,1,(&(parameterArrays[2])),0x4,0x0}}; 436static const Method* const methodArrays[6] = {&(methods[0]),&(methods[0]),&(methods[0]),&(methods[0]),&(methods[1]),&(methods[2])}; 437static const char strings[144] = "initialize_reverse_monitor\0deliver_message_from_host\0get_message_to_host\0wait_on_thread_exit\0start_thread\0stop_thread\0messageLen\0message\0buffer\0"; 438static const uint16_t methodStrings[9] = {53,137,118,27,129,106,0,73,93}; 439static const uint16_t methodStringsArrays[6] = {8,7,6,5,0,3}; 440__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(chre_slpi_slim) = {6,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; 441#endif //_CHRE_SLPI_SLIM_H 442#ifdef __cplusplus 443extern "C" { 444#endif 445static __inline int _skel_method(int (*_pfn)(char*, uint32_t), uint32_t _sc, remote_arg* _pra) { 446 remote_arg* _praEnd; 447 char* _in0[1]; 448 uint32_t _in0Len[1]; 449 uint32_t* _primIn; 450 remote_arg* _praIn; 451 int _nErr = 0; 452 _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); 453 _ASSERT(_nErr, (_pra + ((2 + 0) + (0 + 0))) <= _praEnd); 454 _ASSERT(_nErr, _pra[0].buf.nLen >= 4); 455 _primIn = _pra[0].buf.pv; 456 _COPY(_in0Len, 0, _primIn, 0, 4); 457 _praIn = (_pra + 1); 458 _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0])); 459 _in0[0] = _praIn[0].buf.pv; 460 _TRY(_nErr, _pfn(*_in0, *_in0Len)); 461 _CATCH(_nErr) {} 462 return _nErr; 463} 464static __inline int _skel_method_1(int (*_pfn)(char*, uint32_t, uint32_t*), uint32_t _sc, remote_arg* _pra) { 465 remote_arg* _praEnd; 466 char* _rout0[1]; 467 uint32_t _rout0Len[1]; 468 uint32_t _rout1[1]; 469 uint32_t* _primIn; 470 int _numIn[1]; 471 uint32_t* _primROut; 472 remote_arg* _praIn; 473 remote_arg* _praROut; 474 int _nErr = 0; 475 _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); 476 _ASSERT(_nErr, (_pra + ((1 + 2) + (0 + 0))) <= _praEnd); 477 _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1); 478 _ASSERT(_nErr, _pra[0].buf.nLen >= 4); 479 _primIn = _pra[0].buf.pv; 480 _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4); 481 _primROut = _pra[(_numIn[0] + 1)].buf.pv; 482 _COPY(_rout0Len, 0, _primIn, 0, 4); 483 _praIn = (_pra + 1); 484 _praROut = (_praIn + _numIn[0] + 1); 485 _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout0Len[0])); 486 _rout0[0] = _praROut[0].buf.pv; 487 _TRY(_nErr, _pfn(*_rout0, *_rout0Len, _rout1)); 488 _COPY(_primROut, 0, _rout1, 0, 4); 489 _CATCH(_nErr) {} 490 return _nErr; 491} 492static __inline int _skel_method_2(int (*_pfn)(void), uint32_t _sc, remote_arg* _pra) { 493 remote_arg* _praEnd; 494 int _nErr = 0; 495 _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc) + REMOTE_SCALARS_INHANDLES(_sc) + REMOTE_SCALARS_OUTHANDLES(_sc)); 496 _ASSERT(_nErr, (_pra + ((0 + 0) + (0 + 0))) <= _praEnd); 497 _TRY(_nErr, _pfn()); 498 _CATCH(_nErr) {} 499 return _nErr; 500} 501__QAIC_SKEL_EXPORT int __QAIC_SKEL(chre_slpi_skel_invoke)(uint32_t _sc, remote_arg* _pra) __QAIC_SKEL_ATTRIBUTE { 502 switch(REMOTE_SCALARS_METHOD(_sc)) 503 { 504 case 0: 505 return _skel_method_2((void*)__QAIC_IMPL(chre_slpi_start_thread), _sc, _pra); 506 case 1: 507 return _skel_method_2((void*)__QAIC_IMPL(chre_slpi_wait_on_thread_exit), _sc, _pra); 508 case 2: 509 return _skel_method_2((void*)__QAIC_IMPL(chre_slpi_initialize_reverse_monitor), _sc, _pra); 510 case 3: 511 return _skel_method_2((void*)__QAIC_IMPL(chre_slpi_stop_thread), _sc, _pra); 512 case 4: 513 return _skel_method_1((void*)__QAIC_IMPL(chre_slpi_get_message_to_host), _sc, _pra); 514 case 5: 515 return _skel_method((void*)__QAIC_IMPL(chre_slpi_deliver_message_from_host), _sc, _pra); 516 } 517 return AEE_EUNSUPPORTED; 518} 519#ifdef __cplusplus 520} 521#endif 522#endif //_CHRE_SLPI_SKEL_H 523