* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: magictraps.c
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)magictraps.c 1.5 06/10/27 SMI"
#include "tsparcv9internal.h"
#if ENABLE_MAGIC_TRAPS /* { */
pabcopy(simcpu_t
*sp
, uint64_t pasrc
, uint64_t padst
, uint64_t size
)
config_proc_t
*config_procp
;
config_addr_t
*capsrc
, *capdst
;
uint8_t *srcbufp
, *dstbufp
;
DBG( lprintf(sp
->gid
, "pabcopy(0x%llx, 0x%llx, 0x%llx)\n",
config_procp
= sp
->config_procp
;
domainp
= config_procp
->domainp
;
capsrc
= find_domain_address(domainp
, pasrc
);
EXEC_WARNING(("@ pc=0x%llx : simbcopy: src address not valid",
/* try and get the buffer pointer */
extent
= capsrc
->config_devp
->dev_typep
->dev_cacheable(capsrc
, DA_Load
,
pasrc
-capsrc
->baseaddr
, &srcbufp
);
EXEC_WARNING(("@ pc=0x%llx : pabcopy: src not large enough",
capdst
= find_domain_address(domainp
, padst
);
EXEC_WARNING(("@ pc=0x%llx : pabcopy: dest address not valid",
/* try and get the buffer pointer */
extent
= capdst
->config_devp
->dev_typep
->dev_cacheable(capdst
, DA_Store
,
padst
-capdst
->baseaddr
, &dstbufp
);
EXEC_WARNING(("@ pc=0x%llx : pabcopy: dest not large enough",
bcopy(srcbufp
, dstbufp
, size
);
* Called from a trap instruction implementation if a trap falls
* into the magic trap number range - see the macro SS_MAGIC_TRAP().
* Returns true to indicate the magic trap was actioned, false
* otherwise. Typically, the call sequence is:
* if (SS_MAGIC_TRAP(sp, tt)) {
bool_t
ss_magic_trap(simcpu_t
* sp
, uint32_t tt
)
if (!options
.magic_traps
)
v9p
= (sparcv9_cpu_t
*)(sp
->specificp
);
if (v9p
->state
== V9_User
)
EXEC_WARNING(("Magic trap 0x%x: compiled with NDEBUG,"
"so no simulator debug output", tt
));
simcore_update_debug_bits( sp
->intreg
[Reg_sparcv9_o0
] );
sp
->intreg
[Reg_sparcv9_o0
] = val
;
if (v9p
->state
== V9_User
)
/* Use for dramatic exit */
warning("magic trap 0x%x requested exit(0x%llx)\n", tt
,
sp
->intreg
[Reg_sparcv9_o0
]);
exit(sp
->intreg
[Reg_sparcv9_o0
]);
case MAGIC_TRAP_GOT_HERE
: {
if (v9p
->state
== V9_User
)
log_printf(sp
->gid
, "Got here: 0x%llx\n", sp
->pc
);
#if !defined(NDEBUG) /* { */
case MAGIC_TRAP_LOG_DUMP
: /* rot log dump */
if (v9p
->state
== V9_User
)
#if !defined(NDEBUG) /* { */
case MAGIC_TRAP_PABCOPY
: { /* pa bcopy */
if (v9p
->state
!= V9_RED
&& v9p
->state
!= V9_HyperPriv
)
sp
->intreg
[Reg_sparcv9_g4
] =
pabcopy(sp
, sp
->intreg
[Reg_sparcv9_g1
],
sp
->intreg
[Reg_sparcv9_g2
],
sp
->intreg
[Reg_sparcv9_g3
]);
case MAGIC_TRAP_INST_CNT
: { /* instruction count */
if (v9p
->state
== V9_User
)
temp_flags
= sp
->intreg
[Reg_sparcv9_o0
];
if (temp_flags
& MT_INST_CNT_PRINT
) {
lprintf(sp
->gid
, "At: %llu : "
"Instruction count = %llu\n", (uint64_t)count
,
(uint64_t)(count
- sp
->magic_count
));
if (temp_flags
& MT_INST_CNT_SET_PREV
) {
case MAGIC_TRAP_ALLDBG
: {
if (v9p
->state
== V9_User
)
EXEC_WARNING(("Magic trap 0x%x: compiled with NDEBUG,"
"so no simulator debug output", tt
));
simcore_update_debug_bits(-1);
case MAGIC_TRAP_NO_DBG
: {
if (v9p
->state
== V9_User
)
EXEC_WARNING(("Magic trap 0x%x: compiled with NDEBUG,"
"so no simulator debug output", tt
));
simcore_update_debug_bits(0);
case MAGIC_TRAP_SAVE_STATE
: {
lprintf(sp
->gid
, "MAGIC_TRAP_SAVE_STATE: Got here: 0x%llx (instn_cnt=%lld)\n",
if (sp
->config_procp
->proc_typep
->save_state(sp
) == false) {
fatal("Legion Save State Failed. Exiting!\n");
/* We are done, so terminate legion with a Message */
lprintf(sp
->gid
, "Legion Save State Completed. Exiting\n");
/* no return here - compiler will catch errors in the switch */