129a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi/* 229a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * Copyright (C) 2016 The Android Open Source Project 329a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * 429a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * Licensed under the Apache License, Version 2.0 (the "License"); 529a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * you may not use this file except in compliance with the License. 629a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * You may obtain a copy of the License at 729a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * 829a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * http://www.apache.org/licenses/LICENSE-2.0 929a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * 1029a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * Unless required by applicable law or agreed to in writing, software 1129a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * distributed under the License is distributed on an "AS IS" BASIS, 1229a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1329a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * See the License for the specific language governing permissions and 1429a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi * limitations under the License. 1529a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi */ 1629a28c40ccaa69b912f53e067b90a0ee3d7992dbAshutosh Joshi 1762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg#include <syscall.h> 1862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg#include <stdio.h> 1962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergstatic uint32_t mTableStore[(sizeof(struct SyscallTable) + sizeof(union SyscallTableEntry[1 << SYSCALL_BITS_LEVEL_0]) + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 2362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergstatic const uint8_t mLevelBits[] = {SYSCALL_BITS_LEVEL_0, SYSCALL_BITS_LEVEL_1, SYSCALL_BITS_LEVEL_2, SYSCALL_BITS_LEVEL_3, 0}; 2462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergstatic struct SyscallTable *mTable = (struct SyscallTable*)mTableStore; 2562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 2862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergvoid syscallInit(void) 2962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg{ 3062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg mTable->numEntries = 1 << SYSCALL_BITS_LEVEL_0; 3162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg} 3262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 3362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergbool syscallAddTable(uint32_t path, uint32_t level, struct SyscallTable *table) 3462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg{ 3562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg struct SyscallTable** tabP = &mTable; 3662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg const uint8_t *bits = mLevelBits; 3762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 3862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg while (level--) { 3962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg uint32_t idx = path >> (32 - *bits); 4062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg path <<= *bits++; 4162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 4262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg //cannot traverse 4362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg if ((*tabP)->numEntries <= idx) 4462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return false; 4562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 4662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg //cannot add table as final leaf 4762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg if (*bits == 0) 4862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return false; 4962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 5062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg tabP = &(*tabP)->entry[idx].subtable; 5162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg } 5262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 5362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg *tabP = table; 5462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return true; 5562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg} 5662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 5762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergstatic SyscallFunc* syscallFindHandlerLoc(uint32_t path) 5862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg{ 5962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg struct SyscallTable* tab = mTable; 6062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg const uint8_t *bits = mLevelBits; 6162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 6262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg while (tab) { 6362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg uint32_t idx = path >> (32 - *bits); 6462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 6562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg path <<= *bits++; 6662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 6762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg if (tab->numEntries <= idx) 6862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg break; 6962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 700daf3debdabd99ceb38d372832c6b4dfcb3e1810Ben Fennema if (!*bits) 7162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return &tab->entry[idx].func; 7262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg else 7362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg tab = tab->entry[idx].subtable; 7462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg } 7562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 7662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return NULL; 7762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg} 7862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 7962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinbergbool syscallAddFunc(uint32_t path, SyscallFunc func) 8062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg{ 8162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg SyscallFunc *f = syscallFindHandlerLoc(path); 8262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 8362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg if (!f) 8462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return false; 8562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 8662b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg *f = func; 8762b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return true; 8862b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg} 8962b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 9062b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry GrinbergSyscallFunc syscallGetHandler(uint32_t path) 9162b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg{ 9262b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg SyscallFunc *f = syscallFindHandlerLoc(path); 9362b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg 9462b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg return f ? *f : NULL; 9562b2b5d80e197210bfbe8dfb6aff66ccb8a495c1Dmitry Grinberg} 9674e472948470ccf63b9e80f4317f6b3eba8a194cDmitry Grinberg 9774e472948470ccf63b9e80f4317f6b3eba8a194cDmitry Grinberg 98