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

📄 driver.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
   ASSERT( (EMP[cpuNum].PC & 0x3) == 0 );   /* CPUWarning("EMBRA: entering TC \n"); */   if( clobber_machine_regs ) {      gettimeofday(&run_start);      curEmp = &EMP[cpuNum];      /* Save where we are; we return here on a ReenterTC */      if (setjmp(Embra_Run_Setjmp) != 2)	/* Enter TC - never returns*/	EnterTC(curEmp);      else	EnterTC_CX(curEmp); /* Enter TC and switch */      /* Never reached */      ASSERT(0);   }}voidProcRemove( int cpuNum ){   ASSERT( embra.MPinUP );   ASSERT( cpuNum < TOTAL_CPUS );   ((EmbraState*)EMP[cpuNum].prev)->next = EMP[cpuNum].next;   ((EmbraState*)EMP[cpuNum].next)->prev = EMP[cpuNum].prev;   /* Aid Debugging -- dont reset next because I need it to schedule */   /* the next guy */   EMP[cpuNum].prev = 0;}voidProcInsertFirst( int cpuNum ){   ASSERT( embra.MPinUP );   ASSERT( cpuNum < TOTAL_CPUS );   EMP[cpuNum].next = EMP[TOTAL_CPUS].next;   EMP[cpuNum].prev = &EMP[TOTAL_CPUS];   ((EmbraState*)EMP[TOTAL_CPUS].next)->prev = &EMP[cpuNum];   EMP[TOTAL_CPUS].next = &EMP[cpuNum];}void ProcInsert( int cpuNum ){   EmbraState *t = &EMP[TOTAL_CPUS];   ASSERT( cpuNum < TOTAL_CPUS );   ASSERT( !EMP[cpuNum].prev );   while (cpuNum > t->next->myNum ) {      t = t->next;   }   EMP[cpuNum].next = t->next;   EMP[cpuNum].prev = t;   t->next->prev = & EMP[cpuNum];   t->next = & EMP[cpuNum];}intProcListEmpty(void){   ASSERT( embra.MPinUP );   return EMP[TOTAL_CPUS].next == &EMP[TOTAL_CPUS];}static SimTime stallStart[NUM_MODES][SIM_MAXCPUS];static CPUMode stallMode[SIM_MAXCPUS]; /* Sanity Check *//* ********************************************** * Descheduling to speed up Embra boot * **********************************************/void EmbraPromReleaseInit(void){   deschedNumCPUs = 0;}void EmbraPromRelease(void *p1, void *p2){   int i;   CPUWarning("Releasing CPUs. \n");   for(i=0;i<TOTAL_CPUS;i++) {      if( !EMP[i].outOfSlaveLoop && sim_misc.launchAddr[i]) {         CPUWarning("EmbraPromRelease, launching %i \n",i);         deschedNumCPUs++;         ProcInsert(i);      }   }}/* ****************************************************************** * EmbraConfigureTC * ******************************************************************/#define LOG_TC_USER_SIZE 22#define LOG_TC_KERN_SIZE 20#define LOG_TC_GLUE_SIZE 12#define TCFLUSH_USER 0x0#define TCFLUSH_KERN 0x1#define TC_USER_NUM (1<<LOG_TC_USER_SIZE)#define TC_KERN_NUM (1<<LOG_TC_KERN_SIZE)#define TC_GLUE_NUM (1<<LOG_TC_GLUE_SIZE)#define TC_USER_SIZE (TC_USER_NUM * 4 )#define TC_KERN_SIZE (TC_KERN_NUM * 4 )#define TC_GLUE_SIZE (TC_GLUE_NUM * 4 )#define TC_ANNOTATION_BUFFER (32*1024)#define MIPS_COMPOSE_I_OP(opCode, rt, rs, immed) ((opCode) << 26 | (rs) << 21 | (rt) << 16 | ((immed) & 0xffff ))#define TC_BREAKOPCODE  MIPS_COMPOSE_I_OP(cop0_op,0,mfc_op,0);/* Note we also allocate space for our dynamically * generated interface code (see main_run.c) as * well as the actual translation caches; * we hope that these are within jump range */static void EmbraConfigureTC(void){   int tcSize[3];   int tcAnnSize[3];   int pctcSize[3];   Inst breakOp = TC_BREAKOPCODE;   /*    * init TC    */      tcSize[0] = TC_USER_SIZE;   tcSize[1] = TC_KERN_SIZE;   tcSize[2] = TC_GLUE_SIZE;   tcAnnSize[0] = TC_ANNOTATION_BUFFER;   tcAnnSize[1] = TC_ANNOTATION_BUFFER;   tcAnnSize[2] = 2;   pctcSize[0] = TC_USER_SIZE / (4*8);   pctcSize[1] = TC_KERN_SIZE / (4*8);   pctcSize[2] = 2;      TC_init(3,tcSize,pctcSize,tcAnnSize,breakOp); }/* This clears all data structures associated with a translation chache */void Clear_Translation_State(int cache ){   int i;   /* Need to clear (now stale) return addresses from inside CPU state */   /* structures */    for( i = 0; i < TOTAL_CPUS; i++ ) {      if( EMP[i].stalled ) {         EMP[i].jumpPC = (uint)(void*)continue_run_without_chaining;         /*EmContinueStall;*/      } else {         EMP[i].jumpPC = (uint)continue_run_without_chaining;      }   }      if (cache==TCFLUSH_ALL) {       /*       * conflict detected. flush everything.       * Only at this point can be clear the tccoherence information       * XXX maybe we should split it by TC cache       */      TCcoherence_flush();      /* Note we don't want to flush our dynamic code!!       * Only flush User and Kernel TC's       */      TC_flush(TCFLUSH_USER);      TC_flush(TCFLUSH_KERN);   }   else {     TC_flush(cache);   }}/*****************************************************************//* Debugging function called from continue_run */void print_pc( int cpuNum, unsigned pc ){   if( EMP[cpuNum].outOfSlaveLoop ) {      CPUPrint("%d 0x%x\n", EMP[cpuNum].myNum, pc );      fflush( stdout );   }}void AssertNotStalled(int cpuNum){   VASSERT(!EMP[cpuNum].stalled, ("CpuNum %d\n", cpuNum) );}/* This is only used when simulating R3k locking *//* It doesn't work anymore because of cpuNum */void TNS( int cpuNum ){   int retval;   volatile int* lock_ptr;   lock_ptr = (volatile int*)(EMP[cpuNum].R[4]);   if ( *lock_ptr & 1 ){      retval = 0;   } else {      *lock_ptr = EMP[cpuNum].R[8];      retval = 1;   }   EMP[cpuNum].R[8] = retval;}/* Called when a checkpoint is requested.*/void EmbraCheckpoint(int cpuNum){   int i;   VA oldPC[SIM_MAXCPUS];   ASSERT( cpuNum==0);   for (i=0;i<TOTAL_CPUS;i++) {       oldPC[i] = EMP[i].PC;      if( IS_BACKDOOR(EMP[i].PC) ) {         /* PC was in the backdoor. In embra, this can only be the          * case for the processor requesting the checkpoint.           * We save the RA rather than the PC          */       EMP[i].PC  = EMP[i].R[REG_RA];      }      if (IN_BD(EMP[i].PC)) {         if ( EmbraAnnType() == ANNFM_PC_TYPE) {            CPUError("CANNOT TAKE CHECKPOINT IN A BRANCH DELAY with a post-pc annotation -- at least not now \n");         }          EMP[i].PC = CLEAR_BD(EMP[i].PC)-INST_SIZE;      } else {          if (i==CPUVec.CurrentCpuNum() &&             EmbraAnnType()== ANNFM_PC_TYPE ) {            EMP[i].PC += INST_SIZE;         }      }     }   Simcpt_Checkpoint(CPT_SAVE, NULL);   CPUWarning("\n-> Simcheckpoint: Returning from checkpoint save...\n");   for (i=0;i<TOTAL_CPUS;i++) {      EMP[i].PC = oldPC[i];   }                         }                     /* ********************************************************************* * Embra_DoAnn: (TC callout)  * Handles PC annotations * *********************************************************************/void Embra_DoAnn( int cpuNum) {   VA annAddr = CLEAR_BD(EMP[cpuNum].PC);   AnnPtr aptr;   ASSERT (curEmp->myNum==cpuNum);#if defined(SIM_MIPS64)   if (IS_CKSEG0(annAddr)) {      annAddr = CKSEG0_TO_XKPHYS(annAddr);   }#endif   aptr = AnnFMLookup(annAddr,ANNFM_PC_TYPE);   ASSERT(aptr);   /*     * Call EmbraAnnExec to trap the case where    * the annotation has side-effects    */   EmbraAnnExec(cpuNum,aptr,ANNFM_PC_TYPE);}void Embra_DoPrePCAnn( int cpuNum) {   VA annAddr = CLEAR_BD(EMP[cpuNum].PC);   AnnPtr aptr;   ASSERT (curEmp->myNum==cpuNum);   aptr = AnnFMLookup(annAddr,ANNFM_PRE_PC_TYPE);   ASSERT(aptr);   /*     * Call EmbraAnnExec to trap the case where    * the annotation has side-effects    */   EmbraAnnExec(cpuNum,aptr,ANNFM_PRE_PC_TYPE);}static void VerifyOffsets(void){   /* checking a couple of the fields of CPUState */   ASSERT(  GP_OFF == offsetof(CPUState,R));   ASSERT(  FP_OFF == offsetof(CPUState,FPR));   ASSERT(  FCR_OFF == offsetof(CPUState,FCR));   ASSERT(  CP0_OFF == offsetof(CPUState,CP0));   ASSERT(  PC_OFF == offsetof(CPUState,PC));   ASSERT(  HI_OFF == offsetof(CPUState,HI));   ASSERT(  LO_OFF == offsetof(CPUState,LO));   ASSERT(  CCD_OFF == offsetof(CPUState,cycleCountdown));   ASSERT(  BCCD_OFF == offsetof(CPUState,blockCycleCountdown));   ASSERT(  TQ_OFF == offsetof(CPUState,timeQuantum));   ASSERT(  MMU_OFF == offsetof(CPUState,mmu));   ASSERT(  CACHE_OFF == offsetof(CPUState,cache_tag));   ASSERT(  SDHIT_OFF == offsetof(CPUState,Sdhit_count));   ASSERT(  SIHIT_OFF == offsetof(CPUState,Sihit_count));   ASSERT(  SSTACK_OFF == offsetof(CPUState,Sstack_base));   ASSERT(  SSREG2_OFF == offsetof(CPUState,Ssreg2));   ASSERT(  SORIGSTACK_OFF == offsetof(CPUState,Sorig_stack));   ASSERT(  MYNUM_OFF == offsetof(CPUState,myNum));   ASSERT(  NEXT_OFF == offsetof(CPUState,next));   ASSERT(  OLDPC_OFF == offsetof(CPUState,oldPC));   ASSERT(  JUMPPC_OFF == offsetof(CPUState,jumpPC));   ASSERT(  CALL_OFF == offsetof(CPUState,eventQueueTimePtr));   ASSERT(  HICC_OFF == offsetof(CPUState,cycleCount));   ASSERT(  LOCC_OFF == offsetof(CPUState,cycleCount)+4);   ASSERT(  STALLED_OFF == offsetof(CPUState,stalled));   ASSERT(  CACHE_AX_OFF == offsetof(CPUState,cache_ax));   ASSERT(  LLCONTENTS_OFF == offsetof(CPUState,LLContents));   ASSERT(  LLADDR_OFF == offsetof(CPUState,LLAddr));   ASSERT(  HACKADDR_OFF == offsetof(CPUState,hackedSavedVaddr));   ASSERT(  LLBIT_OFF == offsetof(CPUState,LLBit));   ASSERT(  FPLOADED_OFF == offsetof(CPUState,fpLoaded));   ASSERT(  OUTTC_OFF == offsetof(CPUState,outTC));   ASSERT(  QCRA_OFF  == offsetof(CPUState,qcra));}

⌨️ 快捷键说明

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