⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 embra.h

📁 一个用在mips体系结构中的操作系统
💻 H
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#ifndef EMBRA_H#define EMBRA_H#include <sys/cdefs.h>/* From embra - should this be shared? */#include "c_port.h"/* From the shared directory */#include "mips_arch.h"#include "addr_layout.h"#include "cpu_state.h"#include "cpu_interface.h"#include "sim_error.h"/* From simos */#include "syslimits.h"#ifndef _LANGUAGE_ASSEMBLY#include "simmisc.h" #include "machine_params.h"/* ***************************************************************** * A form of PC that allows us to pass information as to whether we  * are in the delay slot  * ****************************************************************/typedef VA  PC_BD;#define IN_BD(_pc) ((_pc) & 0x1)#define CLEAR_BD(_pc) ((_pc) & (~(0x1)))/* Directory Entry.  Limits to 30 cpus, but ll/sc is word limited *//* Could expand to 62 cpus with lld MIPS III opcode */typedef uint Dir_Entry;/* **************************************************************** * Virtual quick check status byte  * *****************************************************************/typedef enum {MEM_D_EXCLUSIVE = 0x80,               MEM_I_EXCLUSIVE = 0xc0,               MEM_D_SHARED = 0x01,               MEM_I_SHARED = 0x41,               MEM_INVALID = 0x00} EmVQCMemState;#define VQC_SHARED(_x)((int)(_x) &   0x00000001)#define VQC_EXCL(_x)  ((int)(_x) &   0x00000080 )#define VQC_INST(_x)  ((int)(_x) &   0x00000040 )#define VQC_DATA(_x)  ((int)(_x) == MEM_D_EXCLUSIVE || (int)(_x) == MEM_D_SHARED)#endif /* _LANGUAGE_ASSEMBLY *//* *********************************************************************** * Still this BACKDOOR vs KSEG1 confusion.  * ***********************************************************************/#define IS_BACKDOOR(_addr) (IS_KSEG1(_addr))#if defined(SIM_MIPS32)#define IS_USER(_pc) (!IS_KSEG0(_pc))#else#define IS_USER(_pc) (IS_XKUSEG(_pc))#endif/* Zero offset bits, and add a line */#define ALIGN_IT( _val, _mod ) ( ((unsigned)(_val) & (~((unsigned)_mod-1))) +\(unsigned)_mod )#define HOST_SCACHE_LINE_SIZE (128)/* ******************************************************************* * Memory Address macros. Should in fact be somewhere else (not * embra specific) * ******************************************************************/#define MA_TO_UINT(x)  ((uint)(x))#define EMBRA_IS_MEMADDR(_m, x) (IS_VALID_MA((_m), (x)))#define EMBRA_IS_PADDR(_m, x)   (IS_VALID_PA((_m), (x)))#ifndef _LANGUAGE_ASSEMBLY/* We may need extra state eventually, but right now, CPUState is sufficient*/typedef CPUState EmbraState;extern EmbraState* EMP;  /* allocated in driver.c */typedef struct EmbraParams {    int sequential;          /* not really a param - for now 1 */   int parallel;            /* not really a param - for now 0 */   CPUType emode;           /* not really a param - EMBRA_CACHE | EMBRA_PAGE */     int MPinUP;              /* never set for cpuNum==1 - yes */      int useETLB;             /* boolean - yes */   int useVQC;              /* boolean - yes */   int stats;               /* boolean - yes */   int inlineQC;            /* boolean - yes */   int timeQuantum;         /* 1024 */   int periodicAnnInterval; /* 32*1024*1024 */   int statInterval;        /* 32*1024*1024 */   int miscCheckInterval;   /* 50000 */   int separateMMUs;}  EmbraParams;extern EmbraParams embra;/* ********************************************************** * Current EMP and cpu is determined by curEmp, updated * on context switches * ********************************************************* */extern int EmbraCurrentCpuNum(void);#define CURR_CPU (curEmp->myNum)extern EmbraState* curEmp;/* Allocated in driver.c This is NOT shared*/extern int quick_ASID[SIM_MAXCPUS];/* Allocated in simos_interface.c - the number of CPUs in the simulation *//* Here are a whole bunch of defines.  All of the registers, and how *//* Embra uses them are here. */#endif /* _LANGUAGE_ASSEMBLY *//* DEFINE what registers simulator will use */#ifndef _LANGUAGE_ASSEMBLYtypedef struct RegNoDummy {   char nothing[1];} RegNo;#define REGNUM(_x) ((int)(_x))#endif#ifdef _LANGUAGE_ASSEMBLY/*  * this is a work-around around the expansion rules of cpp. */#if  defined(_ABIN32) #define REGISTER_NUMBER(_x) $/**/_x#else#define REGISTER_NUMBER2(_dollar,_x) _dollar##_x#define REGISTER_NUMBER(_x) REGISTER_NUMBER2($,_x)#endif#else#define REGISTER_NUMBER(_x) (_x)#endif/* ********************************************************************* * new register map: * ********************************************************************* *  0  zero   : *  1  at     : shadow *  2  v0     : used to return stuff (tc internal) *  3  v1     : shadow *  4  a0-a3  : parameter passing (tc internal + callout) *  8  t0-t2  : shadow *  11 t3-t6  : tc internal *  15 t7     : shadow *  24 t8-t9  : shadow *     s0-s8  : common variables * ********************************************************************//* ********************************************************************* * Simulator working registers  *  SIM_T1 & SIM_T2 are used by ALU_OPS and L/S generally as * rs == SIM_T2, rt == SIM_T1, rd = SIM_T2 *  * BRANCHREG holds either the branch condition or the target address if * its a register indirect jump.  Therefore it must be saved on * callouts because if we callout in a delay slot, we don't want to * lose our branch information * * XXX bugnion(fix this. should be a callee saved register) * * SIM_T4 Used for Quick Check and link address in branch and link  * instructions *  ************************************************************************/#define SIM_T1 REGISTER_NUMBER(REG_T3)#define SIM_T2 REGISTER_NUMBER(REG_T4)#define SIM_T3 unused-register#define SIM_T4 REGISTER_NUMBER(REG_T6)/* ******************************************************************* * Simulator permanent registers. * These registers are used to cache the most frequently accessed * variables from within the translation cache. * All registers are callee saved, therefore do not need to  * explicitely saved on callouts. * * VSS_BASE == curEmp == &EMP[CURR_CPU] * QC_REG   == curEmp->qc_v, (cache mode only) * MMU_REG  == curEmp->mmu: base of relocation array * PC_REG   == curEmp->PC (must spill on callouts!) * CLOCK_REG== curEmp->XXX * MMUMASK_REG == 0x7fffffff (page mode only) *  * IHIT     == number of instructions executed * DHIT     == number of references *  * *******************************************************************//* common variables: reconstruct after callout  * Either have these variables callee saved or recompute them * after returning from the callout */#define VSS_BASE     REGISTER_NUMBER(REG_S8)#define QC_REG       REGISTER_NUMBER(REG_T1)#define PA_REG       QC_REG#define MMU_REG      REGISTER_NUMBER(REG_T0)#define MMUMASK_REG  REGISTER_NUMBER(REG_V1)/* volatile registers: save to EMP before callout. Restore from EMP * Note that the clock and ihit must be adjusted.  * Ideally, these registers are caller saved.  */#define CLOCK_REG    REGISTER_NUMBER(REG_T7)#define IHIT_REG     REGISTER_NUMBER(REG_T8)#define DHIT_REG     REGISTER_NUMBER(REG_T9)/* internal registers: save to stack if caller saved *  * As non-intuitive as this might seem, PC_REG and curEmp->PC * MUST BE KEPT incoherent, the first walue corresponds * to the start ot the BB while the second one is updated on * callouts !!!! * Note that there is an incentive of having them callee saved. * If we support mid-translation context switches, we must  * save the BRANCHREG and the PC_REG in the saveArea.  */#define BRANCHREG    REGISTER_NUMBER(REG_T5)#define PC_REG       REGISTER_NUMBER(REG_S5)#define UNUSED       REGISTER_NUMBER(REG_T2)/* shadow registers: save to stack if caller saved * Again, there is an incentive of having them callee * saved.  */#define SHADOW0      REGISTER_NUMBER(REG_S0)#define SHADOW1      REGISTER_NUMBER(REG_S1)#define SHADOW2      REGISTER_NUMBER(REG_S2)#define SHADOW3      REGISTER_NUMBER(REG_S3)#define SHADOW4      REGISTER_NUMBER(REG_S4)#define SHADOW5      REGISTER_NUMBER(REG_S6)#define SHADOW6      REGISTER_NUMBER(REG_S7)/* DON'T USE $AT!!! VCODE CAN USE $AT and this * CAN HOSE US BIG TIME. Should fix vcode, but for now * play it safe. XXX -BL *//* #define SHADOW7      REGISTER_NUMBER(REG_AT) */#define REGALLOC_LIST {SHADOW0,SHADOW1,SHADOW2, \                       SHADOW3,SHADOW4,SHADOW5, \                       SHADOW6,0}#ifdef OBSOLETE/* This is used to hold the old PC, so we can see if we are *//* transfering to code on the same page */#define OLD_PC         REGISTER_NUMBER(REG_S3)/* In MP_IN_UP, we store the old PC directly in the state structure, *//* so we use it to provide guarantees on interleaving between *//* processors It holds the threshold which, with CLOCK_REG falls under *//* this value, we context switch*/#define  TQUANTUM_REG     REGISTER_NUMBER(REG_S3)#endif#endif /* EMBRA_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -