libspe2 0.9a
|
00001 /* 00002 * libspe2 - A wrapper library to adapt the JSRE SPU usage model to SPUFS 00003 * Copyright (C) 2005 IBM Corp. 00004 * 00005 * This library is free software; you can redistribute it and/or modify it 00006 * under the terms of the GNU Lesser General Public License as published by 00007 * the Free Software Foundation; either version 2.1 of the License, 00008 * or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, but 00011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this library; if not, write to the Free Software Foundation, 00017 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include <errno.h> 00022 00023 #include "spebase.h" 00024 #include "lib_builtin.h" 00025 #include "default_c99_handler.h" 00026 #include "default_posix1_handler.h" 00027 #include "default_libea_handler.h" 00028 00029 #define HANDLER_IDX(x) (x & 0xff) 00030 00031 /* 00032 * Default SPE library call handlers for 21xx stop-and-signal. 00033 */ 00034 static void *handlers[256] = { 00035 [HANDLER_IDX(SPE_C99_CLASS)] = _base_spe_default_c99_handler, 00036 [HANDLER_IDX(SPE_POSIX1_CLASS)] = _base_spe_default_posix1_handler, 00037 [HANDLER_IDX(SPE_LIBEA_CLASS)] = _base_spe_default_libea_handler 00038 }; 00039 00040 int _base_spe_callback_handler_register(void * handler, unsigned int callnum, unsigned int mode) 00041 { 00042 errno = 0; 00043 00044 if (callnum > MAX_CALLNUM) { 00045 errno = EINVAL; 00046 return -1; 00047 } 00048 00049 switch(mode){ 00050 case SPE_CALLBACK_NEW: 00051 if (callnum < RESERVED) { 00052 errno = EACCES; 00053 return -1; 00054 } 00055 if (handlers[callnum] != NULL) { 00056 errno = EACCES; 00057 return -1; 00058 } 00059 handlers[callnum] = handler; 00060 break; 00061 00062 case SPE_CALLBACK_UPDATE: 00063 if (handlers[callnum] == NULL) { 00064 errno = ESRCH; 00065 return -1; 00066 } 00067 handlers[callnum] = handler; 00068 break; 00069 default: 00070 errno = EINVAL; 00071 return -1; 00072 break; 00073 } 00074 return 0; 00075 00076 } 00077 00078 int _base_spe_callback_handler_deregister(unsigned int callnum ) 00079 { 00080 errno = 0; 00081 if (callnum > MAX_CALLNUM) { 00082 errno = EINVAL; 00083 return -1; 00084 } 00085 if (callnum < RESERVED) { 00086 errno = EACCES; 00087 return -1; 00088 } 00089 if (handlers[callnum] == NULL) { 00090 errno = ESRCH; 00091 return -1; 00092 } 00093 00094 handlers[callnum] = NULL; 00095 return 0; 00096 } 00097 00098 void * _base_spe_callback_handler_query(unsigned int callnum ) 00099 { 00100 errno = 0; 00101 00102 if (callnum > MAX_CALLNUM) { 00103 errno = EINVAL; 00104 return NULL; 00105 } 00106 if (handlers[callnum] == NULL) { 00107 errno = ESRCH; 00108 return NULL; 00109 } 00110 return handlers[callnum]; 00111 } 00112 00113 int _base_spe_handle_library_callback(struct spe_context *spe, int callnum, 00114 unsigned int npc) 00115 { 00116 int (*handler)(void *, unsigned int); 00117 int rc; 00118 00119 errno = 0; 00120 if (!handlers[callnum]) { 00121 DEBUG_PRINTF ("No SPE library handler registered for this call.\n"); 00122 errno=ENOSYS; 00123 return -1; 00124 } 00125 00126 handler=handlers[callnum]; 00127 00128 /* For emulated isolation mode, position the 00129 * npc so that the buffer for the PPE-assisted 00130 * library calls can be accessed. */ 00131 if (spe->base_private->flags & SPE_ISOLATE_EMULATE) 00132 npc = SPE_EMULATE_PARAM_BUFFER; 00133 00134 rc = handler(spe->base_private->mem_mmap_base, npc); 00135 if (rc) { 00136 DEBUG_PRINTF ("SPE library call unsupported.\n"); 00137 errno=ENOSYS; 00138 return rc; 00139 } 00140 return 0; 00141 } 00142