// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: SS_VirtualCpu.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 ============================================
#include "SS_VirtualCpu.h"
uint_t
SS_VirtualCpu::id
= 0;
SS_VirtualCpu
* SS_VirtualCpu::list
= 0;
SS_VirtualCpu::SS_VirtualCpu( SS_Model
* model
)/*{{{*/
strand(new SS_VirtualStrand
[cpu
->strand_cnt()])
// The virtual cpu id (vid) numbers from 0 to N-1.
// The strand id associated with vid X is sid X
// if the id is not overwritten in the rc file.
for (int s
=0; s
< cpu
->strand_cnt(); s
++)
strand
[s
].strand
= cpu
->strand
[s
];
SS_VirtualStrand
* SS_VirtualCpu::create( SS_Model
* (*model
)(), Sam::VCPU_Config
* config
, Sam::VCPU_ImpIntf
* interface
)/*{{{*/
// Get the strand with strand_id() number config->id .
// Whilst locating the strand create any missing cpu instances.
SS_Model
* ss
= (model
)();
list
= new SS_VirtualCpu(ss
);
for (pntr
= list
; config
->id
>= (pntr
->cpu
->strand_cnt() + base_id
) ; pntr
= pntr
->next
)
base_id
+= pntr
->cpu
->strand_cnt();
SS_Model
* ss
= (model
)();
pntr
->next
= new SS_VirtualCpu(ss
);
uint_t i
= config
->id
- base_id
;
// Connect the strand to the "outside" world
pntr
->strand
[i
].strand
->io
->set_access_io(interface
->access_io
);
pntr
->strand
[i
].strand
->memory
= interface
->mem
;
pntr
->strand
[i
].strand
->asi_ext_obj
= &pntr
->strand
[i
];
pntr
->strand
[i
].strand
->asi_ext_ld64_fp
= ss_asi_ext_ld64
;
pntr
->strand
[i
].strand
->asi_ext_st64_fp
= ss_asi_ext_st64
;
pntr
->strand
[i
].config
= *config
;
pntr
->strand
[i
].sys_intf
= *interface
;
// Make the strand active in step().
pntr
->cpu
->set_stepping(i
);
// Return the virtual cpu instance.
void SS_VirtualCpu::remove( SS_Model
* ss
)/*{{{*/
SS_VirtualCpu
* hlp
= list
;
int SS_VirtualCpu::snapshot( SS_Model
* model
, const char* dir_name
, const char* file_name
, bool load
)/*{{{*/
FILE* file
= fopen(name
,load
? "r" : "w");
SS_SnapShot
ss(file
,load
);
int SS_VirtualCpu::cycle( uint64_t nn
)
SS_VirtualStrand
*vcpu
= SS_VirtualCpu::list
? SS_VirtualCpu::list
->strand
: NULL
;
if ( vcpu
&& vcpu
->config
.trace_on
&& vcpu
->config
.execution_driven
)
vcpu
->sys_intf
.vtrace
->cycle();
SS_AsiSpace::Error
SS_VirtualCpu::ss_asi_ext_ld64( SS_Node
*, void* asi_ptr
, SS_Strand
* s
, SS_Vaddr va
, uint64_t* data
)/*{{{*/
int sid
= s
->strand_id();
uint8_t asi
= *((uint8_t *)asi_ptr
);
SS_VirtualStrand
*v
= (SS_VirtualStrand
*)s
->asi_ext_obj
;
int ok
= v
->sys_intf
.access_asi(sid
, Sam::VCPU_LOAD_OP
, asi
, va
, 8, (*data
));
return SS_AsiSpace::Error(ok
);
SS_AsiSpace::Error
SS_VirtualCpu::ss_asi_ext_st64( SS_Node
*, void* asi_ptr
, SS_Strand
* s
, SS_Vaddr va
, uint64_t data
)/*{{{*/
int sid
= s
->strand_id();
uint8_t asi
= *((uint8_t *)asi_ptr
);
SS_VirtualStrand
*v
= (SS_VirtualStrand
*)s
->asi_ext_obj
;
int ok
= v
->sys_intf
.access_asi(sid
, Sam::VCPU_STORE_OP
, asi
, va
, 8, data
);
return SS_AsiSpace::Error(ok
);