Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / tracemod / tm_blaze_ext.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: tm_blaze_ext.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/*
22 * Copyright (C) 1991, 2001 Sun Microsystems, Inc.
23 * All rights reserved.
24 */
25#pragma ident "@(#)1.4 01/11/06 tm_blaze_ext.cc"
26
27/*
28 * Copyright (c) 1989, Sun Microsystems, Inc. All Rights Reserved. Sun
29 * considers its source code as an unpublished, proprietary trade secret, and
30 * it is available only under strict license provisions. This copyright
31 * notice is placed here only to protect Sun in the event the source is
32 * deemed a published work. Disassembly, decompilation, or other means of
33 * reducing the object code to human readable form is prohibited by the
34 * license agreement under which this code is provided to the user or company
35 * in possession of this copy
36 *
37 * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
38 * Government is subject to restrictions as set forth in subparagraph
39 * (c) (1) (ii) of the Rights in Technical Data and Computer Software clause
40 * at DFARS 52.227-7013 and in similar clauses in the FAR and NASA FAR
41 * Supplement
42 */
43
44#include <sys/types.h>
45#include <alloca.h>
46#include <assert.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <synch.h>
51#include <dlfcn.h>
52
53#include "types.h"
54#include "blaze_globals.h"
55#include "system.h"
56
57typedef void* TM_OPAQUE_DATA;
58#include "tracemod.h"
59
60#include "ui.h"
61#include "tm_impl.h"
62
63//////////////////////////////////////////////////////////
64
65void *TM_get_blaze_data (void * handle)
66{
67 return ((Ldm*)handle)->blaze_data;
68}
69
70//////////////////////////////////////////////////////////
71
72void *TM_get_client_data (void * handle)
73{
74 Ldm *pldm = (Ldm*)handle;
75 return pldm->client_data;
76}
77
78//////////////////////////////////////////////////////////
79
80void *TM_get_asi_client_data (void * handle)
81{
82 Ldm *pldm = (Ldm*)handle;
83 return pldm->asi_client_data;
84}
85
86//////////////////////////////////////////////////////////
87
88
89char *TM_get_name (void * handle)
90{
91 Ldm *pldm = (Ldm*)handle;
92 return pldm->name;
93}
94
95//////////////////////////////////////////////////////////
96
97bool_t TM_is_device ()
98{
99 LdmNode * pnode;
100 for (pnode=head_ldm; pnode!=NULL; pnode=pnode->Next()) {
101 Ldm *pldm = pnode->GetData();
102 if (pldm->type == TM_TYPE_EXT_DEVICE) {
103 return TRUE;
104 }
105 }
106 return FALSE;
107}
108
109//////////////////////////////////////////////////////////
110
111tracemod_t *TM_get_mod (void * handle)
112{
113
114 LdmNode *pnode = (LdmNode*) handle;
115 return pnode->GetData ();
116}
117
118//////////////////////////////////////////////////////////
119
120void *TM_getnext_ext (void * handle, uint32_t mode)
121{
122 LdmNode *pnode = (LdmNode*)handle;
123 Ldm *pldm;
124
125 if (pnode == NULL) {
126 pnode = (LdmNode*)head_spec_ldm;
127 }
128 else {
129 pnode = pnode->Next();
130 }
131
132 for (;pnode;pnode = pnode->Next()) {
133 pldm = pnode->GetData ();
134 if (pldm->mode & mode) {
135 return pnode;
136 }
137 }
138 return NULL;
139}
140
141//////////////////////////////////////////////////////////
142// Internal API routine :
143// Is used to bind a MODULE with specific opaque data
144// consealed inside of other BLAZE subsystem (SCHIZO for instance)
145//
146void TM_include_ext (void * io_module, void *local_handle)
147{
148 Ldm *pldm = (Ldm*)io_module;
149 pldm->blaze_data = local_handle;
150 if (pldm->mode & TM_EXT_IO) {
151 if ((pldm->io_ld_action == NULL) && (pldm->io_mmi_ld_action == NULL)) {
152 ui->error("extension <%s> doesn't have LOAD op handler\n", pldm->name);
153 }
154 if ((pldm->io_st_action == NULL) && (pldm->io_mmi_st_action == NULL)) {
155 ui->error("extension <%s> doesn't have STORE op handler\n", pldm->name);
156 }
157 }
158}
159
160//////////////////////////////////////////////////////////
161
162fn_misc TM_get_ld_action_ext (void *io_module)
163{
164 Ldm *pldm = (Ldm*)io_module;
165 return pldm->io_ld_action;
166}
167
168//////////////////////////////////////////////////////////
169
170fn_misc TM_get_st_action_ext (void *io_module)
171{
172 Ldm *pldm = (Ldm*)io_module;
173 return pldm->io_st_action;
174}
175
176//////////////////////////////////////////////////////////
177
178uint32_t TM_is_ready_ext (void * /* io_module */)
179{
180 return 1; // always ready
181}
182
183//////////////////////////////////////////////////////////
184
185fn_misc TM_get_st_mmi_action_ext (void *io_module)
186{
187 Ldm *pldm = (Ldm*)io_module;
188 return pldm->io_mmi_st_action;
189}
190
191//////////////////////////////////////////////////////////
192
193fn_misc TM_get_ld_mmi_action_ext (void *io_module)
194{
195 Ldm *pldm = (Ldm*)io_module;
196 return pldm->io_mmi_ld_action;
197}
198
199
200//////////////////////////////////////////////////////////
201
202// EXTERNAL
203// ---------
204// This routine registers module object
205// without existing *.so file.
206// Another words an entire NAME RELATED functionality
207// can be bound with this PSEUDOMODULE
208//
209tracemod_t *TM_self_pseudomod_spec (tracemod_t *main_mod, const char* mod_name,
210 const char *help, TM_OPAQUE_DATA client_data)
211{
212 Ldm *pldm = NULL;
213
214 if (SYSTEM_is_running()) {
215 ui->fatal("TM_self_pseudomod_spec called while blaze running\n");
216 exit (1);
217 }
218 pldm = ldm_add_spec ((char*)mod_name, NULL);
219 if (pldm == NULL) {
220 return NULL;
221 }
222 pldm->argc = 1;
223 pldm->argv = (char**) calloc (1, sizeof(char*));
224 pldm->argv[0] = strdup(mod_name);
225 pldm->so_handle = 0;
226 pldm->valid = TRUE;
227 pldm->help = strdup(help);
228 pldm->client_data = client_data;
229 pldm->parent = main_mod;
230 return pldm;
231}
232
233//////////////////////////////////////////////////////////
234// EXTERNAL
235// --------
236
237void TM_register_io_action (tracemod_t *mod, fn_misc ld_action, fn_misc st_action)
238{
239 mod->io_ld_action = ld_action;
240 mod->io_st_action = st_action;
241}
242
243//////////////////////////////////////////////////////////
244
245void TM_register_io_mmi_action (tracemod_t *mod, fn_misc ld_action, fn_misc st_action)
246{
247 mod->io_mmi_ld_action = ld_action;
248 mod->io_mmi_st_action = st_action;
249}
250
251//////////////////////////////////////////////////////////
252
253void TM_register_client_data (tracemod_t *mod, TM_OPAQUE_DATA d)
254{
255 mod->client_data = d;
256}
257
258void TM_register_asi_client_data (tracemod_t *mod, TM_OPAQUE_DATA d)
259{
260 mod->asi_client_data = d;
261}
262
263
264//////////////////////////////////////////////////////////
265// time_intf
266//////////////////////////////////////////////////////////
267
268mutex_t time_intf_lock;
269ldm_time_intf *head_time_intf;
270
271void ldm_tick_ext_init()
272{
273 mutex_init(&time_intf_lock, USYNC_THREAD, NULL);
274}
275
276//////////////////////////////////////////////////////////
277
278void TM_enable_time_intf (void *intf, uint64_t how_often)
279{
280 ldm_time_intf *time_intf = (ldm_time_intf*)intf;
281 time_intf->threshold = how_often;
282 time_intf->cnt = how_often;
283 time_intf->status = TM_INTF_STATUS_ENABLED;
284}
285
286//////////////////////////////////////////////////////////
287
288void TM_disable_time_intf (void *intf)
289{
290 ldm_time_intf *time_intf = (ldm_time_intf*)intf;
291 time_intf->status = TM_INTF_STATUS_DISABLED;
292}
293
294
295//////////////////////////////////////////////////////////
296
297void *TM_register_time_intf (tracemod_t *mod, TM_OPAQUE_DATA d, fn_event_cycle handler, uint64_t how_often)
298{
299
300 ldm_time_intf *time_intf = (ldm_time_intf*)calloc (1, sizeof(ldm_time_intf));
301 assert(time_intf);
302
303 time_intf->threshold = how_often;
304 time_intf->cnt = how_often;
305 time_intf->event_handler = handler;
306 time_intf->client_data = d;
307 time_intf->self = time_intf;
308 time_intf->owner = mod;
309 time_intf->status = TM_INTF_STATUS_ENABLED;
310
311 mutex_lock(&time_intf_lock);
312 time_intf->next = head_time_intf;
313 head_time_intf = time_intf;
314 mutex_unlock(&time_intf_lock);
315
316 return time_intf;
317}
318
319//////////////////////////////////////////////////////////
320
321void TM_unregister_time_intf (tracemod_t *mod, void *intf)
322{
323 ldm_time_intf *time_intf, **prev;
324
325 mutex_lock(&time_intf_lock);
326 for (prev = &head_time_intf; (time_intf = *prev) != NULL; ) {
327 if (!intf && time_intf->owner == mod) {
328 *prev = time_intf->next;
329 free ((void*)time_intf);
330 }
331 else if (time_intf == intf) {
332 *prev = time_intf->next;
333 free ((void*)time_intf);
334 break;
335 }
336 else
337 prev = &time_intf->next;
338 }
339 mutex_unlock(&time_intf_lock);
340}
341
342//////////////////////////////////////////////////////////
343
344void TM_tick_ext (int incr)
345{
346 ldm_time_intf *copy;
347 ldm_time_intf *time_intf;
348 ldm_time_intf *time_intf_copy = NULL;
349
350 // make a copy of callbacks while the lock is held
351 mutex_lock(&time_intf_lock);
352 for (time_intf = head_time_intf; time_intf; time_intf = time_intf->next) {
353 if (time_intf->status == TM_INTF_STATUS_ENABLED) {
354 time_intf->abs_cnt += incr;
355 if ((time_intf->cnt -= incr) <= 0) {
356 // the owner is always ready to accept the tick callback
357 copy = (ldm_time_intf *) alloca(sizeof(ldm_time_intf));
358 assert(copy);
359 *copy = *time_intf;
360 copy->next = time_intf_copy;
361 time_intf_copy = copy;
362 time_intf->cnt = time_intf->threshold;
363 }
364 }
365 }
366 mutex_unlock(&time_intf_lock);
367
368 // now call the handlers without a lock
369 while ((time_intf = time_intf_copy) != NULL) {
370 time_intf_copy = time_intf->next;
371 time_intf->event_handler(time_intf->client_data, time_intf->abs_cnt);
372 }
373}
374
375