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

📄 driver.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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.  * *//**************************************************************** * driver.c * This file contains the entry points to mshade.  The init functions * in this file are responsible for initializing all of the needed * data structures. * We also try to concentrate the policy #defines in this file. *  * Author: $Author: bosch $ * Date:   $Date: 1998/02/10 00:30:32 $ *****************************************************************/#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <strings.h>#include <unistd.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/time.h>#include <fcntl.h>#include <setjmp.h>#include "simmisc.h"#include "annotations.h"#include "checkpoint.h"#include "embra.h"#include "driver.h"#include "tc.h"#include "translator.h"#include "mem_control.h"#include "callout.h"#include "main_run.h"#include "cp0.h"#include "clock.h"#include "qc.h"#include "cache.h"#include "stats.h"#include "embra_interface.h"#include "directory.h"#include "decoder.h"#include "stats.h"#include "clock.h"#include "simutil.h"#include "tcl_init.h"#include "debug.h"#include "tc_coherence.h"CptCallback EmbraExecStateCheckpointCB;/* Globals *//* Wouldn't it be nice if we lived in a world where compiliers could   deal with alignment information?  That way maybe our much abused   typing system in C could stand a ghost of a chance */#ifdef COMMENTOUTunsigned PE_space[ ( SIM_MAXCPUS * sizeof(EmbraState) + DEFAULT_PAGESZ)/                   sizeof(unsigned)];#endifEmbraState* EMP;/*int curr_cpu; */EmbraState* curEmp;EmbraParams embra;jmp_buf embra_env;struct timeval run_start;struct timeval run_end;/* This is necessary to allow the cp0 module to fool the rest of us *//* into thinking that ASID 0 never runs *//* It is set in cp0.c */int quick_ASID[SIM_MAXCPUS];#if 0 int EmUseETLB = 0;int barrCPUs = 0;int MPinUP = 0;int useVQC = 0;int K0FromDevZero = 0;int alreadyAlloc = 0;#endifint* gBarrier = 0;int* debugBarrier = 0;int* checkpointBarrier = 0;int* tnsLock = 0;int* exitBarrier = 0;int deschedNumCPUs = -1;/* XXX - this is really depended on CPUType */int log2sizeofcputype = 2;static void EmbraConfigureTC(void);static void VerifyOffsets(void);/* On startup the mmu gets initialized, so we must go through   and zero out the appropriate pages.  We could just rely   on the fact that qc_map_page won't map pages with annotations,   but this will make sure kernel addresses are zerod out.*/voidEmbraInstallMemAnnotation(VA vAddr) {   uint page = PAGE_NUMBER(vAddr);   if (embra.emode == EMBRA_PAGE) {      if (TOTAL_CPUS==1 || embra.MPinUP) {         int cpu;         for (cpu = 0; cpu < TOTAL_CPUS; cpu++) {#ifdef EMBRA_USE_QC64            qc64_remove_addr(cpu,vAddr);#else            EMP[cpu].mmu[page] = 0;#endif         }      } else {         CPUWarning("Fix InstallMemAnnotations for MPinMP\n");      }   } else {   }}C_LINK int _is_mips2(void);void Embra_Init(int cpuNum, int swtch){   static int embra_initialized;   /* Should always be up to date *//*  curr_cpu = cpuNum; */   VerifyOffsets();   curEmp = &EMP[cpuNum];   if( !embra_initialized ) {      embra_initialized = 1;      /* Quick runtime way of deciding if we are on an R4000 */      if( !_is_mips2()  ) {         CPUPut("Embra only runs on machines that supports at least the mips2 ISA\n");         exit( 1 );      }      EmbraClockInit();      if( embra.MPinUP ) {         int i;         EmbraState *state = &EMP[TOTAL_CPUS];         for( i = 0; i <= TOTAL_CPUS; i++ ) {            EMP[i].myNum = i;            EMP[i].myBit = (1<<i);            /* Assume that if any cpu is out of slave loop, then they */            /* all are */             /*if( EMP[TOTAL_CPUS-1].outOfSlaveLoop ) {*/            if( deschedNumCPUs >= 0 && EMP[i].outOfSlaveLoop ) {                state->next = &EMP[i];               EMP[i].next = &EMP[TOTAL_CPUS];               state = state->next;               deschedNumCPUs++;            }            if( deschedNumCPUs < 0  ) {                if( 1 ) {                  EMP[i].next = &EMP[(i+1)%(TOTAL_CPUS+1)];                  /* Either C handles mod wierd, or I learned them wrong */                  if( i == 0 )                     EMP[i].prev = &EMP[TOTAL_CPUS];                  else                     EMP[i].prev = &EMP[(i-1)%(TOTAL_CPUS+1)];               } else {                   /* Then we must be booting so only add CPU 0 */                  EMP[0].next = &EMP[TOTAL_CPUS];                  EMP[TOTAL_CPUS].next = &EMP[0];               }            }         }         /*          * figure out the backpointer in the doubly linked list          */         ASSERT( EMP[TOTAL_CPUS].next != &EMP[TOTAL_CPUS]);         for(state = &EMP[TOTAL_CPUS]; !state->next->prev;state = state->next) {            state->next->prev = state;         }      } else {         EMP[cpuNum].myNum = cpuNum;         EMP[cpuNum].myBit = (1<<cpuNum);      }      gBarrier          = ZMALLOC(256,"Embra::gBarrier");      debugBarrier      = ZMALLOC(256,"Embra::debugBarrier");      checkpointBarrier = ZMALLOC(256,"Embra::checkpointBarrier");      exitBarrier       = ZMALLOC(256,"Embra::exitBarrier");      tnsLock           = ZMALLOC(256,"Embra::tnsLock");   }         Embra_Clock_Init(cpuNum);   /* Initialize translation caches & space for dynamic interface code */   EmbraConfigureTC();   /* Initialize interface code and register allocation stuff */   Translator_Init();   /* Initialize maxInGroup */   DecoderInit();   Stat_Init();   emSMHT = ZMALLOC(TOTAL_CPUS * sizeof(EmSMHT),"Embra:SMHT");    TCcoherence_init(SIM_MEM_ADDR(0));   Cache_Init(cpuNum);   Em_Tlb_Init(cpuNum, swtch);   Directory_Init();     Cache_Init(cpuNum);   if (cpuNum == 0) {      if (embra.emode == EMBRA_PAGE) {         AnnFMInit(DEFAULT_PAGESZ);      } else {         /* embra.emode == EMBRA_CACHE */         AnnFMInit(SCACHE_LINE_SIZE);      }      if (!swtch) {         AnnCommonSetup();      }   }     if( embra.MPinUP ) {      /* XXX - Note the space for the extra processor is not actualy */      /* mapped shared. It should be allocated elsewhere */      /* The mythical extra processor just holds the callback address */      EMP[TOTAL_CPUS].PC = (Reg)EmEventPoll;      EMP[TOTAL_CPUS].R[31] = (Reg)EmEventPoll;      /* This needs to be set for the code in main_run which tries to do a */      /* lookup on the PC, but it is a backdoor, so that look up will */      /* fail.   May want to check for backdoor directly in that code */      EMP[TOTAL_CPUS].mmu = EMP[0].mmu;      /* Have to activate this processor */      EMP[TOTAL_CPUS].outOfSlaveLoop = 1;   }}void Init_Proc_State(int cpu ){   EMP[cpu].Sdhit_count = 0;   EMP[cpu].Sihit_count = 0;   EMP[cpu].jumpPC = (uint)continue_run_without_chaining;   /* Shave 32 bytes off so routines called by continue_run can */   /* store into it and continue_run itself can store 4 words */   if((embra.emode == EMBRA_PAGE)||(!embra.useVQC))      EMP[cpu].Ssreg2 = 0x7fffffff;}/* This setjmp allows us to unwind the stack (e.g. after we've flushed * the translation cache, taken exceptions, etc.) and return to * running in the TC */jmp_buf Embra_Run_Setjmp;/* We call this routine to unwind the stack and continue running * in the TC */void ReenterTC(EmbraState *emp){  curEmp = emp;  longjmp(Embra_Run_Setjmp, 1);  /* Not Reached */  ASSERT(0);}/* We call this routine to unwind the stack and continue running * in the TC */void ReenterTC_CX(EmbraState *emp){  curEmp = emp;  longjmp(Embra_Run_Setjmp, 2); /* 2 -> do context switch */  /* Not Reached */  ASSERT(0);}/* This is the entry point to Embra. Embra_Init should be called *//* before calling this function */void Embra_Run( int cpuNum, int clobber_machine_regs ){  /* Call the main run routine which does translation on the fly. */  /* Note that the stack grows down, so we start at the top */   if( embra.MPinUP ) {      int cpu;      for( cpu = 0; cpu <= TOTAL_CPUS; cpu++ ) {         Init_Proc_State(cpu);         CPUPrint("%d entering TC at 0x%x\n", cpu, EMP[cpu].PC);      }      EMP[TOTAL_CPUS].jumpPC = (Reg)EmEventPoll;   } else {      Init_Proc_State(cpuNum);      CPUPrint("%d entering TC at 0x%x\n", cpuNum, EMP[cpuNum].PC);   }   ASSERT(embra.emode == EMBRA_PAGE ||embra.sequential || EMP[cpuNum].outTC );

⌨️ 快捷键说明

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