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

📄 page.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ***************************************************************************//* *                                                                         *//* * page.c - does some memory allocation, plus paging for "virtual memory"  *//* *                                                                         *//* ***************************************************************************//* This code was liberated from flashlite, hence the copyright:              *//* ************************************************************************* *//* *                                                                       * *//* *               Copyright (C) 1993-1998 Stanford University             * *//* *                                                                       * *//* *  These coded instructions, statements, and computer programs contain  * *//* *  unpublished proprietary information of Stanford University, and      * *//* *  are protected by Federal copyright law.  They may not be disclosed   * *//* *  to third parties or copied or duplicated in any form, in whole or    * *//* *  in part, without the prior written consent of Stanford University.   * *//* *                                                                       * *//* ************************************************************************* *//*#define COMA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "solo.h"#include "simtypes.h"#include "sim_error.h"#include "solo_page.h"#include "cp0.h"#include "tcl_init.h"#include "params.h"#ifdef USE_FLASHLITE# include "machine.h"# ifdef FLASHPOINT#  include "mipsy_interface.h"#  include "flash_interface.h"# endif#endif#include "pcache.h"		/* So we know the MHT size */#include "scache.h"		/* So we know the MHT size */#include "bstring.h"#define MINIMUM_VA_VALUE	100#define ONE_MEGABYTE	0x100000/* padding so that comaHACKADDR  * is on a FLASH cacheline of its * own.  We need to avoid a situation * where it is on the same cache line * as soloActiveProcs...bad things * happen if it is!!! */static struct garbage {  int PAD[128];  int comaHACKADDR;  int PAD1[128];} junk;#ifdef COMAvoid SysPlaceRangeCOMAHack(unsigned procNum, FLASHAddress addrToDelete);#elsevoid SysPlaceRangeCOMAHack(unsigned procNum, FLASHAddress addrToDelete) {}#endifint soloPACompressNodeShift;uint soloPACompressOffsetMask;uint soloLockBase;uint soloBarrierBase;uint soloTotalMemory;static int nextclus = 0;       /* next processor to assign pages to */static unsigned *cachepage;	/* array of next cacheable space page numbers */static int totalProcs;   /* Number of processors on system */static int totalMemPerProc; /* Memory per node */static int applicationMemoryStart;  /* ??? */static enum { ROUND_ROBIN, FIRST_TOUCHED} allocationPolicy;/* Global FlashLite declarations *//* local function prototypes */static void InitPageTrans(void);static void InitMemAllocation(void);static int NumBits(unsigned number);static bool RemoveMapping(VA v_addr);#ifdef FLASHPOINT// I need to call this from solo_anl.c when using flashpointbool GetPhysicalAddr(VA v_addr, SoloPA *p_addr, uint *flavor);SoloPA AllocatePage(int module, VA va);void NewMapping(VA v_addr, SoloPA p_addr,  uint flavor);#elsestatic bool GetPhysicalAddr(VA v_addr, SoloPA *p_addr, uint *flavor);static SoloPA AllocatePage(int module, VA va);static void NewMapping(VA v_addr, SoloPA p_addr,  uint flavor);#endifstatic void TrySysPlaceRange(int cpuNum, EventCallbackHdr *hdr, void *v);static EventCallbackHdr sys_place_range_callback;static int sys_place_range_tries;static VA sys_place_range_start;static VA sys_place_range_stop;static int sys_place_range_node;int sys_place_range_StallCPUS = 0;static unsigned *nextPageFrame;static char *protocol;#define SYS_PLACE_RANGE_QUIESCENT_TIME	100000#define SYS_PLACE_RANGE_MAX_TRIES	15void SoloInitPageTranslation(void){   InitMemAllocation();   InitPageTrans();   ParamLookup(&protocol, "MEMSYS.FLASH.Protocol", PARAM_STRING);}voidSolosys_place_range(VA start, VA stop, int node){   SoloPA pa;   VA 	va;   int oldNode;   uint flavor;   int i;#ifdef DEBUG_PAGE_VERBOSE   CPUPrint( "sys_place_range %d: Allocating range %x to %x\n",      node, start, stop);#endif   pa = 0LL;   va = start & SOLO_PAGE_NUMBER_MASK;   do {      if (!GetPhysicalAddr(va, &pa, &flavor))   {	 ASSERT(node < totalProcs);         pa = AllocatePage(node, va);	 NewMapping( va, pa, TLB_CACHED);      } else {         oldNode = SOLO_PA_NODE(pa);	 if (oldNode != node) {#ifdef DEBUG_PAGE_VERBOSE	    CPUWarning("sys_place_range %u: Moving page %x (%llx) from %d to %d\n",                        node, va, pa, oldNode, node);#endif	    sys_place_range_StallCPUS = 1;				/* Tell all the CPU's not to do anything */	    sys_place_range_tries = 0;	    sys_place_range_start = va;	    sys_place_range_stop = stop;	    sys_place_range_node = node;	    sys_place_range_callback.active = 0;	    EventDoCallback(soloCPUNum, TrySysPlaceRange,			    &sys_place_range_callback, 0,			    SYS_PLACE_RANGE_QUIESCENT_TIME);	    break;		/* TrySysPlaceRange will loop for me */	 }      }      va += SOLO_PAGE_SIZE;   } while (va < stop);} static voidTrySysPlaceRange(int cpuNum, EventCallbackHdr *hdr, void *v){   SoloPA pa, currentPA;   PA realPA;   FLASHAddress transit;   VA 	va, currentVA;   int cpu, i, j, result, wasDirty;   int oldNode;   uint flavor;   int node = sys_place_range_node;#define LINE_BUFFER_SIZE 1024   char data[LINE_BUFFER_SIZE];#ifdef DEBUG_PAGE_VERBOSE   CPUPrint( "TrySysPlaceRange %d: Moving VA range %8.8x to %8.8x\n",	     node, sys_place_range_start, sys_place_range_stop);#endif   ASSERT(LINE_BUFFER_SIZE >= SCACHE_LINE_SIZE);   /* Check MHT's to see if anything is outstanding */   for (i=0; i<soloActiveProcs; i++) {      for (j = 0; j < MHT_SIZE; j++) {         if (CACHE[i].MHT[j].inuse) {	    CPUPrint("sys_place_range %u: wakeup %d found MHT %d, entry %d in use\n",		     cpuNum, sys_place_range_tries, i, j);	       sys_place_range_tries++;	       if (sys_place_range_tries >= SYS_PLACE_RANGE_MAX_TRIES) {		  CPUError("sys_place_range %u: too many tries with MHT full\n",cpuNum);	       }	       EventDoCallback(cpuNum, TrySysPlaceRange,			       &sys_place_range_callback, 0,			       SYS_PLACE_RANGE_QUIESCENT_TIME);	       return;	 }      }   }   /* Ok, MHT's seem clean, so let's clean up the caches. Now when I find mappings      already established, I go ahead and move them.  Grab on to your socks.*/      ASSERT(node < totalProcs);   va = sys_place_range_start;   do {      if (!GetPhysicalAddr(va, &pa, &flavor))   {         pa = AllocatePage(node, va);	 NewMapping( va, pa, TLB_CACHED);      } else {         oldNode = SOLO_PA_NODE(pa);	 if (oldNode != node) {	    for (cpu=0; cpu<soloActiveProcs; cpu++) {	       for (currentPA = pa, currentVA = va;		    currentPA < pa + SOLO_PAGE_SIZE;		    currentPA += SCACHE_LINE_SIZE,		       currentVA += SCACHE_LINE_SIZE) {		  realPA = SoloCompressAddr(currentPA);		  if (CacheExtract(cpu, realPA, SCACHE_LINE_SIZE,				   &wasDirty, (char *)data)) {		     if (wasDirty) {			bcopy(data, (char *)currentVA, SCACHE_LINE_SIZE);                         if (!strcmp(protocol,"COMA")) {                           transit.ll = currentPA;                           SysPlaceRangeCOMAHack(cpu, transit);                        }		     }		  }	       }	    }	    /* Do the actual remapping operation */	    CPUPrint("sys_place_range %u: Moving page %x (%llx) to %d\n",		     cpuNum, va, pa, node);            if (!RemoveMapping(va)) {               CPUError("RemoveMapping failed though mapping exists!\n");            }	    pa = AllocatePage(node, va);	    NewMapping(va, pa, TLB_CACHED);	    CPUPrint("sys_place_range %u: VA %x now at PA %llx\n",		     cpuNum, va, pa);	 }      }      va += SOLO_PAGE_SIZE;   } while (va < sys_place_range_stop);   sys_place_range_StallCPUS = 0;}   /* ****************************************************************************//* *   V_to_P  maps virtual to physical addresses                            **//* *            - global cacheble space assigned round-robin                 **//* *            - private cacheable space assigned to home cluster           **//* ****************************************************************************/SoloPASoloV_to_P(int proc, VA va, int clus, bool isFrame, uint *tlbFlavor){   SoloPA pa;   bool	retVal;   uint flavor;#ifdef DEBUG_PAGE_VERBOSE   CPUPrint( "V_to_P %u: Translating %x", proc, va);#endif#ifdef T5_MODEL   pa = (LL) va;#ifdef DEBUG_PAGE_VERBOSE   CPUPrint( "\nV_to_P %u: Returning PA==VA\n", proc);#endif   return pa;#else      pa = 0LL;   if (va < MINIMUM_VA_VALUE) {      CPUError("\nV_to_P %d: Got virtual address 0x%x\n", proc,va);   }      /* Check for references to other spaces */   if (va & VIRTUAL_MSG_MASK) {      /* This is MSG space */#ifdef USE_FLASHLITE	 retVal = GetPhysicalAddr((va & 0x7fffffff), &pa, &flavor);	 ASSERT(retVal); ASSERT(flavor == TLB_CACHED);         pa |= (MSG << SOLO_PA_SPACE_SHIFT);	 *tlbFlavor = TLB_UNCACHED;	 flavor = TLB_UNCACHED; /* this is so the (*tlbFlavor) below */                                /* doesn't squash the uncached setting. */#ifdef DEBUG_PAGE_VERBOSE      CPUPrint("\nMSG_SPACE Returning translation %16.16llx\n",	       pa);#endif#else      CPUError("\nBad access to VA 0x%x\n",va);#endif   } else if (!GetPhysicalAddr(va, &pa, &flavor)) {      int node;      if (isFrame == FALSE)  {  /* global */	 if (allocationPolicy == ROUND_ROBIN) {	    nextclus = ((va & SOLO_PAGE_NUMBER_MASK) >> SOLO_PAGE_SHIFT) &	       (totalProcs - 1);	    node = nextclus;	 } else {  /* first touched */	    node = clus;	 }      } else {					/* private */	 node = proc;      }      ASSERT(node < totalProcs);      pa = AllocatePage(node, va);      NewMapping(va, pa, TLB_CACHED);      flavor = TLB_CACHED;   }   (*tlbFlavor) = flavor;#ifdef DEBUG_PAGE_VERBOSE   CPUPrint( "Resulting translation --> %16.16llx\n", pa);#endif   return pa;#endif /* T5_MODEL */}boolSoloPageHasBeenMapped(VA vaddr){   SoloPA paddr;   uint flavor;   return (GetPhysicalAddr(vaddr, &paddr, &flavor));}voidSoloEstablishMapping(SoloPA pa, VA va, int space, uint tlbFlavor){   SoloPA addr;   uint flavor;   /* Make sure we don't have a normal mapping of this virtual address */   /* to some other physical address */   if (GetPhysicalAddr(va, &addr, &flavor)) {#ifdef DEBUG_PAGE_VERBOSE      CPUPrint( "EstablishMapping: flushing old mapping!\n");#endif      if (!RemoveMapping(va)) {	 CPUError("RemoveMapping failed though old mapping exists!\n");      }   }   addr = SOLO_FORM_PA(SOLO_PA_NODE(pa),space,SOLO_PA_OFFSET(pa));                  /* Be sure space is set in mapping */   NewMapping(va, addr, tlbFlavor);}intSoloGetHome(unsigned vaddr){   SoloPA paddr;   uint flavor;   if (GetPhysicalAddr(vaddr, &paddr, &flavor) == FALSE) {      return -1;   }   else {      return SOLO_PA_NODE(paddr);   }}/* *************************************************************************** *//* *  AllocatePage allocates the next page of cacheable space           * *//* *************************************************************************** */SoloPAAllocatePage(int module, VA va){   VA pageFrame;   unsigned numFrames;   PA offset;   /* Used for COMA only */   LL current, upperBound, lowerBound;   unsigned reservedMemoryPerNode = 0;   if (!strcmp(protocol,"COMA")) {      ParamLookup(&reservedMemoryPerNode, "MEMSYS.FLASH.ReservedMemoryPerNode",                  PARAM_INT);   }   ASSERT(module < totalProcs);   numFrames = ONE_MEGABYTE >> SOLO_PAGE_SHIFT;   /*   pageFrame = (va & (ONE_MEGABYTE - 1)) >> SOLO_PAGE_SHIFT;*/   if (nextPageFrame[module] >= soloLockBase) {      nextPageFrame[module] = 0;   }   pageFrame = nextPageFrame[module];   nextPageFrame[module] = (nextPageFrame[module] + 1) %      (ONE_MEGABYTE >> SOLO_PAGE_SHIFT);   ASSERT(cachepage[(module * numFrames) + pageFrame] !=      (totalMemPerProc/ONE_MEGABYTE));   cachepage[(module * numFrames) + pageFrame]++;#define LOG_ONE_MB 20   if (!strcmp(protocol,"COMA")) {      if (reservedMemoryPerNode > 0) {         lowerBound = (LL)((module*reservedMemoryPerNode)%totalMemPerProc);

⌨️ 快捷键说明

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