📄 driver.c
字号:
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 + -