// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: tm_blaze_ext.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
* Copyright (C) 1991, 2001 Sun Microsystems, Inc.
#pragma ident "@(#)1.4 01/11/06 tm_blaze_ext.cc"
* Copyright (c) 1989, Sun Microsystems, Inc. All Rights Reserved. Sun
* considers its source code as an unpublished, proprietary trade secret, and
* it is available only under strict license provisions. This copyright
* notice is placed here only to protect Sun in the event the source is
* deemed a published work. Disassembly, decompilation, or other means of
* reducing the object code to human readable form is prohibited by the
* license agreement under which this code is provided to the user or company
* in possession of this copy
* RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
* Government is subject to restrictions as set forth in subparagraph
* (c) (1) (ii) of the Rights in Technical Data and Computer Software clause
* at DFARS 52.227-7013 and in similar clauses in the FAR and NASA FAR
#include "blaze_globals.h"
typedef void* TM_OPAQUE_DATA
;
//////////////////////////////////////////////////////////
void *TM_get_blaze_data (void * handle
)
return ((Ldm
*)handle
)->blaze_data
;
//////////////////////////////////////////////////////////
void *TM_get_client_data (void * handle
)
Ldm
*pldm
= (Ldm
*)handle
;
return pldm
->client_data
;
//////////////////////////////////////////////////////////
void *TM_get_asi_client_data (void * handle
)
Ldm
*pldm
= (Ldm
*)handle
;
return pldm
->asi_client_data
;
//////////////////////////////////////////////////////////
char *TM_get_name (void * handle
)
Ldm
*pldm
= (Ldm
*)handle
;
//////////////////////////////////////////////////////////
for (pnode
=head_ldm
; pnode
!=NULL
; pnode
=pnode
->Next()) {
Ldm
*pldm
= pnode
->GetData();
if (pldm
->type
== TM_TYPE_EXT_DEVICE
) {
//////////////////////////////////////////////////////////
tracemod_t
*TM_get_mod (void * handle
)
LdmNode
*pnode
= (LdmNode
*) handle
;
return pnode
->GetData ();
//////////////////////////////////////////////////////////
void *TM_getnext_ext (void * handle
, uint32_t mode
)
LdmNode
*pnode
= (LdmNode
*)handle
;
pnode
= (LdmNode
*)head_spec_ldm
;
for (;pnode
;pnode
= pnode
->Next()) {
pldm
= pnode
->GetData ();
//////////////////////////////////////////////////////////
// Internal API routine :
// Is used to bind a MODULE with specific opaque data
// consealed inside of other BLAZE subsystem (SCHIZO for instance)
void TM_include_ext (void * io_module
, void *local_handle
)
Ldm
*pldm
= (Ldm
*)io_module
;
pldm
->blaze_data
= local_handle
;
if (pldm
->mode
& TM_EXT_IO
) {
if ((pldm
->io_ld_action
== NULL
) && (pldm
->io_mmi_ld_action
== NULL
)) {
ui
->error("extension <%s> doesn't have LOAD op handler\n", pldm
->name
);
if ((pldm
->io_st_action
== NULL
) && (pldm
->io_mmi_st_action
== NULL
)) {
ui
->error("extension <%s> doesn't have STORE op handler\n", pldm
->name
);
//////////////////////////////////////////////////////////
fn_misc
TM_get_ld_action_ext (void *io_module
)
Ldm
*pldm
= (Ldm
*)io_module
;
return pldm
->io_ld_action
;
//////////////////////////////////////////////////////////
fn_misc
TM_get_st_action_ext (void *io_module
)
Ldm
*pldm
= (Ldm
*)io_module
;
return pldm
->io_st_action
;
//////////////////////////////////////////////////////////
uint32_t TM_is_ready_ext (void * /* io_module */)
return 1; // always ready
//////////////////////////////////////////////////////////
fn_misc
TM_get_st_mmi_action_ext (void *io_module
)
Ldm
*pldm
= (Ldm
*)io_module
;
return pldm
->io_mmi_st_action
;
//////////////////////////////////////////////////////////
fn_misc
TM_get_ld_mmi_action_ext (void *io_module
)
Ldm
*pldm
= (Ldm
*)io_module
;
return pldm
->io_mmi_ld_action
;
//////////////////////////////////////////////////////////
// This routine registers module object
// without existing *.so file.
// Another words an entire NAME RELATED functionality
// can be bound with this PSEUDOMODULE
tracemod_t
*TM_self_pseudomod_spec (tracemod_t
*main_mod
, const char* mod_name
,
const char *help
, TM_OPAQUE_DATA client_data
)
if (SYSTEM_is_running()) {
ui
->fatal("TM_self_pseudomod_spec called while blaze running\n");
pldm
= ldm_add_spec ((char*)mod_name
, NULL
);
pldm
->argv
= (char**) calloc (1, sizeof(char*));
pldm
->argv
[0] = strdup(mod_name
);
pldm
->help
= strdup(help
);
pldm
->client_data
= client_data
;
//////////////////////////////////////////////////////////
void TM_register_io_action (tracemod_t
*mod
, fn_misc ld_action
, fn_misc st_action
)
mod
->io_ld_action
= ld_action
;
mod
->io_st_action
= st_action
;
//////////////////////////////////////////////////////////
void TM_register_io_mmi_action (tracemod_t
*mod
, fn_misc ld_action
, fn_misc st_action
)
mod
->io_mmi_ld_action
= ld_action
;
mod
->io_mmi_st_action
= st_action
;
//////////////////////////////////////////////////////////
void TM_register_client_data (tracemod_t
*mod
, TM_OPAQUE_DATA d
)
void TM_register_asi_client_data (tracemod_t
*mod
, TM_OPAQUE_DATA d
)
mod
->asi_client_data
= d
;
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
ldm_time_intf
*head_time_intf
;
mutex_init(&time_intf_lock
, USYNC_THREAD
, NULL
);
//////////////////////////////////////////////////////////
void TM_enable_time_intf (void *intf
, uint64_t how_often
)
ldm_time_intf
*time_intf
= (ldm_time_intf
*)intf
;
time_intf
->threshold
= how_often
;
time_intf
->cnt
= how_often
;
time_intf
->status
= TM_INTF_STATUS_ENABLED
;
//////////////////////////////////////////////////////////
void TM_disable_time_intf (void *intf
)
ldm_time_intf
*time_intf
= (ldm_time_intf
*)intf
;
time_intf
->status
= TM_INTF_STATUS_DISABLED
;
//////////////////////////////////////////////////////////
void *TM_register_time_intf (tracemod_t
*mod
, TM_OPAQUE_DATA d
, fn_event_cycle handler
, uint64_t how_often
)
ldm_time_intf
*time_intf
= (ldm_time_intf
*)calloc (1, sizeof(ldm_time_intf
));
time_intf
->threshold
= how_often
;
time_intf
->cnt
= how_often
;
time_intf
->event_handler
= handler
;
time_intf
->client_data
= d
;
time_intf
->self
= time_intf
;
time_intf
->status
= TM_INTF_STATUS_ENABLED
;
mutex_lock(&time_intf_lock
);
time_intf
->next
= head_time_intf
;
head_time_intf
= time_intf
;
mutex_unlock(&time_intf_lock
);
//////////////////////////////////////////////////////////
void TM_unregister_time_intf (tracemod_t
*mod
, void *intf
)
ldm_time_intf
*time_intf
, **prev
;
mutex_lock(&time_intf_lock
);
for (prev
= &head_time_intf
; (time_intf
= *prev
) != NULL
; ) {
if (!intf
&& time_intf
->owner
== mod
) {
else if (time_intf
== intf
) {
mutex_unlock(&time_intf_lock
);
//////////////////////////////////////////////////////////
void TM_tick_ext (int incr
)
ldm_time_intf
*time_intf
;
ldm_time_intf
*time_intf_copy
= NULL
;
// make a copy of callbacks while the lock is held
mutex_lock(&time_intf_lock
);
for (time_intf
= head_time_intf
; time_intf
; time_intf
= time_intf
->next
) {
if (time_intf
->status
== TM_INTF_STATUS_ENABLED
) {
time_intf
->abs_cnt
+= incr
;
if ((time_intf
->cnt
-= incr
) <= 0) {
// the owner is always ready to accept the tick callback
copy
= (ldm_time_intf
*) alloca(sizeof(ldm_time_intf
));
copy
->next
= time_intf_copy
;
time_intf
->cnt
= time_intf
->threshold
;
mutex_unlock(&time_intf_lock
);
// now call the handlers without a lock
while ((time_intf
= time_intf_copy
) != NULL
) {
time_intf_copy
= time_intf
->next
;
time_intf
->event_handler(time_intf
->client_data
, time_intf
->abs_cnt
);