Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / include / vcpu.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: vcpu.h
* 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 ============================================
*/
///////////////////////////////////////////////////////////
//
// File: vcpu.h
//
// Copyright (C) 2005 Sun Microsystems, Inc.
// All rights reserved.
//
#ifndef _CPU_LIB_INTERFACE_H
#define _CPU_LIB_INTERFACE_H
#include <stdlib.h>
// #include "vtracer.h"
// This file defines interface structures for the cpu module
// in the shared library.
// 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.
// max number of Cpu's supported
const int NCPU_MAX = 1024;
//
// Supported implementations
//
// Bit encoding:
// 0..7 mask rev of chip;
// 8..23 cpu implementation;
// 24..31 sim implementation;
//
typedef enum
{
VCPU_IMPL_VER_NONE = 0,
VCPU_IMPL_VER_SPITFIRE = 0x00001000,
VCPU_IMPL_VER_BLACKBIRD = 0x00001100,
VCPU_IMPL_VER_SABRE = 0x00001200,
VCPU_IMPL_VER_SAPPHIRE = 0x00001300,
VCPU_IMPL_VER_CHEETAH = 0x00001400,
VCPU_IMPL_VER_CHPLUS = 0x00001500,
VCPU_IMPL_VER_SUN4U = 0x00001000,
VCPU_IMPL_VER_N1 = 0x00002300,
VCPU_IMPL_VER_N2 = 0x00002410,
VCPU_IMPL_VER_SUN4V = 0x00002000,
VCPU_IMPL_VER_MASK = 0x00ffffff,
VCPU_IMPL_SIM_BLAZE = 0x01000000,
VCPU_IMPL_SIM_RIESLING = 0x02000000,
VCPU_IMPL_SIM_VONK = 0x03000000,
VCPU_IMPL_SIM_MASK = 0xff000000
}
VCPU_Type;
/////////////////////////////////////////////////////
//
// Cpu config structure
//
typedef class
{
public:
char *name; // cpu instance name
char *type; // Ultrasparc-T1, ...
char *mmu_type; // t1, ...
VCPU_Type cpu_type; // encoded cpu impl version
int reg_wins; // number of reg windows
int tl_max; // trap level max
int itlb_size; // number of tlb entries
int dtlb_size;
int loopticks; // number of instruction completed before incrementing stick reg
int stickincr; // the amount stick has to be incremented
uint64_t cpufreq; // cpu clock
uint64_t stickfreq; // system clock
double cpi; // cycles per instruction
int delay; // delay this number of instructions
int mode; // 1 - multithreaded (MP on MP) run;
// 0 - all cpu's on a single thread;
int trace_on; // 1 - trace enabled;
// 0 - trace disabled;
int execution_driven; // must be updated using the get/enable/disable functions
// a platform dependent id by which a "strand" can be referred to
// by the operating system or system bus devices. For a ch/ch+ platform
// the "strand" is the cpu itself, and id would be the agent id of the cpu
// on the safari bus. For a sun4v implementation, the id would be the
// strand id of the strand. The typical usage of this id is to identify
// the vcpu that is a target of a cpu cross call or device mondo interrupt.
// the value either comes from cpu sysconf line or an implementation
// may choose to provide one automatically.
int id;
}
VCPU_Config;
/////////////////////////////////////////////////////
//
// Interrupt message
//
#define INTR_DATA_SIZE 8
struct VCPU_InterruptRequest
{
int isid; // interrupt sender ID
int itid; // interrupt target ID
uint64_t data[INTR_DATA_SIZE]; // (sun4u only?) data
uint32_t bogus_src_dev_id; // aka INO, ie interrupt number ???
uint32_t bogus_src_dev_type; // bogus debug info
};
/////////////////////////////////////////////////////
//
// Cpu imported interface for the io and memory
// subsystem
//
// Set of function pointers that cpu module calls
// to send a request to the system modules.
//
enum VCPU_Operation
{
VCPU_LOAD_OP, // Load 1,2, or more bytes from memory. Atomicity is guaranteed up to 8 bytes
VCPU_STORE_OP, // Store 1,2, or more bytes to memory. Atomicity is guaranteed up to 8 bytes
VCPU_STORE_PARTIAL_OP, // Store 1,2, or more bytes to memory, bit enabled by set bits
VCPU_LOAD_ATOMIC_OP, // Load atomic. Atomicity of the load is guaranteed
VCPU_SWAP_OP, // Swap - SunSparc 32bit swap instruction
VCPU_CAS_OP, // Compare And Swap - SunSparc 32bit casa, or 64bit casxa instruction
VCPU_LDSTUB_OP, // LoaD STore Unsigned Byte - SunSparc 8bit ldstub instruction
VCPU_PREFETCH_OP, // Prefetch data into the cache hierarchy
VCPU_FLUSH_OP, // Flush data in the cache hierarchy to memory
VCPU_PEEK_OP, // Read data from memory mapped registers without causing sideeffect
VCPU_POKE_OP // Write data to memory mapped registers without causing sideeffect
};
class SMemory; // forward declarations
class VTracer;
typedef struct
{
// memory interface
class SMemory *mem;
// vtracer interface
class VTracer *vtrace;
// io interface
int (*access_io)
(
int vcpu_id, // cpu id
int operation, // operation code
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
);
// interface to access devices that mapped to asi ring
int (*access_asi)
(
int vcpu_id, // cpu id
int operation, // operation code
uint32_t asi, // asi value
uint64_t vaddr, // virtual address
int32_t size, // access size
uint64_t &buf // 64 bit data value
);
// serial device for software bring up debugging
int (*access_serial)
(
uint8_t *c, // character to read/write
int wr // 0 - read, 1 - write
);
}
VCPU_ImpIntf;
/////////////////////////////////////////////////////
//
// Cpu module exported interface
//
// when applicable return 0- if succeed, >0- if fail.
//
typedef struct
{
// create/config method
// return vcpu pointer
void * (*create ) // new cpu module
(
VCPU_Config *cinfo, // cpu config params
VCPU_ImpIntf *intf // interface to the system
);
int (*reset ) ( uint64_t pc );
int (*destroy) ();
// set/get config param
int (*exec_cmd)
(
char *cmd_str, // command string
char *reply, // return reply string
int reply_size // size of reply string
);
// save restore methods
int (*save ) ( char *dir_name );
int (*restore) ( char *dir_name );
// advance nn number of cycles
int (*cycle ) ( uint64_t nn );
}
VCPU_ExInterface;
////////////////////////////////////////////////////////
//
// Get exported interface from the cpu shared library.
//
// Assign function pointers in the interface structure.
//
//
// return: 0 - success; 1 - fail;
extern "C" int get_ex_interface
(
VCPU_ExInterface *intf // pointer to the interface structure
);
typedef int (*VCPU_GetIntfFn )( VCPU_ExInterface *intf );
// breakpoint type
typedef enum
{
VCPU_BP_INSTR_ADDR = 0,
VCPU_BP_TRAP,
VCPU_BP_RED,
VCPU_BP_DATA_READ_ADDR,
VCPU_BP_DATA_WRITE_ADDR,
VCPU_BP_OPCODE,
VCPU_N_BP_TYPES
}
VCPU_BpType;
// This enum is used to access cpu register state through vcpu's
// get_reg/set_reg methods.
enum
{
VCPU_IRF_0 = 0x00,
VCPU_DRF_0 = 0x20,
VCPU_ASR_0 = 0x40,
VCPU_PR_0 = 0x60,
VCPU_HPR_0 = 0x80,
VCPU_SIM_0 = 0xA0,
VCPU_FRF_0 = 0xC0,
VCPU_MAX_INDEX = VCPU_FRF_0 + 0x1f,
VCPU_ASR_Y = VCPU_ASR_0,
VCPU_ASR_CCR = VCPU_ASR_0 + 2,
VCPU_ASR_ASI = VCPU_ASR_0 + 3,
VCPU_ASR_TICK = VCPU_ASR_0 + 4,
VCPU_ASR_PC = VCPU_ASR_0 + 5,
VCPU_ASR_FPRS = VCPU_ASR_0 + 6,
VCPU_ASR_PCR = VCPU_ASR_0 + 16,
VCPU_ASR_PIC = VCPU_ASR_0 + 17,
VCPU_ASR_IEU_CNTRL = VCPU_ASR_0 + 18,
VCPU_ASR_GSR = VCPU_ASR_0 + 19,
VCPU_ASR_SOFTINT_SET= VCPU_ASR_0 + 20,
VCPU_ASR_SOFTINT_CLR= VCPU_ASR_0 + 21,
VCPU_ASR_SOFTINT = VCPU_ASR_0 + 22,
VCPU_ASR_TICK_CMPR = VCPU_ASR_0 + 23,
VCPU_ASR_STICK = VCPU_ASR_0 + 24,
VCPU_ASR_STICK_CMPR = VCPU_ASR_0 + 25,
VCPU_PR_TPC = VCPU_PR_0 + 0,
VCPU_PR_TNPC = VCPU_PR_0 + 1,
VCPU_PR_TSTATE = VCPU_PR_0 + 2,
VCPU_PR_TT = VCPU_PR_0 + 3,
VCPU_PR_TICK = VCPU_PR_0 + 4,
VCPU_PR_TBA = VCPU_PR_0 + 5,
VCPU_PR_PSTATE = VCPU_PR_0 + 6,
VCPU_PR_TL = VCPU_PR_0 + 7,
VCPU_PR_PIL = VCPU_PR_0 + 8,
VCPU_PR_CWP = VCPU_PR_0 + 9,
VCPU_PR_CANSAVE = VCPU_PR_0 + 10,
VCPU_PR_CANRESTORE = VCPU_PR_0 + 11,
VCPU_PR_CLEANWIN = VCPU_PR_0 + 12,
VCPU_PR_OTHERWIN = VCPU_PR_0 + 13,
VCPU_PR_WSTATE = VCPU_PR_0 + 14,
VCPU_PR_FPQ = VCPU_PR_0 + 15, // depricated after USIII
VCPU_PR_GL = VCPU_PR_0 + 16,
VCPU_PR_VER = VCPU_PR_0 + 31, // depricated after USIII (replaced by HVER)
VCPU_HPR_HPSTATE = VCPU_HPR_0 + 0,
VCPU_HPR_HTSTATE = VCPU_HPR_0 + 1,
VCPU_ASR_NPC = VCPU_SIM_0 + 0,
VCPU_ASR_FSR = VCPU_SIM_0 + 1,
VCPU_SIM_MAX_GL = VCPU_SIM_0 + 6,
VCPU_SIM_MAX_TL = VCPU_SIM_0 + 4,
VCPU_SIM_MAX_WP = VCPU_SIM_0 + 3
};
/////////////////////////////////////////////////////////////
//
// 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 strands;
// for cpu without strands it represent the cpu.
typedef int (*VCPU_BpActionFn)( int bp_id, int vcpu_id );
class Vcpu
{
public:
VCPU_Config config;
VCPU_ImpIntf sys_intf;
public:
// virtual interface methods,
// when applicable return 0- success, >0- fail;
virtual int reconfig (VCPU_Config conf) { return 0; }
// "unique" platform dependent id of a cpu. eg in case of ch/ch+, the
// id is same as the agent id if the cpu. In case of N1/N2, etc,
// the id is the threadid of the strand. The id is the one that is to
// be used for cpu cross calls and identifying cpu target for device
// interrupts. Typically the 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 contiguous, it is
// derived from cpu sysconf parameter "id". If the parameter is
// not present, then id is assigned in sequential order.
//
virtual int id() { return config.id; }
// step n number of instructions;
// each Vcpu can be called from a separate working thread of
// the host machine;
// Vcpu that belongs to the same core may need to be on the
// same working thread to reduce locking for mt safe calls
//
virtual int stepi ( int64_t n=1 )=0;
// signal an interrupt
virtual int interrupt ( VCPU_InterruptRequest *signal )=0;
virtual void update_stick(int64_t stickincr) = 0;
// HW performance instrumentation counters
// CH and NI have just two counters, we will extend this enum
// as needed when we implement xx, etc...
//
typedef enum {PIC0, PIC1} perfcntr;
//
virtual void update_perfcntr(perfcntr which, int64_t incr) = 0;
// debugger/frontend methods
typedef int RegIndex;
enum RegError
{
REG_OK, // All OK
REG_NOT_AVAILABLE, // Register name or index is not available.
REG_VALUE_OUT_OF_RANGE // Value written is not accepted
};
virtual RegError get_reg_index( const char* reg_name, RegIndex* index ) = 0;
virtual const char* get_reg_name( RegIndex index ) = 0;
// get_reg() and set_reg() read and write the vcpu registers
// such as window regs like %i2, globals like %g0, asr like
// %asr13, privileged like %tl, hyperprivileged like %htstate,
// unmapped state like %npc and %fsr, etc.
virtual RegError get_reg( RegIndex index, uint64_t* value ) = 0;
virtual RegError set_reg( RegIndex index, uint64_t value ) = 0;
// asi mapped regs
virtual int get_asi(uint8_t asi, uint64_t addr, uint64_t &data) = 0;
virtual int set_asi(uint8_t asi, uint64_t addr, uint64_t data) = 0;
// The TranslateMode enumeration is for translate() interfaces
// that takes an address and converts it into an physical address.
// The enumeration tells the translate() method of the vcpu
// api which arguments are valid and how to interpret the
// input address: VA virtual, RA real, PA phisical
enum TranslateMode
{
TRANSLATE_VA_TO_PA, // VA to PA with processor context and partitionid
TRANSLATE_VA_TO_PA_CTX, // VA to PA with given context and processor partitionid
TRANSLATE_VA_TO_PA_CTX_PID, // VA to PA with given context and partitionid
TRANSLATE_RA_TO_PA, // RA to PA with processor partitionid
TRANSLATE_RA_TO_PA_PID, // RA to PA with given partitionid
TRANSLATE_PA_TO_PA // PA (64bit) to PA (processor specific width)
};
// The TranslateError enum is for errors returned by translate()
enum TranslateError
{
TRANSLATE_OK, // phys_addr argument to translate conmtains phys addr
TRANSLATE_NO_TTE_FOUND // translate() cound not find matching TTE to get phys addr
};
// If translate() returns TRANSLATE_OK then the translation was successful. Else
// the translation cannot be completed with the parameters given for the particular mode.
virtual TranslateError translate( TranslateMode mode, uint64_t addr, uint64_t context, uint64_t partitionid, uint64_t* phys_addr ) = 0;
// caller must explicitly FREE return_array before it is overwritten or goes out of scope
virtual int get_tlb_entries(struct TLBInfo * &return_array) = 0;
// mem read - used if caches or write buffer is present;
// address could be virtuall or physical;
// little or big endian access is defined by current state;
virtual int 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
)=0;
// mem write
virtual int 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
)=0;
// set breakpoint;
// when breakpoint hits - instruction should not be commited
virtual int 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
);
// remove breakpoint bp_id
// if bp_id is ~(0) - remove all instruction bp
virtual int delete_breakpoint ( int bp_id = ~(0) );
// print breakpoint list to a file/consol
virtual int print_breakpoints ( FILE *fp );
// print all regs to file/consol
virtual int print_regs ( FILE *fp );
// print tlbs to file/consol
virtual int print_tlbs ( FILE *fp );
// Return cpu implementation name
static const char* cpu_name(VCPU_Type type)
{
switch (type & VCPU_IMPL_VER_MASK) {
case VCPU_IMPL_VER_SPITFIRE:
return "spitfire";
case VCPU_IMPL_VER_BLACKBIRD:
return "blackbird";
case VCPU_IMPL_VER_SABRE:
return "sabre";
case VCPU_IMPL_VER_SAPPHIRE:
return "sapphire";
case VCPU_IMPL_VER_CHEETAH:
return "ch";
case VCPU_IMPL_VER_CHPLUS:
return "chplus";
case VCPU_IMPL_VER_N1:
return "ni";
case VCPU_IMPL_VER_N2:
return "n2";
default:
return "unknown-cpu";
}
};
};
#endif // _CPU_LIB_INTERFACE_H