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

📄 flash_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 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.  * *//* -*-mode:c-*- DO NOT MOVE THIS COMMENT *//* $Id: flash_interface.c,v 1.91 1998/02/10 00:37:08 bosch Exp $ *//***************************************************************** * flash_interface.c *  *****************************************************************/#include <stdio.h>#include <time.h>#include <assert.h>#include <stdlib.h>#include "cpu_interface.h"#include "mipsy.h"#include "pcache.h"#include "scache.h"#include "memstat.h"#include "memsys.h"#include "eventcallback.h"#include "cpu_interface.h"#include "cpu_state.h"#include "cp0.h"#include "memory.h"#include "string.h"#include "simutil.h"#include "tcl_init.h"#include "registry.h"#include "machine_defs.h"#include "params.h"#ifdef USE_FLASHLITE#define ERROR FLASHLITE_ERROR#define BIG_ENDIAN#include "simosinterface.h"#include "flash_interface.h"#include "mipsy_interface.h" #include "datafind.h"#ifdef SOLO#include "solo.h"#include "solo_page.h"#else#include "firewallhack.h"#include "simmagic.h"#include "firewall.h"#endif#endif#ifdef HWBCOPY#include "hw_bcopy.h"#endif/* for now just putting these here until there's a better place */#define OSPC_LOADDR_SIMOS    (__MAGIC_OSPC_BASE + MAGIC_OSPC_LO_OFFS - K0BASE)#define OSPC_HIADDR_SIMOS    (__MAGIC_OSPC_BASE + MAGIC_OSPC_HI_OFFS - K0BASE)#define OSPC_VEC_REQ_ADDR_SIMOS    (__MAGIC_OSPC_BASE + MAGIC_OSPC_VEC_REQ_OFFS - K0BASE)#define OSPC_VEC_REP_ADDR_SIMOS    (__MAGIC_OSPC_BASE + MAGIC_OSPC_VEC_REP_OFFS - K0BASE)#define OSPC_RANGE_OFFSET(_offset_field_bits)  \    ((0x1LL << (_offset_field_bits)) - 0x4000)#define SWS_ZONENUM_BITS  4#define SWS_ZONENUM_OFFSET  24#define SWS_ZONE_FRAMALIAS   (0<<SWS_ZONENUM_OFFSET)#define SWS_ZONE_FIREWALL    (3<<SWS_ZONENUM_OFFSET)#define SWS_ZONE_FPROMALIAS (15<<SWS_ZONENUM_OFFSET)#define SW_SERVICES_FLAVOR PI_UNC_FLAVOR_A#define PIO_FLAVOR PI_UNC_FLAVOR_Ctypedef enum {PIO_BYTE, PIO_HALF, PIO_WORD, PIO_DWORD} PIOAccessSize;typedef enum {HIVE, FIRST_TOUCH, ROUND_ROBIN, HIVE_ROUND_ROBIN} AddrMapType;#ifdef USE_FLASHLITEstatic AddrMapType addrMap;#ifndef SOLO/* directMapLimit must be >= remap size AND must include any special   addresses, which would normally include OSPC addrs, but they are handled   separately because they need to be translated to non-coherent get space.   Addresses that are less than directMapLimit don't go through Address Map conversion.*/static int directMapLimit;#define IS_DIRECT_MAP(addr) (((addr) & nodeOffsetMask) < directMapLimit)#endif#endif/* * Struct to hold information about a pending memory request -- * this is necessary because FlashAdvanceTime might change the state * of the cache, forcing the outgoing memory request to change. */struct FlashPending {   int active;   int fcmd;   int flavor;   int cpuNum;   PA addr;} flashPending;   /* * Unlike the other memory systems we have, the flashlite memory system  * is currently a compile time option triggered by the USE_FLASHLITE * define. If this is not defined we provide stubs so simulator can * link without it.  */#ifndef USE_FLASHLITE/***************************************************************** * FlashliteInit *****************************************************************/void FlashliteInit(void){   { extern int LinkSymbolToRetrieveFlashFaultInit;     LinkSymbolToRetrieveFlashFaultInit = 1;   }   CPUError("FlashliteCmd called when compile with !USE_FLASHLITE\n");   return;}void FlashliteInstallTimer(int cpuNum, unsigned int interval, unsigned int timeLeft){}void FlashliteConfigDefaults(void){   }voidFlashliteRaiseSlot(int cpu, int slot){   CPUError("FlashliteRaisedIBit called and USE_FLASHLITE not defined\n");}voidFlashliteClearSlot(int cpu, int slot){   CPUError("FlashliteClearIBit called and USE_FLASHLITE not defined\n");}extern void InitMagicPromalias(char* addr, unsigned nbytes){   CPUError("InitMagicPromalias called and USE_FLASHLITE not defined\n");}extern intFlashliteWQFull(int cpu){   return 0;}#else /* is defined(USE_FLASHLITE) *//* * Since flashlite uses a thread model while SimOS uses a * calback back model we need to keep the two simulated clocks * in synch.  This is done by registering a callback when * the next thread wakeup will occur in flashlite.  */static LL callbackTime = 0;           /* Time of next flashlite event to fire. */static EventCallbackHdr callback;extern bool mipsySyncWhenDone;static void RunFlashlite(int cpuNum, EventCallbackHdr *hdr, void *v);static Result FlashliteCmd(int cpuNum, int cmd, PA addr, int transId,			   PA replacedPaddr, int writeback, byte *wbData);static void FlashliteStatus(void);static void FlashliteDone(void);static void FlashliteDumpStats(void);static void RetryUncachedOp(int cpuNum, EventCallbackHdr *hdr, void *arg);static void ConvertNormalToCritWordFirst(LL *subBuffer, LL *alignedBuffer,                              unsigned startAddr);static void ConvertCritWordFirstToNormal(LL *subBuffer, LL *alignedBuffer,                              unsigned startAddr);static void GetUncachedAddr(int cpuNum, PA vAddr, unsigned long long *p_addr,                            int *p_flavor);static void SetConsistencyType(int cpuNum, enum ConsistencyType ctype);static void FlashliteDrain(void);#ifndef SOLOstatic void DownloadProtocolState(void);static void DownloadMiscbusState(void);static void DMADone(int nodeNum, void *token, int status);static void InitMagicPromalias(void);extern void MipsyTakeBusError(int cpunum, int isIRef, LL addr);static uint Uncached64To32Bit(unsigned long long addr64);extern void MipsyErrUncachedOp(int cpuNum, uint addr);extern void MipsyNakUncachedOp(int cpuNum);#elsevoidMipsyCacheError(int cpuNum, bool isAsync){   CPUError("Wow!  How'd we get a MipsyCacheError with SoloMipsy?. (cpuNum %d, isAsync %u)\n", cpuNum, isAsync);}#endifbool flashliteRunning = FALSE;FILE *mipsy_cpulogF;LL cpu_start_mem[SIM_MAXCPUS];LL cpu_finish_mem[SIM_MAXCPUS];LL *cpu_start = cpu_start_mem;LL *cpu_finish = cpu_finish_mem;static int bytesPerNode_shift;  /* supports backmap from FLASH                                 * address to simos address in the                                  * hive layout                                 */static int nodeOffsetMask;/* * State kept on behalf of a flashlite node.  */static struct nodeState {    /*    * In order to correctly handle uncached reads we maintain     * the state of outstanding uncached reads in the following    * buffer. Note this assumes we have only one outstanding    * uncached read per node.     */   struct {      bool    active;     /* State structure is inuse */      PA      addr;       /* Address of uncached read */      int     size;       /* Size of uncached read */      bool    done;       /* Flashlite has returned data */      int     status;     /* 0 if no error, data valid. */      char    data[8];    /* Data if returned */   } uncachedReadState;   /*    * Because of flow control problems we might have to stall an    * uncached op. The following callback will unstall us    * for a retry.     */    EventCallbackHdr retryCallback;   /*    * Some stats for the node.    */   struct FlashStats {      long long numGETs;      long long numGETXs;      long long numUPGRADEs;      long long numWBs;       long long numNAKs;   } stats;} nodeState[SIM_MAXCPUS];/* * In order to run SIMOS requires that all its addresses be remapped into * phyiscal addresses that are valid for flash.  The SOLO V_to_P already * handles this remapping for solo.  */#ifndef SOLO/* * Do the mappings between Simos and Flash addresses * This mapping currently assumes fewer than 128 CPUs  */static signed char *simosPageToNode;#define  SimosAddrToMemnum(_addr)     	\               (simosPageToNode[(_addr)/FLASH_PAGE_SIZE])static int nodeaddrMask;static void InitSimosMemoryMap(void);static unsigned int FlashAddrToSimosAddr(unsigned long long faddr);#define FlashAddrFromAddr(_a,_b) FlashAddrFromSimosAddr((_a),(_b))#define FlashAddrToAddr(_a) FlashAddrToSimosAddr((_a))#endif#ifdef SOLO#define FlashAddrFromAddr(_a,_b) FlashAddrFromSoloAddr((_a),(_b))#define FlashAddrToAddr(_a) FlashAddrToSoloAddr((_a))#endifunsigned FlashAddrCompress(unsigned long long flashAddr){   return((unsigned)(FlashAddrToAddr(flashAddr)));}/***************************************************************** * MemsysInit *****************************************************************/void FlashliteInit(void){   int i;   /*    * You wouldn't get very far without upgrades or the wrong     * cache line size but the error messages generated by     * flashlite make it difficult to figure this out so we    * explictly check here.     */   if (NUM_MACHINES > 1) {     CPUError("Flashlite won't run with multiple machines.\n");   }   if ((NUM_CPUS(0) == 1) && !UPGRADES_ON_UP) {     CPUError("Flashlite won't run without upgrades.\n");   }   if (SCACHE_LINE_SIZE != (WORDS_IN_CACHELINE*8)) {     CPUError("Flashlite requires SCacheLineSize of 128.\n");   }        memsysVec.type = FLASHLITE;   memsysVec.NoMemoryDelay = 0;   memsysVec.MemsysCmd = FlashliteCmd;   memsysVec.MemsysDumpStats = FlashliteDumpStats;   memsysVec.MemsysDone = FlashliteDone;   memsysVec.MemsysStatus = FlashliteStatus;   memsysVec.MemsysDrain = FlashliteDrain;   bzero((char *)nodeState, sizeof(nodeState));   callbackTime = 0;   mipsy_cpulogF = cpulogF;   FlashInitSim();   flashliteRunning = TRUE;   mipsySyncWhenDone = TRUE;#ifndef SOLO   InitMagicPromalias();   /* run flash forward a bunch of cycles in order to get past its    * protocol initialization.  This is important so we don't give it    * cache misses while it is booting, plus it allows us to update    * the firewall, NI registers, etc. from a checkpoint without    * worrying about that state being smashed by protocol initialization.    */#ifdef notdef   {      int cycleoffset;      ParamLookup(&cycleoffset, "MEMSYS.FLASH.FlashSimosCycleOffset", PARAM_INT);              if (cycleoffset == 0) {         CPUWarning("\rWARNING: No value specified for FlashSimosCycleOffset\n");         CPUWarning("\rWARNING: Data restored from checkpoint may be overwritten by protocol boot\n");      } else {         CPUWarning("\rRunning flashlite forward by %d simos cycles to exec protocol boot\n",                  cycleoffset);         FlashSimosCycleOffset(cycleoffset);         FlashAdvanceTime(0);         CPUWarning("\rProtocol boot timeout complete, starting SimOS\n");      }   }#endif   {      int cycleoffset;      CPUWarning("\rRunning flashlite forward to exec protocol boot\n");      cycleoffset = FlashAdvanceThroughMAGICBoot();      FlashSimosCycleOffset(cycleoffset);      CPUWarning("\rProtocol boot complete at cycle %d, starting SimOS\n",                  cycleoffset);   }   /* Initialize the address remap and fake firewall    * support for flashlite.    */   /* Order is important -- JKB */   DownloadMiscbusState();   DownloadProtocolState();   InitSimosMemoryMap();   FlashFlushChangesToVerilogMem();   for (i = 0; i < NUM_CPUS(0); i++) {       cpu_start[i] = MipsyReadTime(cpuNum);   }#endif   { extern int LinkSymbolToRetrieveFlashFaultInit;     LinkSymbolToRetrieveFlashFaultInit = 1;   }}#ifndef SOLOstatic voidDownloadMiscbusState(void){  /* initialize workermask and workermatch for each cpu   * This is a bit of a hack since the OS doesn't set these up   * yet -- when we add that functionality we'll have mask/match   * values in the checkpoint directly.   *   * xxx Also: set firewall shift. This is a hack, since we don't   * checkpoint this value and the OS cannot be expected to set it   * when resuming from a checkpoint. The firewall shift is the number   * of positions the node number must be shifted right to get the cell   * number, i.e. log2(CPUs/cell).   */  {      int cpuspercell, i;     int numcells = NUM_CELLS(0);     int wmask;          if (numcells == 0) numcells = 1;     cpuspercell = NUM_CPUS(0) / numcells;     wmask = ~(cpuspercell - 1);     for (i=0; i<NUM_CPUS(0); i++) {        FlashSetWorker(i, wmask, i & wmask);	FlashSetFWShift(i, GetLog2(cpuspercell));     }  }}

⌨️ 快捷键说明

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