// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dr.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, 2005 Sun Microsystems, Inc.
#pragma ident "@(#)1.4 02/05/2002 dr.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 "workerthread.h"
#include "blaze_globals.h"
///////////////////////////////////////////////////
// This module is an implementation of
// BLAZE DUMP/RESTORE facility
///////////////////////////////////////////////////
static DR_unitNode
*dr_head
= NULL
, *dr_tail
= NULL
;
static char help_string
[] = "dump <directory name> - directory shouldn't exist";
static char *dr_dir
= NULL
;
int dump_cmd_action (void*, int argc
, char **argv
);
bool_t
dump_blaze (DR_unit
*);
bool_t
restore_blaze (DR_unit
*);
char ver
[128] = BLAZEVERSION_STRING
;
char second_ver
[128] = "\0";
///////////////////////////////////////////////////
{int ver_no
, sub_ver_no
; char blaze_ver
[8];
strncpy(blaze_ver
, ver
,4);
sscanf(blaze_ver
, "%d.%d", &ver_no
, &sub_ver_no
);
// This must be called in company with restore_v4_dump()!!
{int ver_no
, sub_ver_no
; char blaze_ver
[8];
assert(restore_v4_dump());
if (handle_pseud_v4_dump())
strncpy(blaze_ver
, second_ver
, 4);
strncpy(blaze_ver
, ver
, 4);
sscanf(blaze_ver
, "%d.%d", &ver_no
, &sub_ver_no
);
{int ver_no
, sub_ver_no
; char blaze_ver
[8];
strncpy(blaze_ver
, ver
, 4);
sscanf(blaze_ver
, "%d.%d", &ver_no
, &sub_ver_no
);
{int ver_no
, sub_ver_no
, sub_sub_ver_no
; char blaze_ver
[8];
strncpy(blaze_ver
, ver
, 7);
sscanf(blaze_ver
, "%d.%d.%d", &ver_no
, &sub_ver_no
, &sub_sub_ver_no
);
// For handling a primary V5 dump created from a restored V4 dump
bool_t
handle_pseud_v4_dump()
if (second_ver
[0] == '4')
bool_t
restore_pure_v4_dump()
if (BLAZE_restore_from_checkpoint() && dump_version() == 4)
if (BLAZE_restore_from_checkpoint() && (dump_version() == 4 || handle_pseud_v4_dump()))
if (BLAZE_restore_from_checkpoint() && dump_version() >= 5)
// ----------------------------------------------------------------------------
//@@@ why not call DR_register(&dump_blaze,&restore_blaze)
dr_head
= DR_unitNode::CreateInstance ("DR list");
ui
->error("Unable to allocate memory for DR");
pdr
= dr_head
->GetData ();
pdr
->dump_fn
= dump_blaze
; /* local ftn, calls SYSTEM_dump */
pdr
->restore_fn
= restore_blaze
; /* local ftn, calls SYSTEM_restore */
pdr
->name
= (char*)strdup(BLAZE_SYSTEM
);
UI_register_cmd_2 ((char*)"dump", help_string
, dump_cmd_action
, NULL
);
// ----------------------------------------------------------------------------
int dump_cmd_action (void*, int argc
, char **argv
)
if (dump_version() < 5) {
ui
->warning("restored from old-format (V4) dump; the new dump will be V5 format\n");
//** pre-dump criteria *****
if (!SYSTEM_is_stopped ()) {
ui
->error("SAM must be STOPPED for dump");
ui
->error("Illegal UI command format ");
if (mkdir(argv
[1], S_IRWXU
| S_IRWXG
| S_IRWXO
) == -1) {
ui
->output("dump directory <%s> is created\n", argv
[1]);
//** pre-dump actions *****
WorkerThread::doEventqueUnloads ();
//** now call every registered dump function *****
pdr
= dr_head
->GetData ();
pdr
->dir
= (char*)strdup(argv
[1]);
dr_dir
= (char*)strdup(argv
[1]);
for (pnode
= dr_head
; pnode
; pnode
= pnode
->Next()) {
ui
->output("Dumping <%s> ...\n", pdr
->name
);
bool tmp
= pdr
->dump_fn(pdr
); //*** <--- here's the action
ui
->output(" %s\n",(tmp
? "done" : "failed"));
ui
->output("no dump action found for <%s> \n", pdr
->name
);
//** post-dump return *****
// ----------------------------------------------------------------------------
// gets called indirectly by the above (dump_cmd_action) function
bool_t
dump_blaze (DR_unit
* pdr
)
char *dumpfile
= (char*) malloc (strlen(pdr
->dir
) + 64);
ui
->error("memory problems");
sprintf(cmd_line
, "cp %s %s/%s", get_script_file(), pdr
->dir
, RC_DUMP
);
ui
->error("Script copy failed. %s!", strerror(errno
));
sprintf (dumpfile
, SAM_VERSION_FILE
, pdr
->dir
);
pdr
->fp
= fopen(dumpfile
, "w");
fputs (SYSTEM_get_version(), pdr
->fp
);
/* dump_version() < 5 means the restored V4 dump is being dumped as a V5 dump.
handle_pseud_v4_dump() means the V4 mixed V5 dump is being dumped again. */
if (dump_version() < 5 || handle_pseud_v4_dump()) {
sprintf (dumpfile
, SECONDARY_VERSION_FILE
, pdr
->dir
);
pdr
->fp
= fopen(dumpfile
, "w");
fputs(second_ver
, pdr
->fp
);
sprintf (dumpfile
, "%s/%s.dmp", pdr
->dir
, pdr
->name
);
pdr
->fp
= fopen(dumpfile
, "w");
pdr
->filename
= (char*)strdup(dumpfile
);
SYSTEM_dump (pdr
->fp
); //*** <--- here's the action, but this is
// only for "dump/blaze_system.dmp" !!!
// ---------------------------------------------------------------------------
// gets called indirectly by ui_cmds.cc before first "run" command:
// (@@@@@ but not for "stepi", "stepc" commands ?????)
// -> complete_initialization
// -> restore_devices_action
bool_t
restore_blaze (DR_unit
* pdr
)
char *rfile
= (char*) malloc (strlen(pdr
->restore_dir
) + strlen(pdr
->name
) + 16);
ui
->error("memory problems");
sprintf (rfile
, "%s/%s.dmp", pdr
->restore_dir
, pdr
->name
);
ret
= SYSTEM_restore (fp
); //*** <--- here's the action, but this is
// only for "dump/blaze_system.dmp" !!!
///////////////////////////////////////////////////
void DR_register (const char *name
, dump_action dump_fn
, restore_action restore_fn
, void * client_data
)
DR_unitNode
*pnode
= DR_unitNode::CreateInstance ("DR list");
ui
->error("unable to allocate memory for <%s>", name
);
pdr
->name
= (char*) strdup (name
);
pdr
->restore_fn
= restore_fn
;
pdr
->client_data
= client_data
;
DR_unitNode::AddTail (&dr_head
, &dr_tail
, pnode
);
///////////////////////////////////////////////////
void DR_unregister (void *client_data
)
DR_unitNode
*pnode
= dr_head
;
DR_unitNode
*prev
= NULL
;
DR_unit
*pdr
= pnode
->GetData();
if (pdr
->client_data
== client_data
) {
DR_unitNode::DeleteNode(&dr_head
, prev
);
///////////////////////////////////////////////////
char * DR_get_name (DR_OPAQUE pdr
)
char * DR_get_rdir (DR_OPAQUE pdr
)
///////////////////////////////////////////////////
void* DR_get_client_data (DR_OPAQUE pdr
)
///////////////////////////////////////////////////
DR_restore_object (char * dir
, char * name
)
DR_unitNode
*pnode
= dr_head
;
ui
->output("Restoring <%s> ...", name
);
for (;pnode
; pnode
= pnode
->Next()) {
if (strcmp(pdr
->name
, name
) == NULL
) {
pdr
->restore_dir
= (char*)strdup(dir
);
dr_dir
= (char*)strdup(dir
);
ret
= pdr
->restore_fn (pdr
); //***
ui
->output(" .. NO HANDLER .. ");
ui
->output(" %s \n", ret
? "done" : "failed");
//** if restoring, is called from UI before first "run" command
void restore_devices_action(char *dir
)
for (pnode
= dr_head
; pnode
; pnode
= pnode
->Next()) {
if (!DR_restore_object(dir
, pdr
->name
)) //***