1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _SYSCALL_H_ 18 #define _SYSCALL_H_ 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #include <stdbool.h> 25 #include <stdint.h> 26 #include <stdarg.h> 27 28 /* 29 * System calls are indexed by an unsigned 32-bit constant path. To avoid having a 30 * single gigantic table, we use a system of 4-level tables to dispatch them. In 31 * order of use the tables use: 5, 10, 8, 9 bits, from high to low, so for example 32 * syscall 0x19918FC8 would use table indices 3, 200, 199, 456 since it is equal to 33 * (3 << (10 + 8 + 9)) + (200 << (8 + 9)) + (199 << 9) + 456. Each table may be 34 * truncated (with a length field specified), and may be in RAM or ROM, as seen fit. 35 * The expected use case is that the first level detemines grand purpose 36 * (OS, driver, google app, 3rd party app, etc), second level determines vendor, 37 * third level determines subsystem, and the last level determines desired function. 38 */ 39 40 #define SYSCALL_BITS_LEVEL_0 5 /* domain */ 41 #define SYSCALL_BITS_LEVEL_1 10 /* family */ 42 #define SYSCALL_BITS_LEVEL_2 8 /* genus */ 43 #define SYSCALL_BITS_LEVEL_3 9 /* species */ 44 45 #define SYSCALL_CUT_SCALE_SHIFT(_val, _cut, _shift) ((((uint32_t)(_val)) & ((1UL << (_cut)) - 1)) << (_shift)) 46 #define SYSCALL_NO(_domain, _family, _genus, _species) ( \ 47 SYSCALL_CUT_SCALE_SHIFT((_domain) , SYSCALL_BITS_LEVEL_0, SYSCALL_BITS_LEVEL_1 + SYSCALL_BITS_LEVEL_2 + SYSCALL_BITS_LEVEL_3) + \ 48 SYSCALL_CUT_SCALE_SHIFT((_family) , SYSCALL_BITS_LEVEL_1, SYSCALL_BITS_LEVEL_2 + SYSCALL_BITS_LEVEL_3) + \ 49 SYSCALL_CUT_SCALE_SHIFT((_genus) , SYSCALL_BITS_LEVEL_2, SYSCALL_BITS_LEVEL_3) + \ 50 SYSCALL_CUT_SCALE_SHIFT((_species), SYSCALL_BITS_LEVEL_3, 0) \ 51 ) 52 53 //level 0 indices: 54 #define SYSCALL_DOMAIN_OS 0 55 #define SYSCALL_DOMAIN_DRIVERS 1 /* hardware drivers for custom hardware */ 56 #define SYSCALL_DOMAIN_CHRE 2 /* alternative API */ 57 58 typedef void (*SyscallFunc)(uintptr_t *retValP, va_list args); /* you better know what args you need */ 59 60 struct SyscallTable { 61 uint32_t numEntries; 62 union SyscallTableEntry { 63 struct SyscallTable *subtable; 64 SyscallFunc func; 65 } entry[]; 66 }; 67 68 69 void syscallInit(void); 70 71 //add a complete table 72 bool syscallAddTable(uint32_t path, uint32_t level, struct SyscallTable *table); 73 74 //this will only work if the backing table exists...this is intentional to avoid auto growth in scary ways 75 bool syscallAddFunc(uint32_t path, SyscallFunc func); 76 77 SyscallFunc syscallGetHandler(uint32_t path); // NULL if none 78 79 80 #ifdef __cplusplus 81 } 82 #endif 83 84 #endif 85 86