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

📄 flash_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
static void FlashliteInitRemap(void);static voidInitSimosMemoryMap(void){   char *addrMapType;   int i, memPerProc = 0;   memsysVec.MemsysSetRemap = FlashliteSetRemap;   memsysVec.MemsysControlRemap = FlashliteControlRemap;   memsysVec.MemsysGetNodeAddress = FlashliteGetNodeAddress;   FlashliteInitRemap();   ParamLookup(&addrMapType, "MEMSYS.FLASH.FlashAddrMap", PARAM_STRING);   if (addrMapType == NULL)       addrMapType = "ZeroOnly";   simosPageToNode = (signed char *) calloc(1,MEM_SIZE(0)/FLASH_PAGE_SIZE);   ParamLookup(&memPerProc, "MEMSYS.FLASH.TotalMemPerProc", PARAM_INT);   bytesPerNode_shift = GetLog2(MEM_SIZE(0)/NUM_CPUS(0));   ASSERT(MEM_SIZE(0) == ((1<<bytesPerNode_shift) * NUM_CPUS(0)));   nodeOffsetMask = (1<<bytesPerNode_shift) - 1;/* Hive currently uses only a single remap page, but using 2 pages just to be safe.   There's an assert in remap code anyway... */   directMapLimit = 2*FLASH_PAGE_SIZE;   if (!strcmp(addrMapType, "FirstTouch")) {      addrMap = FIRST_TOUCH;      ASSERT(MEM_SIZE(0) <= memPerProc);      for(i = 0; i < MEM_SIZE(0)/FLASH_PAGE_SIZE; i++)          simosPageToNode[i] = -1;      CPUPrint("FlashAddrMap is FirstTouch\n");   } else if (!strcmp(addrMapType, "RoundRobin")) {      int pagesPerMem = 0, stripewidth = 0;      addrMap = ROUND_ROBIN;      ASSERT(MEM_SIZE(0) <= memPerProc);      ParamLookup(&pagesPerMem, "MEMSYS.FLASH.RoundRobinStripe", PARAM_INT);      ParamLookup(&stripewidth, "MEMSYS.FLASH.NumFlashNodes", PARAM_INT);              if (stripewidth < 0) stripewidth = NUM_CPUS(0);      for(i = 0; i < MEM_SIZE(0)/FLASH_PAGE_SIZE; i++)          simosPageToNode[i] = (i/pagesPerMem) % stripewidth;      CPUPrint("FlashAddrMap is RoundRobin with stripe unit of %d\n",               pagesPerMem);   } else if (!strcmp(addrMapType, "HiveRoundRobin")) {      int pageNum, cell, cpu, ncpusPerCell, pagesPerCPU;      addrMap = HIVE_ROUND_ROBIN;      /* compact roundrobin memory layout:         pages are laid out across all cpus in cell using roundrobin allocation,         and the offset is same as for Hive.         */      ncpusPerCell = NUM_CPUS(0)/NUM_CELLS(0);      pagesPerCPU = MEM_SIZE(0)/NUM_CPUS(0)/FLASH_PAGE_SIZE;      ASSERT(MEM_SIZE(0)/NUM_CPUS(0) <= memPerProc);      CPUPrint("FlashAddrMap is HiveRoundRobin with ncells: %d\nncpusPerCell: %d\npagesPerCPU: 0x%x\nbytesPerNode_shift: %d   nodeOffsetMask: 0x%x   directMapLimit: 0x%x\n",               NUM_CELLS(0), ncpusPerCell, pagesPerCPU,               bytesPerNode_shift, nodeOffsetMask, directMapLimit);      for (cell = 0; cell < NUM_CELLS(0); cell++) {         for (cpu = 0; cpu < ncpusPerCell; cpu++) {            int CPU = cell*ncpusPerCell + cpu;            for (pageNum = pagesPerCPU*CPU; pageNum < pagesPerCPU*(CPU+1); pageNum++) {               simosPageToNode[pageNum] = cell*ncpusPerCell + ((pageNum + cpu) % ncpusPerCell);            }         }      }   } else if (!strcmp(addrMapType, "Hive")) {      int pageNum, numPages;      addrMap = HIVE;      ASSERT(MEM_SIZE(0)/NUM_CPUS(0) <= memPerProc);      numPages = MEM_SIZE(0)/FLASH_PAGE_SIZE;      for (pageNum = 0; pageNum < numPages; pageNum++) {         PA paddr = pageNum*FLASH_PAGE_SIZE;         int n;         for (n = NUM_CPUS(0)-1; n >= 0; n--) {            if (paddr >= remapVec->NodeAddr[n]) {               simosPageToNode[pageNum] = n;               break;            }         }      }            CPUPrint("FlashAddrMap is using the Hive mappings\n");   } else {      CPUPrint("FlashAddrMap is node zero only\n");   }#ifdef FIREWALL_HACK   FlashliteDownloadFirewall();#endif}/***************************************************************** * remap region support - XXX Once we get PPCs working this  * should use the remap support inside of flashlite. Until then * we fake it here.  *****************************************************************/static voidFlashliteInitRemap(void){   int i;   /* We initialize backmapMask to all ones except for the    * bits that might be set in the node id field    */   nodeaddrMask = ~0;   for (i=0; i<NUM_CPUS(0); i++) {      if (!remapVec->NodeAddrInitialized) {	 remapVec->NodeAddr[i] =             MEMADDR_TO_PHYS(0, SIM_MEM_ADDR(0) + i * (MEM_SIZE(0) / NUM_CPUS(0)));      }      nodeaddrMask &= ~remapVec->NodeAddr[i];   }   remapVec->NodeAddrInitialized = 1;}static voidFlashliteSetRemap(int cpunum, PA mask){   remapVec->RemapMask[cpunum] = mask;}static voidFlashliteControlRemap(int cpunum, int isEnabled){   remapVec->RemapEnable[cpunum] = isEnabled;   /* make sure directMapLimit is bigger than remap range */   if (isEnabled)      ASSERT(directMapLimit & remapVec->RemapMask[cpunum]);}static unsigned int FlashliteGetNodeAddress(int cpunum){   return remapVec->NodeAddr[cpunum];}static voidInitMagicPromalias(void){   int   cpu;   char* pFram;  /* points into Flashlite's FRAM memory */   char* pFprom; /* points into Flashlite's FPROM memory */   char* fprom;  /* points to Simos's copy of the FPROM */   fprom = sim_misc.fprom[0];   if (fprom == NULL) return; /* none there */   for (cpu= 0; cpu<NUM_CPUS(0); cpu++) {      pFprom = FlashWritePromAlias(cpu, SWS_ZONE_FPROMALIAS,				   fprom, FPROM_SIZE);      /* For now, don't use SIMRAMALIAS_SIZE ... it's big! */      pFram  = FlashWriteRamAlias(cpu, SWS_ZONE_FRAMALIAS,				  sim_misc.fram[cpu], FRAM_SIZE);      free(sim_misc.fram[cpu]);      sim_misc.fram[cpu]  = pFram;      sim_misc.fprom[cpu] = pFprom;   }   free(fprom);   /* NOTE: at this point, the sim_misc fprom and fram pointers    *       point directly into Flashlite memory. This allows a    *       cohabitation between Flite and fast FRAM/FPROM access    *       emulation through simmagic.    */}/* * The following function is called by the memory fault command * (cpus/shared/faults.c) to set ECC for a number of lines, starting at a * specified address. The address MUST be KSEG0. */int insertECC(unsigned int addr, int lines){  LL faddr;  int node;  int cachelinesz = SCACHE_LINE_SIZE;  if (!IS_KSEG0(addr) || lines <= 0 || !IS_KSEG0(addr+(unsigned)lines))    return 1;  faddr = FlashAddrFromAddr(0, MEMADDR_TO_PHYS(0, addr));  node  = SimosAddrToMemnum(MEMADDR_TO_PHYS(0, addr));  for ( ; lines > 0; lines--) {    SetECC(node, faddr, ~0);    addr += cachelinesz;  }  return 0;}#ifdef HWBCOPY/****************************************************************** * Hwbcopy annotations -- place pages on a specific node *****************************************************************/static int HwbPlaceCmd(Tcl_Interp *interp, int argc, char *argv[]);static tclcmd hwbcopyCmds[] = {   "place",       4, HwbPlaceCmd,     " place address node",   NULL,          0, NULL,            NULL};void HwbcopyAnnInit(Tcl_Interp *interp) {   Tcl_CreateCommand(interp, "hwbcopy", DispatchCmd,                     (ClientData) hwbcopyCmds, (Tcl_CmdDeleteProc*)NULL);   Tcl_SetVar2(interp, "HWBCOPY", "hwbDMA", "No", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwbDMA)",               (char *) &hwbDMA, TCL_LINK_BOOLEAN);   Tcl_SetVar2(interp, "HWBCOPY", "hwprefetch", "No", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwprefetch)",               (char *) &hwprefetch, TCL_LINK_BOOLEAN);   Tcl_SetVar2(interp, "HWBCOPY", "hwprefRange", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwprefRange)",               (char *) &hwprefRange, TCL_LINK_INT);   Tcl_SetVar2(interp, "HWBCOPY", "hwprefDepth", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwprefDepth)",               (char *) &hwprefDepth, TCL_LINK_INT);   Tcl_SetVar2(interp, "HWBCOPY", "hwbDMAChannels", "1", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwbDMAChannels)",               (char *) &hwbDMAChannels, TCL_LINK_INT);   Tcl_SetVar2(interp, "HWBCOPY", "hwbDMADelay", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "HWBCOPY(hwbDMADelay)",               (char *) &hwbDMADelay, TCL_LINK_INT);}static int HwbPlaceCmd(Tcl_Interp *interp, int argc, char *argv[]){   int node;   int pAddr;   int page;   char *addrMapType;   ParamLookup(&addrMapType, "MEMSYS.FLASH.FlashAddrMap", PARAM_STRING);   if ((memsysVec.type == FLASHLITE) && (!strcmp(addrMapType, "FirstTouch"))) {      if (argc < 4) {         Tcl_AppendResult(interp, "not enough arguments to hwbcopy place", NULL);         return TCL_ERROR;      }            Tcl_GetInt(interp, argv[3], &node);      Tcl_GetInt(interp, argv[2], &pAddr);      page = pAddr / FLASH_PAGE_SIZE;            if (simosPageToNode[page] == -1) {         simosPageToNode[page] = node;         /*      CPUWarning("Page 0x%x being placed on node %d\n",pAddr,node);*/      } else if (node != simosPageToNode[page]) {         CPUWarning("Tried to place page 0x%x on node %d, already on node %d\n",pAddr,node,simosPageToNode[page]);      }   }   return TCL_OK;}#endif /* HWBCOPY */#endif#ifndef SOLOvoid FlashliteUndirtify(int leaveShared){   /* first drain memory system, then undirtify */   FlashDrainMemSys();   FlashUndirtify(leaveShared);}void SyncMemory(void){   datafindHeader *dfH;   int pAddr;   int nDirty = 0, nCrit = 0;   FlashFreezeMemSys();   for (pAddr = 0; pAddr < MEM_SIZE(0); pAddr += SCACHE_LINE_SIZE) {      dfH = FlashGetAppData(FlashAddrFromAddr(0, pAddr));      ASSERT(dfH->numCopies > 0);      if (dfH->dirty) {#ifdef SOLO         LL *memAddr = (LL *)pAddr;#else         LL *memAddr = (LL *)PHYS_TO_MEMADDR(0, pAddr);#endif         ASSERT(dfH->numCopies == 1);         if (dfH->critWordOffset[0]) {            ConvertCritWordFirstToNormal((LL*)(dfH->dataCopies[0]),                                          memAddr, dfH->critWordOffset[0]);            nCrit++;         } else {            bcopy(dfH->dataCopies[0], memAddr, SCACHE_LINE_SIZE);         }         nDirty++;	/* just for stats */      } else {         /* clean:  so there must be a copy in memory, and I don't need to do anything */         ASSERT((dfH->dataLocation[dfH->numCopies-1] & DATAFIND_LOCATION_TYPE_MASK) == DATAFIND_LOCATION_MEMORY);      }   }   FlashUnfreezeMemSys();   CPUWarning("%d critical-word ordered lines, %d dirty lines, %d total lines\n", nCrit, nDirty, MEM_SIZE(0)/SCACHE_LINE_SIZE);}#endif/*  Routines for reading from / writing to the FPROM and FRAM.  Check for the [vAddr, vAddr+nbytes) to see if it's in FPROM/FRAM range.  If so, copy the data into buf and return 1 to indicate data was found  in FPROM/FRAM. */intGetFPROMAndFRAM(int cpunum, VA vAddr, uint nbytes, char *buf){#ifndef SOLO   if (vAddr >= FRAM_BASE && vAddr+nbytes < FRAM_BASE + FRAM_SIZE) {      unsigned raddr = vAddr - FRAM_BASE + SWS_ZONE_FRAMALIAS;            FlashReadRamAlias(cpunum, buf, (unsigned long long)raddr, nbytes);      return 1;   }      if (vAddr >= FPROM_BASE && vAddr+nbytes < FPROM_BASE + FPROM_SIZE) {      unsigned raddr = vAddr - FPROM_BASE + SWS_ZONE_FPROMALIAS;            FlashReadPromAlias(cpunum, buf, (unsigned long long) raddr, nbytes);      return 1;   }#endif   return 0;}intPutFPROMAndFRAM(int cpunum, VA vAddr, uint nbytes, char *buf){#ifndef SOLO   if (vAddr >= FRAM_BASE && vAddr+nbytes < FRAM_BASE + FRAM_SIZE) {      unsigned raddr = vAddr - FRAM_BASE + SWS_ZONE_FRAMALIAS;            FlashWriteRamAlias(cpunum, (unsigned long long)raddr, buf, nbytes);      return 1;   }      if (vAddr >= FPROM_BASE && vAddr+nbytes < FPROM_BASE + FPROM_SIZE) {      unsigned raddr = vAddr - FPROM_BASE + SWS_ZONE_FPROMALIAS;            FlashWritePromAlias(cpunum, (unsigned long long) raddr, buf, nbytes);      return 1;   }#endif   return 0;}voidFlashliteDrain(void){#ifndef SOLO   uint cpu, i, numBadNodes, *badNodes;   FlashDrainMemSys();   /* download nodemap */   numBadNodes = FlashGetBadNodesList(0, &badNodes);   for (i = 0; i < numBadNodes; i++) {      int badNode = badNodes[i];      /* NOTE:  this is not exactly what flashlite does for non-Hive addr maps         due to roundrobin effect */      uint memPerCPU = MEM_SIZE(0)/NUM_CPUS(0);      uint startAddr = memPerCPU * badNode;      uint endAddr = memPerCPU * (badNode+1);      uint addr;      for (addr = startAddr; addr < endAddr; addr += SCACHE_LINE_SIZE) {         SimMagic_MakeIncoherent(addr);      }      CPUVec.ResetCPU(badNode);      ResetCPUs(badNode, badNode);   }   /* incoherent lines on working nodes */   for (cpu = 0; cpu < NUM_CPUS(0); cpu++) {      uint *badLines;      uint numBadLines;      FLASHAddress faddr;      /* skip bad nodes */      for (i = 0; i < numBadNodes; i++) {         if (cpu == badNodes[i])            break;      }      if (i != numBadNodes)         continue;      faddr.ll = 0;      faddr.fa.node = cpu;      numBadLines = FlashGetIncoherentLinesList(cpu, &badLines);      for (i = 0; i < numBadLines; i++) {         faddr.fa.offset = badLines[i];         SimMagic_MakeIncoherent(FlashAddrToSimosAddr(faddr.ll));      }      free(badLines);      if (numBadLines) CPUWarning("WARNING: incoherent lines found.\n");   }   free(badNodes);   /* download firewall */   if (SIMFIREWALL_ON) {      FLASHAddress faddr;      LL prot;      uint p;      for (p = 0; p < MEM_SIZE(0); p += FLASH_PAGE_SIZE) {      

⌨️ 快捷键说明

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