uwx_env.c revision 256281
1264790Sbapt/*
2264790SbaptCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
3272955SrodrigcPermission is hereby granted, free of charge, to any person
4264790Sbaptobtaining a copy of this software and associated documentation
5264790Sbaptfiles (the "Software"), to deal in the Software without
6264790Sbaptrestriction, including without limitation the rights to use,
7264790Sbaptcopy, modify, merge, publish, distribute, sublicense, and/or sell
8264790Sbaptcopies of the Software, and to permit persons to whom the
9264790SbaptSoftware is furnished to do so, subject to the following
10264790Sbaptconditions:
11264790Sbapt
12264790SbaptThe above copyright notice and this permission notice shall be
13264790Sbaptincluded in all copies or substantial portions of the Software.
14264790Sbapt
15264790SbaptTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16264790SbaptEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17264790SbaptOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18264790SbaptNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19264790SbaptHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20264790SbaptWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21264790SbaptFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22264790SbaptOTHER DEALINGS IN THE SOFTWARE.
23264790Sbapt*/
24264790Sbapt
25264790Sbapt#ifndef _KERNEL
26264790Sbapt#include <stdlib.h>
27264790Sbapt#endif
28264790Sbapt
29264790Sbapt#include "uwx_env.h"
30264790Sbapt#include "uwx_scoreboard.h"
31264790Sbapt#include "uwx_str.h"
32264790Sbapt#include "uwx_trace.h"
33264790Sbapt
34264790Sbapt#ifdef _KERNEL
35264790Sbaptstatic struct uwx_env uwx_env;
36264790Sbapt#define	free(p)		/* nullified */
37264790Sbapt#define	malloc(sz)	((sz == sizeof(uwx_env)) ? &uwx_env : NULL)
38264790Sbapt#endif
39264790Sbapt
40264790Sbaptalloc_cb uwx_allocate_cb = 0;
41264790Sbaptfree_cb uwx_free_cb = 0;
42264790Sbapt
43264790Sbaptint uwx_register_alloc_cb(alloc_cb alloc, free_cb free)
44264790Sbapt{
45264790Sbapt    uwx_allocate_cb = alloc;
46264790Sbapt    uwx_free_cb = free;
47264790Sbapt    return UWX_OK;
48264790Sbapt}
49264790Sbapt
50264790Sbaptint uwx_init_history(struct uwx_env *env)
51264790Sbapt{
52264790Sbapt    int i;
53264790Sbapt
54264790Sbapt    if (env == 0)
55264790Sbapt	return UWX_ERR_NOENV;
56264790Sbapt
57264790Sbapt    for (i = 0; i < NSPECIALREG; i++)
58264790Sbapt	env->history.special[i] = UWX_DISP_REG(i);;
59264790Sbapt    for (i = 0; i < NPRESERVEDGR; i++)
60264790Sbapt	env->history.gr[i] = UWX_DISP_REG(UWX_REG_GR(4+i));
61264790Sbapt    for (i = 0; i < NPRESERVEDBR; i++)
62264790Sbapt	env->history.br[i] = UWX_DISP_REG(UWX_REG_BR(1+i));
63264790Sbapt    for (i = 0; i < 4; i++)
64264790Sbapt	env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(2+i));
65264790Sbapt    for ( ; i < NPRESERVEDFR; i++)
66264790Sbapt	env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(12+i));
67264790Sbapt
68264790Sbapt    return UWX_OK;
69264790Sbapt}
70264790Sbapt
71264790Sbaptint uwx_init_env(struct uwx_env *env, size_t total_size)
72264790Sbapt{
73264790Sbapt    int i;
74264790Sbapt    struct uwx_str_pool *str_pool;
75264790Sbapt    struct uwx_scoreboard *scoreboards;
76264790Sbapt
77264790Sbapt    str_pool = (struct uwx_str_pool *)(env + 1);
78264790Sbapt    scoreboards = (struct uwx_scoreboard *)(str_pool + 1);
79264790Sbapt
80264790Sbapt    if (sizeof(struct uwx_env) + sizeof(struct uwx_str_pool) > total_size)
81264790Sbapt	return UWX_ERR_NOMEM;
82264790Sbapt    total_size -= sizeof(struct uwx_env) + sizeof(struct uwx_str_pool);
83264790Sbapt
84264790Sbapt    env->context.valid_regs = 0;
85264790Sbapt    env->context.valid_frs = 0;
86264790Sbapt    for (i = 0; i < NSPECIALREG; i++)
87264790Sbapt	env->context.special[i] = 0;
88264790Sbapt    for (i = 0; i < NPRESERVEDGR; i++)
89264790Sbapt	env->context.gr[i] = 0;
90264790Sbapt    for (i = 0; i < NPRESERVEDBR; i++)
91264790Sbapt	env->context.br[i] = 0;
92264790Sbapt    for (i = 0; i < NPRESERVEDFR; i++) {
93264790Sbapt	env->context.fr[i].part0 = 0;
94264790Sbapt	env->context.fr[i].part1 = 0;
95264790Sbapt    }
96264790Sbapt    env->rstate = 0;
97264790Sbapt    env->remapped_ip = 0;
98264790Sbapt    env->function_offset = 0;
99264790Sbapt    env->ptr_size = DWORDSZ;
100264790Sbapt    env->uinfo_hdr = 0;
101264790Sbapt    env->uinfo_end = 0;
102264790Sbapt    env->code_start = 0;
103264790Sbapt    env->text_base = 0;
104264790Sbapt    (void)uwx_init_history(env);
105264790Sbapt    if (uwx_allocate_cb != NULL)
106264790Sbapt	env->allocate_cb = uwx_allocate_cb;
107264790Sbapt    else
108264790Sbapt	env->allocate_cb = NULL;
109264790Sbapt    if (uwx_free_cb != NULL)
110264790Sbapt	env->free_cb = uwx_free_cb;
111264790Sbapt    else
112264790Sbapt	env->free_cb = NULL;
113264790Sbapt    env->free_scoreboards = 0;
114264790Sbapt    env->used_scoreboards = 0;
115264790Sbapt    env->labeled_scoreboards = 0;
116264790Sbapt    (void)uwx_init_str_pool(env, str_pool);
117264790Sbapt    env->module_name = 0;
118264790Sbapt    env->function_name = 0;
119264790Sbapt    env->cb_token = 0;
120264790Sbapt    env->copyin = 0;
121264790Sbapt    env->lookupip = 0;
122264790Sbapt    env->remote = 0;
123264790Sbapt    env->byte_swap = 0;
124264790Sbapt    env->abi_context = 0;
125264790Sbapt    env->nsbreg = NSBREG;
126264790Sbapt    env->nscoreboards = 0;
127264790Sbapt    env->on_heap = 0;
128264790Sbapt    env->trace = 0;
129264790Sbapt    TRACE_INIT
130264790Sbapt    for (i = 0; total_size >= sizeof(struct uwx_scoreboard); i++) {
131264790Sbapt	(void) uwx_prealloc_scoreboard(env, &scoreboards[i]);
132264790Sbapt	total_size -= sizeof(struct uwx_scoreboard);
133264790Sbapt    }
134264790Sbapt    return UWX_OK;
135264790Sbapt}
136264790Sbapt
137264790Sbaptint uwx_set_nofr(struct uwx_env *env)
138264790Sbapt{
139264790Sbapt    if (env == 0)
140264790Sbapt	return UWX_ERR_NOENV;
141264790Sbapt
142264790Sbapt    env->nsbreg = NSBREG_NOFR;
143264790Sbapt    return UWX_OK;
144264790Sbapt}
145264790Sbapt
146264790Sbaptstruct uwx_env *uwx_init()
147264790Sbapt{
148264790Sbapt    struct uwx_env *env;
149264790Sbapt    size_t total_size;
150264790Sbapt
151264790Sbapt    total_size = sizeof(struct uwx_env) +
152264790Sbapt		    sizeof(struct uwx_str_pool) +
153264790Sbapt			NSCOREBOARDS * sizeof(struct uwx_scoreboard);
154264790Sbapt
155264790Sbapt    if (uwx_allocate_cb == 0)
156264790Sbapt	env = (struct uwx_env *) malloc(total_size);
157264790Sbapt    else
158264790Sbapt	env = (struct uwx_env *) (*uwx_allocate_cb)(total_size);
159264790Sbapt    if (env != 0) {
160264790Sbapt	uwx_init_env(env, total_size);
161264790Sbapt	env->on_heap = 1;
162264790Sbapt    }
163264790Sbapt    return env;
164264790Sbapt}
165264790Sbapt
166264790Sbaptint uwx_set_remote(struct uwx_env *env, int is_big_endian_target)
167264790Sbapt{
168264790Sbapt    int is_big_endian_host;
169264790Sbapt    char *p;
170264790Sbapt
171264790Sbapt    if (env == 0)
172264790Sbapt	return UWX_ERR_NOENV;
173264790Sbapt
174264790Sbapt    env->remote = 1;
175264790Sbapt
176264790Sbapt    is_big_endian_host = 1;
177264790Sbapt    p = (char *)&is_big_endian_host;
178264790Sbapt    *p = 0;
179264790Sbapt    if (is_big_endian_target == is_big_endian_host)
180264790Sbapt	env->byte_swap = 0;
181264790Sbapt    else
182264790Sbapt	env->byte_swap = 1;
183264790Sbapt
184264790Sbapt    return UWX_OK;
185264790Sbapt}
186264790Sbapt
187264790Sbaptint uwx_register_callbacks(
188264790Sbapt    struct uwx_env *env,
189264790Sbapt    intptr_t tok,
190264790Sbapt    copyin_cb copyin,
191264790Sbapt    lookupip_cb lookupip)
192264790Sbapt{
193264790Sbapt    if (env == 0)
194264790Sbapt	return UWX_ERR_NOENV;
195264790Sbapt    env->cb_token = tok;
196264790Sbapt    env->copyin = copyin;
197264790Sbapt    env->lookupip = lookupip;
198272955Srodrigc    return UWX_OK;
199272955Srodrigc}
200272955Srodrigc
201272955Srodrigcint uwx_get_abi_context_code(struct uwx_env *env)
202272955Srodrigc{
203264790Sbapt    if (env == 0)
204264790Sbapt	return UWX_ERR_NOENV;
205264790Sbapt    return env->abi_context;
206264790Sbapt}
207264790Sbapt
208264790Sbaptint uwx_free(struct uwx_env *env)
209264790Sbapt{
210264790Sbapt    if (env != 0) {
211264790Sbapt	uwx_free_scoreboards(env);
212264790Sbapt	uwx_free_str_pool(env);
213264790Sbapt	if (env->on_heap) {
214264790Sbapt	    if (env->free_cb == 0)
215264790Sbapt		free((void *)env);
216264790Sbapt	    else
217264790Sbapt		(*env->free_cb)((void *)env);
218264790Sbapt	}
219264790Sbapt    }
220264790Sbapt    return UWX_OK;
221264790Sbapt}
222264790Sbapt