📄 flash_interface.c
字号:
*/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 + -