// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: tm_cpu_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"
#include "cpu_interface.h"
typedef void* TM_OPAQUE_DATA
;
static tracemod_t
*pTm_ASI_ext
= NULL
;
// say there are 1024 possible asi's (including room for future growth).
// we declare an array of modules, indexed by the ASI, for quick access
static const int N_ASI
= 1024;
static tracemod_t
*asi_modules
[N_ASI
];
static int asi_modules_cnt
= 0;
static tracemod_t
* asi2module
[N_ASI
] = {0};
static mmi_ld_asi_action asi2ldhandler
[N_ASI
] = {0};
static mmi_st_asi_action asi2sthandler
[N_ASI
] = {0};
/////////////////////////////////////////////////////////////
bool_t
add_asi_module (tracemod_t
* mod
, uint32_t asi
, mmi_ld_asi_action ld_handler
, mmi_st_asi_action st_handler
)
if (asi2module
[asi
] != NULL
) {
if (mod
!= asi2module
[asi
]) {
ui
->error("loading asi module %s: a module (%s) for asi %d is already loaded\n",
mod
->name
, asi2module
[asi
]->name
, asi
);
for (ii
= 0; ii
< asi_modules_cnt
; ii
++) {
if (asi_modules
[ii
] == mod
) {
// module is already loaded, but for some other ASI
if (ii
== asi_modules_cnt
) {
if (asi_modules_cnt
>= N_ASI
) {
ui
->error("loading asi module %s: too many ASI modules (%d) already loaded\n",
asi_modules
[asi_modules_cnt
++] = mod
;
asi2ldhandler
[asi
] = ld_handler
;
asi2sthandler
[asi
] = st_handler
;
/////////////////////////////////////////////////////////////
// TODO : to make it more accurate
// Assume we have CPU (CPUM) and DEVICE module (DEVM) responsible for some extra ASI handling.
// 1. DEVM registers ASI handler with "mmi_register_asi...." with BLAZE
// 2. RS2BLAZE "glue code" registers it's own ASI callback with CPUM
// 3. When CPUM executes say LD with unsopported ASI it INVOKES callback (see #2)
// 4. This callback in turn invokes TM_execute_load/store_asi (see below).
TM_execute_load_asi (uint32_t asi
, uint64_t vaddr
, uint64_t *buf
, int size
, uint32_t cpuid
)
tracemod_t
* mod
= asi2module
[asi
];
if (mod
== NULL
) return -1;
mmi_ld_asi_action ld_handler
= asi2ldhandler
[asi
];
if (ld_handler
== NULL
) {
return ld_handler(TM_get_asi_client_data((void*)mod
), asi
, vaddr
, buf
, size
, cpuid
);
/////////////////////////////////////////////////////////////
TM_execute_store_asi (uint32_t asi
, uint64_t vaddr
, uint64_t *buf
, int size
, uint32_t cpuid
)
tracemod_t
* mod
= asi2module
[asi
];
if (mod
== NULL
) return -1;
mmi_st_asi_action st_handler
= asi2sthandler
[asi
];
if (st_handler
== NULL
) {
return st_handler(TM_get_asi_client_data((void*)mod
), asi
, vaddr
, *buf
, size
, cpuid
);