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

📄 flash_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static voidConvertNormalToCritWordFirst(LL *subBuffer,LL *alignedBuffer, unsigned startAddr){   unsigned     offset;   unsigned     count;   unsigned     start;   start = (startAddr & ((WORDS_IN_CACHELINE*8)-1)) >> 3;    for (count=0; count < WORDS_IN_CACHELINE; count++) {      offset = start ^ count;      subBuffer[count] = alignedBuffer[offset];   }} static voidConvertCritWordFirstToNormal(LL *subBuffer, LL *alignedBuffer, unsigned startAddr){   unsigned     offset;   unsigned     count;   unsigned     start;    start = (startAddr & ((WORDS_IN_CACHELINE*8)-1)) >> 3;    for (count=0; count < WORDS_IN_CACHELINE; count++) {      offset = start ^ count;      alignedBuffer[count] = subBuffer[offset];   }} #ifndef SOLO/* convert a 32 bit magic address to a full 64 bit addr.   Also, return the zone */static voidUncached32To64Bit(int cpuNum, uint PA, unsigned long long *p_addr, int *p_flavor){   FLASHAddress faddr;   uint node, zone, zoneOffset;   node = (PA >> __MAGIC_NODE_OFFS) & ((1 << __MAGIC_NODE_BITS) - 1);   zone = (PA >> __MAGIC_ZONE_OFFS) & ((1 << __MAGIC_ZONE_BITS) - 1);   zoneOffset = (PA & ((1 << __MAGIC_ZONE_OFFS) - 1));   *p_flavor = SW_SERVICES_FLAVOR;   faddr.ll = 0;   faddr.fa.node = node;   /* if the following assert is no longer true, we'll have to change the code      below to use faddr.ll instead of faddr.fa.offset */   ASSERT(OFFSET_FIELD_SIZE > (SWS_ZONENUM_BITS + SWS_ZONENUM_OFFSET));   faddr.fa.offset = (((unsigned long long)zone) << SWS_ZONENUM_OFFSET)      | zoneOffset;   switch (zone) {   case MAGIC_ZONE_BDOOR_DEV: {      uint offset;      *p_flavor = PIO_FLAVOR;      /*       * Since Flashlite doesn't support remote PIOs we always make the local.       * Until we have remote device support we just pass the PA to thru Magic       * back to SimosDispatchPIO().       */      offset = PA - __MAGIC_BASE;      faddr.fa.node = cpuNum; /* Make PIOs always local. */      faddr.fa.offset = offset;      ASSERT(faddr.fa.offset == offset) /* Detects if fa.offset it too small */      break;      }   case MAGIC_ZONE_FPROM_ALIAS:      /* hack to convert 32bit frpom zone to 64bit fprom zone because they're not the same */   {#ifdef LARGE_SIMULATION      if (node == 127) { /* 0xbfc0.... is node 127 */#endif         /* first, zero out bad zone number and part of offset fields */         faddr.fa.offset &= ~(((1 << __MAGIC_ZONE_BITS) - 1) << SWS_ZONENUM_OFFSET);         /* now add back the correct zone and portion of offset fields */         faddr.fa.offset |= SWS_ZONE_FPROMALIAS | (MAGIC_ZONE_FPROM_ALIAS << __MAGIC_ZONE_OFFS);#ifdef LARGE_SIMULATION         /* need to add 'c' of 'bfc' back */         faddr.fa.offset |= 0xc00000;      }#endif   }   break;   case MAGIC_ZONE_FIREWALL:      /* if firewall zone, need to fix it to match address mapping */   {      uint fwForAddr32 = faddr.fa.node << bytesPerNode_shift         | (zoneOffset/sizeof(MagicRegister))*FLASH_PAGE_SIZE;      FLASHAddress fwForAddr64;      fwForAddr64.ll = FlashAddrFromSimosAddr(0, fwForAddr32);      faddr.fa.node = fwForAddr64.fa.node;      faddr.fa.offset = SWS_ZONE_FIREWALL         | (fwForAddr64.fa.offset/FLASH_PAGE_SIZE)*sizeof(MagicRegister);   }   break;   default:      /* don't need to do anything */      break;   }   *p_addr = faddr.ll;}static uintUncached64To32Bit(unsigned long long addr64){   FLASHAddress faddr;   uint addr32;   int zone;   faddr.ll = addr64;   /* if the following assert is no longer true, we'll have to change the code      below to use faddr.ll instead of faddr.fa.offset */   ASSERT(OFFSET_FIELD_SIZE > (SWS_ZONENUM_BITS + SWS_ZONENUM_OFFSET));   zone = faddr.fa.offset >> SWS_ZONENUM_OFFSET;   if (zone == (SWS_ZONE_FPROMALIAS>>SWS_ZONENUM_OFFSET)) {      zone = MAGIC_ZONE_FPROM_ALIAS;   }   addr32 = __MAGIC_BASE      | (faddr.fa.node << __MAGIC_NODE_OFFS)      | (zone << __MAGIC_ZONE_OFFS)      | (faddr.ll & ((1 << __MAGIC_ZONE_OFFS) - 1));   /*CPUPrint("U64T32 %llx => %x\n", addr64, addr32);*/   return addr32;}voidGetUncachedAddr(int cpuNum, PA vAddr, unsigned long long *p_addr,                int *p_flavor){  FLASHAddress faddr;  /*   * For testing we convert all backdoor addresses to uncached    * ops to the IO space.    */  faddr.ll = 0;#ifdef HWBCOPY  /* For now, if the given address is a valid physical address,   * assume that we are doing an access to the MSG space.   */  if (vAddr < MEM_SIZE(0)) {     if (simosPageToNode[vAddr/FLASH_PAGE_SIZE] < 0) {              simosPageToNode[vAddr/FLASH_PAGE_SIZE] = cpuNum; /* First touch */     }     *p_addr = FlashAddrFromSimosAddr(MSG,vAddr);     CPUPrint("MSG: Message space write to 0x%08x (0x%016llx) on CPU %d\n",              vAddr,*p_addr,cpuNum);     return;  }#endif  /* direct access firewall and PPC ver2 regions are translated specially   * because they are not always local   */#ifdef OLD_INT  if (vAddr >= PPC2_ZONES && vAddr < (PPC2_ZONES + PPC2_ZONES_SIZE)) {     int szone = PPC2_ZONE(vAddr);     faddr.fa.node = PPC2_NODE(vAddr);     faddr.fa.space = NORMAL;     *p_flavor = SW_SERVICES_FLAVOR;     if (szone < PPCZONE_PPCCORE || szone >= PPCZONE_SWTLB) {        /* each of these zones has a one-to-one translation of addresses         * from the 1k of space offered by SimOS to the first 1k of         * the 16 MB zone implemented by flashlite         */        LL mzone;        switch (szone) {        case PPCZONE_PPR:      mzone = SWS_ZONE_PPR;     break;        case PPCZONE_DMAMAP:   mzone = SWS_ZONE_DMAMAP;  break;        case PPCZONE_NODEMAP:  mzone = SWS_ZONE_NODEMAP; break;        case PPCZONE_SWTLB:    mzone = SWS_ZONE_SWTLB;   break;        default:           CPUError("\rUncached access to unimplemented zone %d in flash_interface.c:GetUncachedAddr\n", szone);           break;        }        faddr.fa.offset = mzone + PPC2_ZONE_OFFSET(vAddr);     } else {        /* ppcs are special because of the limited available address space in simos */        int group = PPC2_PPCGROUP(szone);        int op = PPC2_PPCOP(vAddr,szone);        int seq = SWS_ZONE_PPC_SEQUENCE(vAddr);        faddr.fa.offset = (SWS_ZONE_PPC                            + (group << SWS_ZONE_PPC_GROUP_OFFSET)                           + (op << SWS_ZONE_PPC_OPCODE_OFFSET))                           + seq;     }  } else if (vAddr>=SIMFW_DIRECT && vAddr<(SIMFW_DIRECT+SIMFW_DIRECT_SIZE)) {     int pgnum = (vAddr - SIMFW_DIRECT) / sizeof(FWvector);     int nodeoffset;     /* get the full flash addr and mask off the high word (cpuNum) */     nodeoffset = FlashAddrFromSimosAddr(0, pgnum*FLASH_PAGE_SIZE) & 0xffffffff;          faddr.fa.node = simosPageToNode[pgnum];     faddr.fa.offset = SWS_ZONE_FIREWALL                        + (sizeof(FWvector)*(nodeoffset / FLASH_PAGE_SIZE));     faddr.fa.space = NORMAL;     *p_flavor = SW_SERVICES_FLAVOR;  } else if (vAddr >= SIMRAMALIAS && vAddr < (SIMRAMALIAS + SIMRAMALIAS_SIZE)) {     faddr.fa.node = 0;   /* node field ignored in an alias range */     faddr.fa.offset = SWS_ZONE_FRAMALIAS + (vAddr - SIMRAMALIAS);     faddr.fa.space = NORMAL;     *p_flavor = SW_SERVICES_FLAVOR;  } else if (vAddr >= SIMPROMALIAS              && vAddr < (SIMPROMALIAS + SIMPROMALIAS_SIZE)) {     faddr.fa.node = 0;   /* node field ignored in an alias range */     faddr.fa.offset = SWS_ZONE_FPROMALIAS + (vAddr - SIMPROMALIAS);     faddr.fa.space = NORMAL;     *p_flavor = SW_SERVICES_FLAVOR;  } else if (vAddr >= PPC_RANGE && vAddr < (PPC_RANGE + PPC_RANGE_SIZE)) {     faddr.fa.offset = 0x7480000 + (vAddr - PPC_RANGE);     faddr.fa.space = IO;     faddr.fa.node = cpuNum;  } else if (vAddr >= SIMBASEADDR) {      faddr.fa.offset = (vAddr - SIMBASEADDR);     faddr.fa.space = IO;     faddr.fa.node = cpuNum; /* XXX - always local for now */  } else {     CPUWarning("Unknown uncached address 0x%x pasted to flashlite GetUncachedAddr cpu %d\n",                 vAddr, cpuNum);     faddr.fa.offset = vAddr;     faddr.fa.node = cpuNum;  }#else  Uncached32To64Bit(cpuNum, vAddr, &faddr.ll, p_flavor);  #endif#ifdef notdef  CPUWarning("GetUncachedAddr: input 0x%x output 0x%x%x (flavor 0x%x)\n",             vAddr, ((int) (faddr.ll >> 32)), ((int) (faddr.ll & 0xffffffff)),             *p_flavor);#endif#ifdef OLD_INT  if ((faddr.ll & 0x7)      && (vAddr >= PPC_RANGE) && (vAddr < PIO_RANGE)) {     CPUWarning("GetUncachedAddr: unaligned PPC or PPR:  input 0x%x output 0x%x%x cpu %d\n",                vAddr,                 ((int) (faddr.ll >> 32)),                 ((int) (faddr.ll & 0xffffffff)), cpuNum);  }#endif  *p_addr = faddr.ll;}intSimosDispatchPIO(int node_num, uint offset, int isRead, int size, volatile void *data){   return SimMagic_DoPIO(node_num, offset + __MAGIC_BASE, isRead, size, (void *)data);}#ifndef SOLOBoolSimosGetMemoryAddr(LL p_addrll, Address *v_addr, int mem_type){    *v_addr = (Address) PHYS_TO_MEMADDR(0,(PA)FlashAddrToSimosAddr(p_addrll));   return TRUE;}#endif/* * Interrupt hookup for flashlite. */voidFlashliteRaiseSlot(int cpu, int slot){   FlashRaiseInterrupt(cpu, slot);}voidFlashliteClearSlot(int cpu, int slot){   FlashClearInterrupt(cpu, slot);}int  SimosSetIntrBits(int cpunum, uint enableMask, uint intrBits){#ifdef notdef   /* hack so we can run SIPS through flashlite while all the    * other interrupt support is still in SimOS    */   CPUWarning("SimosSetInterBits: Hack: assuming OSPC interrupt only\n");   if (enableMask & (0x1)) {   /* OSPC LO */      if (intrBits & (0x1)) {         SimRaiseIBit(cpunum, IEC_OSPC_LO);      } else {         SimClearIBit(cpunum, IEC_OSPC_LO);      }   }   if (enableMask & (0x1 << 1)) {  /* OSPC HI */      if (intrBits & (0x1 << 1)) {         SimRaiseIBit(cpunum, IEC_OSPC_HI);      } else {         SimClearIBit(cpunum, IEC_OSPC_HI);      }   }   return 0;#endif   enableMask <<= 2; /* Skip over softeare interrupt bits */   intrBits <<= 2;      CPUVec.intrBits[cpunum] = (CPUVec.intrBits[cpunum] & ~enableMask) | intrBits;   if (DEBUG_INTR()) {     LogEntry("SSIB", cpunum, "emask: 0x%x  ibits: 0x%x  vec->ibits: 0x%x\n",	      enableMask, intrBits, CPUVec.intrBits[cpunum]);   }   if (CPUVec.IntrBitsChanged) {      (CPUVec.IntrBitsChanged)(cpunum);   }   return 0;}#endif#ifdef SOLOvoidGetUncachedAddr(int cpuNum, PA vAddr, unsigned long long *p_addr, int *p_flavor){    uint flavor;     *p_addr = (unsigned long long) SoloV_to_P(cpuNum, vAddr, cpuNum, 0, &flavor);    ASSERT(flavor == TLB_UNCACHED);}intSimosDispatchPIO(int node_num, uint offset, int isRead, int size, volatile void *data){   CPUError("SOLO got a PIO to the PCI bus!!!\n");   return 0;}BoolSimosGetMemoryAddr(LL p_addrll, Address *v_addr, int mem_type){     (*v_addr) = (Address)SoloGetMemoryAddr(p_addrll);     return ((*v_addr) ? TRUE : FALSE);}   int  SimosSetIntrBits(int cpunum, uint enableMask, uint intrBits){   CPUWarning("SOLO interrupt (%#x)\n",intrBits);   return 0;}#endif /* SOLO *//* * SetConsistencyType(int cpuNum, ConsistencyType ctype) * Set the write consistency model used by flashlite.  * * Note this routine does an uncached write to launch a PPC * to change the PI's opspace bits. This is intrusive (i.e.  * it cosumes time/resources to execute) and it assumes  * flashlite is in a state such that it can accept uncached * writes.  */static voidSetConsistencyType(int cpuNum, enum ConsistencyType ctype){#ifdef notdef   LL faddr;   Result ret;   FlashCmd   cmd;   LL data;   LL nextEvent;   ASSERT(flashliteRunning);   if (FlashUncachedWriteQueueFull(cpuNum)) {      CPUError("SetConsistencyType called with write queue full\n");   }    data = ((LL)ctype) << 62;   cmd = FLASH_CMD_FORM(PI_PROC_UNC_WRITE_REQ,PI_UNC_FLAVOR_A,0,LEN_NODATA);   faddr = (LL)PPC_ADDR(PPCG_MISC, PPCO_MISC_CONTEXTSWITCH);   nextEvent = FlashCmdToMagic(cpuNum, 0, cmd, faddr, 0, 0, (char *)&data);   if (nextEvent != (LL)-1) {      nextEvent += 1;      if (callbackTime) {	 if (nextEvent < callbackTime) {	    EventCallbackUpdate(&callback, (SimTime) nextEvent);	    callbackTime = nextEvent;	 }      } else {	 EventDoCallback(cpuNum,RunFlashlite, &callback, 0, 			 nextEvent - MipsyReadTime(cpuNum));	 callbackTime = nextEvent;      }   }#endif   CPUError("This is broken\n");}#ifndef SOLOstatic void   FlashliteSetRemap(int cpunum, PA mask);static void   FlashliteControlRemap(int cpunum, int isEnabled);static unsigned int FlashliteGetNodeAddress(int cpunum);

⌨️ 快捷键说明

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