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