libspe2 0.9a
lib_builtin.c
Go to the documentation of this file.
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