SPARC Architectural Model : VCPU Interface

Introduction

Vcpu hides the details of the cpu specific implementation.

It presents an abstract interface to the "virtual cpu" - for cpu with multiple strands, it represents each strand; for cpu without strands, it represent the cpu.

A few instances of cpu objects could be created; each cpu object may have a few cpu cores, each core may have a few strands.

CPU cores could run on separate threads of the host machine.

The interface is defined in vcpu.h file. It allows a hook up for an external source level debugger or user interface frontend module. Cpu module is built as a shared library. Vcpu interface has the following components, see Figure 1 below.

- control interface
- system interface (Memory and IO)
- trace interface

Exported interface – routines in the CPU module which is called from outside of the module. Pointers to the routines exposed by the CPU module are defined in VCPU_ExInterface structure.

Imported interface – routines which CPU module calls to get access to the rest of the system.

It is defined by VCPU_ImpIntf structure - set of pointers that CPU module uses to send a request to the system modules.

Control interface constitute an exported interface; system and trace interfaces constitute an imported interface.

Memory is represented by an abstract interface to allow it to model different levels of memory hierarchy, including L2/L3 caches. Cache models are not included.

Currently, there are sparse memory models and flat memory models. Due to performance consideration, the memory model option is defined at build time instead of at run time.

Tracer is represented by an abstract interface which allows hook up of different analyzers and performance models. Vtracer interface is defined in vtracer.h header file.

The Cpu model calls Vtracer methods to output complete information about the architecture state change for every instruction. The information for every instruction is accumulated in VCPU_Instruction structure. Trap information is collected in VCPU_Trap structure, VCPU_TLB is for tlb information.



VCPU Interface Overview.

Cpu module instantiation.


Control interface.

Memory interface.

Physical IO interface.

Tracer interface.



get_ex_interface

NAME

get_ex_interface - Get exported interface from the cpu module

SYNOPSIS

#include “vcpu.h”

extern "C" int get_ex_interface

(

VCPU_ExInterface *intf // pointer to the interface structure

);

typedef int (*VCPU_GetIntfFn )( VCPU_ExInterface *intf );

DESCRIBTION

To get exported interface from the cpu shared library get_ ex_interface () method should be used. It takes a pointer to the VCPU_ExInterface structure and assigns the function pointers inside this structure to the addresses of the corresponding routines implemented in the CPU module.

RETURN VALUES

0 - success;

1 – fail.

USAGE

// open shared library, lib_name is the name of cpu shared libriry.

void *cpu_lib_handle = dlopen (lib_name, RTLD_LAZY|RTLD_GLOBAL|RTLD_PARENT);

// extract cpu lib exported interface

VCPU_GetIntfFn get_interface = (VCPU_GetIntfFn)dlsym ( cpu_lib_handle, "get_ex_interface" );

// obtain exported cpu interface

VCPU_ExInterface g_cpu_ex_intf;

get_interface ( &g_cpu_ex_intf);

//Create a vcpu instance

Vcpu * vcpu = (Vcpu*)g_cpu_ex_intf.create( &config_info, imp_intf );

SEE ALSO

back to overview

VCPU_ExInterface::create

NAME

create - Create and configure a vcpu instance.

SYNOPSIS

#include “vcpu.h”

void * (*create ) // new cpu module

(

VCPU_Config *cinfo, // cpu config params

VCPU_ImpIntf *intf // interface to the system

);

DESCRIPTION

This function pointer is a member of VCPU_ExInterface structure.

Pointer to the routine to create and configure a vcpu instance.

The routine takes a pointer to the set of vcpu parameters and a pointer to the imported interface structure.

RETURN VALUES

return a pointer to the vcpu class.

NULL if fail.

USAGE

Create a vcpu instance. Cpu module implementation may choose to create all core/strand objects at once and this call may simply return a pointer to the next available vcpu object.

This call should be made only once for each vcpu

A set of parameters describing vcpu configuration options are defined in

VCPU_Config structure.

Vcpu * vcpu = (Vcpu*)g_cpu_ex_intf.create( &config_info, imp_intf );

After vcpu instance is created vcpu id is assigned in sequential order – in the order create() calls are made, starting from 0.

From this point vcpu methods which are defined by Vcpu abstract class could be used.

SEE ALSO

back to overview

VCPU_ExInterface::destroy

NAME

destroy - Destroy all vcpu instances.

SYNOPSIS

#include “vcpu.h”

int (*destroy ) ();

DESCRIPTION

This function pointer is a member of VCPU_ExInterface structure.

Pointer to the routine to destroy all vcpu instances.

RETURN VALUES

1 – success;

0 - fail.

USAGE

int status = g_cpu_ex_intf.destroy();

SEE ALSO

back to overview

VCPU_ExInterface::reset

NAME

reset - Reset cpu module.

SYNOPSIS

#include “vcpu.h”

int (*reset ) ();

DESCRIPTION

This function pointer is a member of VCPU_ExInterface structure.

Pointer to the routine to reset architecture visible CPU state.

RETURN VALUES

1 – success;

0 - fail.

USAGE

int status = g_cpu_ex_intf.reset();

SEE ALSO

back to overview

VCPU_ExInterface::save

NAME

save - Save complete simulation state for the cpu module.

SYNOPSIS

#include “vcpu.h”

int (*save ) (char *dir_name);

DESCRIPTION

This function pointer is a member of VCPU_ExInterface structure.

Pointer to the routine to save complete simulation state for the CPU module.

The state is saved to the directory dir_name.

RETURN VALUES

1 – success;

0 - fail.

USAGE

int status = g_cpu_ex_intf.save(dir_name);

SEE ALSO

back to overview

VCPU_ExInterface::restore

NAME

restore - Restore complete simulation state for the cpu module.

SYNOPSIS

#include “vcpu.h”

int (*restore ) (char *dir_name);

DESCRIPTION

This function pointer is a member of VCPU_ExInterface structure.

Pointer to the routine to restore complete simulation state for the CPU module.

The state is restored from the directory dir_name.

RETURN VALUES

1 – success;

0 - fail.

USAGE

int status = g_cpu_ex_intf.restore(dir_name);

SEE ALSO

back to overview

Vcpu:: id

NAME

Vcpu::id - Get vcpu id

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::id();

DESCRIPTION

Virtual method of Vcpu class which is used to get vcpu id. The id is used as an argument to other routines to identify the vcpu instance.

"Unique" platform dependent id of a cpu. The id is the one that is to be used for cpu cross calls and identifying cpu target for device interrupts. Typically function Vcpu *get_vcpu(int id), defined in cpu_interface.h is used to get the target Vcpu pointer given its id. The id's may or may not by sequential, they are defined by cpu sysconf cpu parameter "id". If the parameter is not present on cpu config line, id's are assigned in sequential order.

RETURN VALUES

vcpu id value

USAGE

Create a vcpu instance, this call should be made only once for each vcpu

Vcpu * vcpu = (Vcpu*)g_cpu_ex_intf.create( &config_info, imp_intf );

After vcpu instance is created the id is assigned in sequential order – in the order create() calls are made, starting from 0.

From this point vcpu methods which are defined by Vcpu abstract class could be used.

...

printf(“vcpu id is : %i \n”) vcpu->id();

SEE ALSO

back to overview

Vcpu::stepi

NAME

Vcpu::stepi - Step n number of instructions

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::stepi ( int64_t n=1 );

DESCRIPTION

Virtual method of Vcpu class - step n number of instructions.

Each Vcpu can be called from a separate working thread of the host machine. Vcpu's that belong to the same core may need to be on the same working thread to reduce needs of locking for MT safaty

RETURN VALUES

1 – success;

0 – fail.

USAGE

....

Step 100 number of instructions

int n = 100;

vcpu->stepi(n);

SEE ALSO

back to overview


Vcpu::update_stick

NAME

Vcpu::update_stick– increment stick reg value;

SYNOPSIS

#include “vcpu.h”

virtual void Vcpu::update_stick(int64_t stickincr);

DESCRIPTION

Virtual methods of Vcpu class to increment stick reg value by stickincr amount.

RETURN VALUES

none

USAGE

// increment stick reg value by 10

g_vcpu[cpu_id]->update_stick(10);

SEE ALSO

back to overview




Vcpu::interrupt

NAME

Vcpu::interrupt - Signal an interrupt

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::interrupt ( VCPU_InterruptRequest *signal );

DESCRIPTION

Virtual method of Vcpu class to signal an interrupt. The interrupt message is described by the structure VCPU_InterruptRequest

RETURN VALUES

1 – success;

0 – fail.

USAGE

VCPU_InterruptRequest signal;

signal.isid = src_aid;

signal.itid = dst_aid;

signal.data[0] = idata[0];

vcpu->interrupt(&signal);

SEE ALSO

back to overview

Vcpu:: access integer register

NAME

Vcpu::get_ireg - Read integer register

Vcpu::set_ireg - Write integer register


SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_ireg (int wp, int regnum, uint64_t & regvalue);

virtual int Vcpu::set_ireg (int wp, int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write an integer register.

For SPARC V9 registers access

regnum = 0-7 (globals); wp = 0 (normal) , 1 (alternate) , 2 (mmu), 3 (interrupt)

regnum = 8-31; wp = -1 (current), wp >= 0 (window number)

RETURN VALUES

1 – success;

0 – fail.

USAGE

int reg_idx = 16;

uint64_t value = 0;

vcpu->get_ireg(VCPU_ACC_CUR , reg_idx, value);

value &= 0xff;

vcpu->set_ireg(VCPU_ACC_CUR , reg_idx, value);

SEE ALSO

back to overview

Vcpu:: access floating point register

NAME

Vcpu::get_freg - Read floating point register

Vcpu::set_freg - Write floating point register

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_freg (int issingle, int regnum, uint64_t & regvalue);

virtual int Vcpu::set_freg (int issingle, int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write a floating point register.

If issingle == 1 – single precision 32 bit floating point register;

issingle == 0 – double precision 64 bit floating point register;

regnum is defined according to SPARC V9 and core specific implementation.

RETURN VALUES

1 – success;

0 – fail.

USAGE

int reg_idx = 16;

uint32_t value32 = 0;

// single precision value

vcpu->get_freg(1, reg_idx, value32);

// double precision value

#define SWAP_BIT_5_0(I) ((( (I) & 0x01e ) | ( ((I) & 0x020) >> 5 )) & 0x1f)

uint64_t value64 = 0;

vcpu->get_freg(0, SWAP_BIT_5_0(reg_idx), value64);

SEE ALSO

back to overview

Vcpu:: access privileged register

NAME

Vcpu::get_pr - Read privileged register

Vcpu::set_pr - Write privileged register

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_pr(int regnum, uint64_t & value);

virtual int Vcpu::set_pr(int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write a privileged register.

For trap-level specific registers, get/set_pr functions use the current trap_level.

regnum = 0...31, it is defined according to SPARC V9 and core specific implementation.

RETURN VALUES

1 – success;

0 – fail.

USAGE

uint64_t value = 0;

vcpu->get_pr(VCPU_PR_PSTATE, value);

printf (“PSTATE = %llx”, value);

vcpu->get_pr(VCPU_PR_CWP, value);

printf(“CWP = %llx”, value);

SEE ALSO

back to overview

Vcpu:: access ancillary register

NAME

Vcpu::get_acr - Read ancillary register

Vcpu::set_asr - Write ancillary register

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_asr(int regnum, uint64_t & value);

virtual int Vcpu::set_asr(int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write an ancillary register.

regnum is defined according to SPARC V9 and core specific implementation.

RETURN VALUES

1 – success;

0 – fail.

USAGE

uint64_t value = 0;

vcpu->get_asr(VCPU_ASR_PC, value)

printf (“PC = %llx”, value);

vcpu->get_asr(VCPU_ASR_ASI, value);

printf(“ASI = %llx”, value);

SEE ALSO

back to overview

Vcpu:: access trap specific registers

NAME

Vcpu::get_trapreg - Read trap-level specific register

Vcpu::set_trapreg - Write trap-level specific register

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_trapreg(int tl, int regnum, uint64_t & value);

virtual int Vcpu::set_trapreg(int tl, int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write a trap-level specific register,

where tl is a trap level;

regnum could be one of

VCPU_PR_TPC = 0x0,

VCPU_PR_TNPC = 0x1,

VCPU_PR_TSTATE = 0x2,

VCPU_PR_TT = 0x3.

RETURN VALUES

1 – success;

0 – fail.

USAGE

uint64_t value = 0;

int tl = 1;

vcpu->get_trapreg(1, VCPU_PR_TPC, value)

printf (“trap level = %i, tpc = %llx”, tl, value);

SEE ALSO

back to overview

Vcpu:: access hyper privileged register

NAME

Vcpu::get_hpr - Read hyper privileged register

Vcpu::set_hpr - Write hyper privileged register

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::get_hpr(int regnum, uint64_t & value);

virtual int Vcpu::set_hpr(int regnum, uint64_t value);

DESCRIPTION

Virtual methods of Vcpu class to read/write a hyper privileged register.

regnum is defined according to core specific implementation.

RETURN VALUES

1 – success;

0 – fail.

USAGE

uint64_t value = 0;

vcpu->get_hpr(VCPU_HPR_HPSTATE, value);

printf (“HPSTATE = %llx”, value);

SEE ALSO

back to overview

Vcpu::read_mem

NAME

Vcpu::read_mem – Read memory in the current CPU state

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::read_mem

(

uint64_t addr, // byte address

uint64_t *value, // value to load

int size, // number of bytes

int asi= 0x82, // ASI_PRIMARY_NO_FAULT

int is_physical=0 // 1-physical address, 0-virtual address

);

DESCRIPTION

Virtual methods of Vcpu class to read memory is used if caches or write buffer are present;

address could be virtuall or physical;

little or big endian access is defined by current state;

RETURN VALUES

1 – success;

0 – fail.

USAGE

// read from the double word aligned address

uint64_t addr8 = addr & ~uint64_t(7);

uint64_t value = 0;

if ( g_vcpu[cpu_id]->read_mem(addr8, &value, 8) != 0 )

{

reply_error (1);

return 1;

}

SEE ALSO

back to overview

Vcpu::write_mem


NAME

Vcpu::write_mem – Write memory in the current CPU state

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::write_mem

(

uint64_t addr, // byte address

uint64_t value, // value to write

int size, // number of bytes

int asi= 0x82, // ASI_PRIMARY_NO_FAULT

int is_physical=0 // 1-physical address, 0-virtual address

);

DESCRIPTION

Virtual methods of Vcpu class to write memory is used if caches or write buffer are present;

address could be virtuall or physical;

little or big endian access is defined by current state;

RETURN VALUES

1 – success;

0 – fail.

USAGE

// write 0 value to the double word aligned address

uint64_t addr8 = addr & ~uint64_t(7);

uint64_t value = 0;

if ( g_vcpu[cpu_id]->write_mem(addr8, value, 8) != 0 )

{

reply_error (1);

return 1;

}

SEE ALSO

back to overview

Vcpu::set_breakpoint

NAME

Vcpu::set_breakpoint – Set a breakpoint

SYNOPSIS

#include “vcpu.h”

typedef int (*VCPU_BpActionFn)( int bp_id, int vcpu_id );

virtual int Vcpu::set_breakpoint

(

int *bp_id, // return breakpoint id;

VCPU_BpType type, // breakpoint type

uint64_t value, // opcode, instruction or data address

VCPU_BpActionFn action, // call this function on breakpoint hit

uint64_t mask= ~(uint64_t(0)) // optional data or addr mask

);

DESCRIPTION

Virtual methods of Vcpu class to set of breakpoint of specified type.

Address could be virtuall or physical. Action() routine is called by cpu module when breakpoint is reached, current instruction is not committed

Breakpoint type

typedef enum

{

VCPU_BP_INSTR_ADDR = 0,

VCPU_BP_DATA_READ_ADDR,

VCPU_BP_DATA_WRITE_ADDR,

VCPU_BP_OPCODE,

VCPU_N_BP_TYPES

} VCPU_BpType;

RETURN VALUES

1 – success;

0 – fail.

USAGE

VCPU_BpType type = VCPU_BP_INSTR_ADDR;

uint64_t addr = 0xfff00000;

int bp_id;

extern int bp_action ( int bp_id, int vcpu_id );

vcpu->set_breakpoint( &bp_id,type, addr, bp_action );

SEE ALSO

back to overview

Vcpu::delete_breakpoint

NAME

Vcpu::delete_breakpoint – Delete a breakpoint

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::delete_breakpoint ( int bp_id = ~(0) );

DESCRIPTION

Virtual methods of Vcpu class to remote breakpoint with bp_id.

If bp_id is ~(0) - remove all breakpoints.

RETURN VALUES

1 – success;

0 – fail.

USAGE

// remove all breakpoints

g_vcpu[cpu_id]->delete_breakpoint();

SEE ALSO

back to overview


Vcpu::reconfig

NAME

Vcpu::reconfig– set new parameters for vcpu configuration;

SYNOPSIS

#include “vcpu.h”

virtual int Vcpu::reconfig(VCPU_Config conf );

DESCRIPTION

Virtual methods of Vcpu class to change cpu configuration parameters.

RETURN VALUES

1 – success;

0 – fail.

USAGE

// update cpu config parameters

g_vcpu[cpu_id]->reconfig(new_conf);

SEE ALSO

back to overview



VCPU_ImpIntf::mem

NAME

mem - Pointer to the memory object.

SYNOPSIS

#include “vcpu.h”

#include “Memory.h”

class SMemory *mem;

DESCRIPTION


This pointer is a member of VCPU_ImpIntf structure.

CPU module uses this pointer internally to access physical memory.

Currently we support two types of simulated memory – flat memory and sparse memory.

For speed consideration the type of the memory is defined at build time.


USAGE


The SMemory object should be instantiated outside the CPU module and the pointer to the object is assigned in VCPU_ImpIntf structure and passed to the create() vcpu routine.

SEE ALSO

back to overview

VCPU_ImpIntf::access_io

NAME

access_io - Access physical IO

SYNOPSIS

#include “vcpu.h”

int (*access_io)

(

int vcpu_id, // cpu id

int operation, // operation code- load, store and etc

uint64_t paddr, // physical address

uint32_t size, // access size

uint64_t &data, // 64 bit value to read/write

uint64_t bytemask // access byte mask

);

DESCRIPTION

This function pointer is a member of VCPU_ImpIntf structure.

Pointer to the routine to access physical io space from the CPU module.

Parameter operation is defined in VCPU_Operation.

CPU module uses this pointer internally to access physical IO space.

RETURN VALUES

1 – success;

0 - fail.

USAGE

The routine should be defined outside the CPU module and the pointer to the routine is assigned in VCPU_ImpIntf structure and passed to the Create vcpu routine.

SEE ALSO

back to overview

VCPU_ImpIntf::access_asi

NAME

access_asi - Optional interface to access devices that mapped to asi ring

SYNOPSIS

#include “vcpu.h”

int (*access_asi)

(

int vcpu_id, // cpu id

int operation, // operation code- load,store and etc.

uint32_t asi, // asi value

uint64_t vaddr, // virtual address

int32_t size, // access size

uint64_t &buf // 64 bit data value

);

DESCRIPTION

This function pointer is a member of VCPU_ImpIntf structure.

Pointer to the routine to access device control registers mapped to the asi ring from the CPU module. Parameter operation is defined in VCPU_Operation.

CPU module uses this pointer internally to access asi mapped address space.

RETURN VALUES

1 – success;

0 - fail.

USAGE

The routine should be defined outside the CPU module and the pointer to the routine is assigned in VCPU_ImpIntf structure and passed to the Create vcpu routine.

NULL if not used.

SEE ALSO

back to overview

VCPU_ImpIntf::access_serial

NAME

access_serial - Optional interface to access serial devices

SYNOPSIS

#include “vcpu.h”

//

int (*access_serial)

(

uint8_t *c, // character to read/write

bool_t wr // 0 - read, 1 - write

);

DESCRIPTION

This function pointer is a member of VCPU_ImpIntf structure.

Pointer to the routine to access serial device for software bring up and debugging from the CPU module. CPU module uses this pointer internally to access simulated serial device.

RETURN VALUES

1 – success;

0 - fail.

USAGE

The routine should be defined outside the CPU module and the pointer to the routine is assigned in VCPU_ImpIntf structure and passed to the Create vcpu routine.

NULL if not used.

SEE ALSO

back to overview

VCPU_ImpIntf::vtrace

NAME

vtrace - Pointer to the vtracer object.

SYNOPSIS

#include “vcpu.h”

#include “vtracer.h”

class VTracer *vtrace;

DESCRIPTION

This pointer is a member of VCPU_ImpIntf structure.

CPU module uses this pointer internally to output instruction trace.

VTracer is an abstract class representing any analyzer which could be hooked up the CPU module. Cpu model calles Vtracer methods to output a complete information about architecture state change for every instruction. The information for every instruction is accumulated in VCPU_Instruction structure.

Trap information is collected in VCPU_Trap structure, VCPU_TLB is for tlb information.

USAGE

The Vtracer object should be instantiated outside the CPU module, pointer to the object is assigned in VCPU_ImpIntf structure and passed to the Create vcpu routine.

A tracer module must NOT define a static vtracer object. The

vtracer object must be created by the vtracer_init() function

provided by the module code and called by the simulator. Also, the

module must provide a function called vtracer_fini() which should

clean up before the module is unloaded (un-register ui commands, free

memory etc.)

Instruction information VCPU_Instruction - provides information

about the instruction been executed.

Fields in this structure are arranged according to the

order in which they are used during instruction lifetime.

SEE ALSO

back to overview

Vtracer::instr

NAME

Vtracer::instr - Send an instruction info message.

SYNOPSIS

#include “vcpu.h”

#include “vtracer.h”

virtual int Vtracer::instr ( VCPU_Instruction *i );

DESCRIPTION

Virtual method of Vtracer class – output an instruction information.

VTracer is an abstract class representing any analyzer which could be hooked up the CPU module. VCPU_Instruction - provides information about the instruction been executed.

Fields in this structure are arranged according to the

order in which they are used during instruction lifetime.

USAGE

// collect trace record

VCPU_Instruction *i;

i->nregs = 0;

i->ld_num = 0;

i->st_num = 0;

i->itype = VCPU_UNKNOWN_ITYPE;

i->cpuid = cpuid;

i->pc_va = pc_va;

i->pc_pa = pc_pa;

i->npc_va = npc_va;

i->opcode = iw;

i->annul = an;

i->taken = (npc_va != (pc_va + 4));

// call tracer

g_ni_vcpu[cpuid]->sys_intf.vtrace->instr(i);

SEE ALSO

back to overview

Vtracer::trap

NAME

Vtracer::instr - Send a trap info message.

SYNOPSIS

#include “vcpu.h”

#include “vtracer.h”

virtual int Vtracer::trap ( VCPU_Trap *t );

DESCRIPTION

Virtual method of Vtracer class – output trap information.

VCPU_Trap - provides information about the trap been taken.

USAGE

Sam::VCPU_Trap *t;

t->pc_va = tr_pc;

t->npc_va = tr_npc;

t->tno = tno;

t->cpuid = id;

//call tracer

g_ni_vcpu[id]->sys_intf.vtrace->trap(t);

SEE ALSO

back to overview