1115013Smarcel/* 2160157SmarcelCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P. 3121642SmarcelPermission is hereby granted, free of charge, to any person 4121642Smarcelobtaining a copy of this software and associated documentation 5121642Smarcelfiles (the "Software"), to deal in the Software without 6121642Smarcelrestriction, including without limitation the rights to use, 7121642Smarcelcopy, modify, merge, publish, distribute, sublicense, and/or sell 8121642Smarcelcopies of the Software, and to permit persons to whom the 9121642SmarcelSoftware is furnished to do so, subject to the following 10121642Smarcelconditions: 11115013Smarcel 12121642SmarcelThe above copyright notice and this permission notice shall be 13121642Smarcelincluded in all copies or substantial portions of the Software. 14121642Smarcel 15121642SmarcelTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16121642SmarcelEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17121642SmarcelOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18121642SmarcelNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19121642SmarcelHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20121642SmarcelWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21121642SmarcelFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22121642SmarcelOTHER DEALINGS IN THE SOFTWARE. 23121642Smarcel*/ 24121642Smarcel 25160163Smarcel#ifndef _KERNEL 26115013Smarcel#include <stdlib.h> 27160163Smarcel#endif 28115013Smarcel 29115013Smarcel#include "uwx_env.h" 30115013Smarcel#include "uwx_scoreboard.h" 31115013Smarcel#include "uwx_str.h" 32115013Smarcel#include "uwx_trace.h" 33115013Smarcel 34160163Smarcel#ifdef _KERNEL 35160163Smarcelstatic struct uwx_env uwx_env; 36160163Smarcel#define free(p) /* nullified */ 37160163Smarcel#define malloc(sz) ((sz == sizeof(uwx_env)) ? &uwx_env : NULL) 38160163Smarcel#endif 39160163Smarcel 40115013Smarcelalloc_cb uwx_allocate_cb = 0; 41115013Smarcelfree_cb uwx_free_cb = 0; 42115013Smarcel 43115013Smarcelint uwx_register_alloc_cb(alloc_cb alloc, free_cb free) 44115013Smarcel{ 45115013Smarcel uwx_allocate_cb = alloc; 46115013Smarcel uwx_free_cb = free; 47115013Smarcel return UWX_OK; 48115013Smarcel} 49115013Smarcel 50115013Smarcelint uwx_init_history(struct uwx_env *env) 51115013Smarcel{ 52115013Smarcel int i; 53115013Smarcel 54115013Smarcel if (env == 0) 55115013Smarcel return UWX_ERR_NOENV; 56115013Smarcel 57115013Smarcel for (i = 0; i < NSPECIALREG; i++) 58115013Smarcel env->history.special[i] = UWX_DISP_REG(i);; 59115013Smarcel for (i = 0; i < NPRESERVEDGR; i++) 60115013Smarcel env->history.gr[i] = UWX_DISP_REG(UWX_REG_GR(4+i)); 61115013Smarcel for (i = 0; i < NPRESERVEDBR; i++) 62115013Smarcel env->history.br[i] = UWX_DISP_REG(UWX_REG_BR(1+i)); 63115013Smarcel for (i = 0; i < 4; i++) 64115013Smarcel env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(2+i)); 65115013Smarcel for ( ; i < NPRESERVEDFR; i++) 66115013Smarcel env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(12+i)); 67115013Smarcel 68115013Smarcel return UWX_OK; 69115013Smarcel} 70115013Smarcel 71160157Smarcelint uwx_init_env(struct uwx_env *env, size_t total_size) 72160157Smarcel{ 73160157Smarcel int i; 74160157Smarcel struct uwx_str_pool *str_pool; 75160157Smarcel struct uwx_scoreboard *scoreboards; 76160157Smarcel 77160157Smarcel str_pool = (struct uwx_str_pool *)(env + 1); 78160157Smarcel scoreboards = (struct uwx_scoreboard *)(str_pool + 1); 79160157Smarcel 80160157Smarcel if (sizeof(struct uwx_env) + sizeof(struct uwx_str_pool) > total_size) 81160157Smarcel return UWX_ERR_NOMEM; 82160157Smarcel total_size -= sizeof(struct uwx_env) + sizeof(struct uwx_str_pool); 83160157Smarcel 84160157Smarcel env->context.valid_regs = 0; 85160157Smarcel env->context.valid_frs = 0; 86160157Smarcel for (i = 0; i < NSPECIALREG; i++) 87160157Smarcel env->context.special[i] = 0; 88160157Smarcel for (i = 0; i < NPRESERVEDGR; i++) 89160157Smarcel env->context.gr[i] = 0; 90160157Smarcel for (i = 0; i < NPRESERVEDBR; i++) 91160157Smarcel env->context.br[i] = 0; 92160157Smarcel for (i = 0; i < NPRESERVEDFR; i++) { 93160157Smarcel env->context.fr[i].part0 = 0; 94160157Smarcel env->context.fr[i].part1 = 0; 95160157Smarcel } 96160157Smarcel env->rstate = 0; 97160157Smarcel env->remapped_ip = 0; 98160157Smarcel env->function_offset = 0; 99160157Smarcel env->ptr_size = DWORDSZ; 100160157Smarcel env->uinfo_hdr = 0; 101160157Smarcel env->uinfo_end = 0; 102160157Smarcel env->code_start = 0; 103160157Smarcel env->text_base = 0; 104160157Smarcel (void)uwx_init_history(env); 105160157Smarcel if (uwx_allocate_cb != NULL) 106160157Smarcel env->allocate_cb = uwx_allocate_cb; 107160157Smarcel else 108160163Smarcel env->allocate_cb = NULL; 109160157Smarcel if (uwx_free_cb != NULL) 110160157Smarcel env->free_cb = uwx_free_cb; 111160157Smarcel else 112160163Smarcel env->free_cb = NULL; 113160157Smarcel env->free_scoreboards = 0; 114160157Smarcel env->used_scoreboards = 0; 115160157Smarcel env->labeled_scoreboards = 0; 116160157Smarcel (void)uwx_init_str_pool(env, str_pool); 117160157Smarcel env->module_name = 0; 118160157Smarcel env->function_name = 0; 119160157Smarcel env->cb_token = 0; 120160157Smarcel env->copyin = 0; 121160157Smarcel env->lookupip = 0; 122160157Smarcel env->remote = 0; 123160157Smarcel env->byte_swap = 0; 124160157Smarcel env->abi_context = 0; 125160157Smarcel env->nsbreg = NSBREG; 126160157Smarcel env->nscoreboards = 0; 127160157Smarcel env->on_heap = 0; 128160157Smarcel env->trace = 0; 129160157Smarcel TRACE_INIT 130160157Smarcel for (i = 0; total_size >= sizeof(struct uwx_scoreboard); i++) { 131160157Smarcel (void) uwx_prealloc_scoreboard(env, &scoreboards[i]); 132160157Smarcel total_size -= sizeof(struct uwx_scoreboard); 133160157Smarcel } 134160157Smarcel return UWX_OK; 135160157Smarcel} 136160157Smarcel 137160157Smarcelint uwx_set_nofr(struct uwx_env *env) 138160157Smarcel{ 139160157Smarcel if (env == 0) 140160157Smarcel return UWX_ERR_NOENV; 141160157Smarcel 142160157Smarcel env->nsbreg = NSBREG_NOFR; 143160157Smarcel return UWX_OK; 144160157Smarcel} 145160157Smarcel 146115013Smarcelstruct uwx_env *uwx_init() 147115013Smarcel{ 148115013Smarcel struct uwx_env *env; 149160157Smarcel size_t total_size; 150115013Smarcel 151160157Smarcel total_size = sizeof(struct uwx_env) + 152160157Smarcel sizeof(struct uwx_str_pool) + 153160157Smarcel NSCOREBOARDS * sizeof(struct uwx_scoreboard); 154160157Smarcel 155115013Smarcel if (uwx_allocate_cb == 0) 156160157Smarcel env = (struct uwx_env *) malloc(total_size); 157115013Smarcel else 158160157Smarcel env = (struct uwx_env *) (*uwx_allocate_cb)(total_size); 159115013Smarcel if (env != 0) { 160160157Smarcel uwx_init_env(env, total_size); 161160157Smarcel env->on_heap = 1; 162115013Smarcel } 163115013Smarcel return env; 164115013Smarcel} 165115013Smarcel 166115013Smarcelint uwx_set_remote(struct uwx_env *env, int is_big_endian_target) 167115013Smarcel{ 168115013Smarcel int is_big_endian_host; 169115013Smarcel char *p; 170115013Smarcel 171115013Smarcel if (env == 0) 172115013Smarcel return UWX_ERR_NOENV; 173115013Smarcel 174115013Smarcel env->remote = 1; 175115013Smarcel 176115013Smarcel is_big_endian_host = 1; 177115013Smarcel p = (char *)&is_big_endian_host; 178115013Smarcel *p = 0; 179115013Smarcel if (is_big_endian_target == is_big_endian_host) 180115013Smarcel env->byte_swap = 0; 181115013Smarcel else 182115013Smarcel env->byte_swap = 1; 183115013Smarcel 184115013Smarcel return UWX_OK; 185115013Smarcel} 186115013Smarcel 187115013Smarcelint uwx_register_callbacks( 188115013Smarcel struct uwx_env *env, 189115013Smarcel intptr_t tok, 190115013Smarcel copyin_cb copyin, 191115013Smarcel lookupip_cb lookupip) 192115013Smarcel{ 193115013Smarcel if (env == 0) 194115013Smarcel return UWX_ERR_NOENV; 195115013Smarcel env->cb_token = tok; 196115013Smarcel env->copyin = copyin; 197115013Smarcel env->lookupip = lookupip; 198115013Smarcel return UWX_OK; 199115013Smarcel} 200115013Smarcel 201115013Smarcelint uwx_get_abi_context_code(struct uwx_env *env) 202115013Smarcel{ 203115013Smarcel if (env == 0) 204115013Smarcel return UWX_ERR_NOENV; 205115013Smarcel return env->abi_context; 206115013Smarcel} 207115013Smarcel 208115013Smarcelint uwx_free(struct uwx_env *env) 209115013Smarcel{ 210115013Smarcel if (env != 0) { 211115013Smarcel uwx_free_scoreboards(env); 212115013Smarcel uwx_free_str_pool(env); 213160157Smarcel if (env->on_heap) { 214160157Smarcel if (env->free_cb == 0) 215160157Smarcel free((void *)env); 216160157Smarcel else 217160157Smarcel (*env->free_cb)((void *)env); 218160157Smarcel } 219115013Smarcel } 220115013Smarcel return UWX_OK; 221115013Smarcel} 222