uint16_t EmptyHandle(uint16_t trap) { /* * on entry: * A0 Handle to be disposed of * * on exit: * D0 Result code * */ uint32_t hh = cpuGetAReg(0); Log("%04x EmptyHandle(%08x)\n", trap, hh); auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto &info = iter->second; if (info.address == 0) return SetMemError(0); if (info.locked) return SetMemError(MacOS::memLockedErr); // ? void *address = Memory + info.address; mplite_free(&pool, address); info.address = 0; info.size = 0; memoryWriteLong(0, hh); return 0; }
uint16_t HSetState(uint16_t trap) { /* * on entry: * A0 Handle * D0 flags * * on exit: * D0 flag byte * */ uint32_t hh = cpuGetAReg(0); uint16_t flags = cpuGetDReg(0); Log("%04x HSetState(%08x, %04x)\n", trap, hh, flags); auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto &info = iter->second; info.resource = (flags & (1 << 5)); info.purgeable = (flags & (1 << 6)); info.locked = (flags & (1 << 7)); return SetMemError(0); }
uint16_t HandleZone(uint16_t trap) { // FUNCTION HandleZone (h: Handle): THz; /* * on entry: * A0 Handle whose zone is to be found * * on exit: * A0 Pointer to handle’s heap zone * D0 Result code * */ uint32_t h = cpuGetAReg(0); Log("%04x HandleZone(%08x)\n", trap, h); if (HandleMap.find(h) == HandleMap.end()) { cpuSetAReg(0, 0); return SetMemError(MacOS::memWZErr); } cpuSetAReg(0, 0); return SetMemError(0); }
uint32_t GetHandleSize(uint16_t trap) { /* * on entry: * A0 handle * * on exit: * D0 size (32-bit) or error code * */ /* * The trap dispatcher sets the condition codes before returning * from a trap by testing the low-order word of register D0 with * a TST.W instruction. Because the block size returned in D0 by * _GetHandleSize is a full 32-bit long word, the word-length * test sets the condition codes incorrectly in this case. To * branch on the contents of D0, use your own TST.L instruction * on return from the trap to test the full 32 bits of the register. */ uint32_t hh = cpuGetAReg(0); Log("%04x GetHandleSize(%08x)\n", trap, hh); if (hh == 0) return SetMemError(MacOS::nilHandleErr); // ???? auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); return iter->second.size; }
uint16_t SetPtrSize(uint16_t trap) { /* * on entry: * A0 pointer * D0 new size * * on exit: * D0 Result code * */ uint32_t mcptr = cpuGetAReg(0); uint32_t newSize = cpuGetDReg(0); Log("%08x SetPtrSize(%08x, %08x)\n", trap, mcptr, newSize); auto iter = PtrMap.find(mcptr); if (iter == PtrMap.end()) return SetMemError(MacOS::memWZErr); uint8_t *ptr = mcptr + Memory; if (mplite_resize(&pool, ptr, mplite_roundup(&pool, newSize)) < 0) { return SetMemError(MacOS::memFullErr); } // update the size. iter->second = newSize; return SetMemError(0); }
tool_return<HandleInfo> GetHandleInfo(uint32_t handle) { const auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); SetMemError(0); return iter->second; }
/* * ReallocHandle (h: Handle; logicalSize: Size); * * ReallocHandle allocates a new relocatable block with a logical * size of logicalSize bytes. It then updates handle h by setting * its master pointer to point to the new block. The main use of * this procedure is to reallocate space for a block that has * been purged. Normally h is an empty handle, but it need not * be: If it points to an existing block, that block is released * before the new block is created. * * In case of an error, no new block is allocated and handle h is * left unchanged. */ uint16_t ReallocHandle(uint16_t trap) { /* * on entry: * A0 Handle to be disposed of * D0 Logical Size * * on exit: * D0 Result code * */ uint32_t hh = cpuGetAReg(0); uint32_t logicalSize = cpuGetDReg(0); Log("%04x ReallocHandle(%08x, %08x)\n", trap, hh, logicalSize); return Native::ReallocHandle(hh, logicalSize); #if 0 auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto& info = iter->second; if (info.locked) return SetMemError(MacOS::memLockedErr); if (info.address) { void *address = Memory + info.address; mplite_free(&pool, address); info.address = 0; info.size = 0; memoryWriteLong(0, hh); } // allocate a new block... if (logicalSize == 0) return SetMemError(0); void *address = mplite_malloc(&pool, logicalSize); if (!address) return SetMemError(MacOS::memFullErr); uint32_t mcptr = (uint8_t *)address - Memory; info.size = logicalSize; info.address = mcptr; memoryWriteLong(mcptr, hh); // lock? clear purged flag? return 0; #endif }
uint16_t HClrRBit(uint32_t handle) { const auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto &info = iter->second; info.resource = false; return SetMemError(0); }
uint16_t GetHandleSize(uint32_t handle, uint32_t &handleSize) { handleSize = 0; const auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); handleSize = iter->second.size; return SetMemError(0); }
uint16_t HandleIt(uint32_t handle, FX fx) { const auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto &info = iter->second; fx(info); return SetMemError(0); }
uint16_t HUnlock(uint32_t handle) { const auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto &info = iter->second; info.locked = false; return SetMemError(0); }
/** * * This is function gets the POR speed limit for U-DDR3 Ni * * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK * * */ VOID STATIC MemPGetPORFreqLimitUNi3 ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT8 *DimmsPerChPtr; UINT8 MaxDimmPerCH; UINT16 SpeedLimit; DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID); if (DimmsPerChPtr != NULL) { MaxDimmPerCH = *DimmsPerChPtr; } else { MaxDimmPerCH = 2; } if (MaxDimmPerCH == 1) { if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) { // // Highest POR supported speed for Unbuffered dimm is 1333 // SpeedLimit = DDR1333_FREQUENCY; } else { // // Max LV DDR3 Speed is 1066 for this silicon // SpeedLimit = DDR1066_FREQUENCY; } } else { // // Highest supported speed in 2DPC configuration is 1066 // SpeedLimit = DDR1066_FREQUENCY; // // VOLT1_35 won't be supported while two DIMMs are populated in a channel // if ((NBPtr->RefPtr->DDR3Voltage == VOLT1_35) && (NBPtr->ChannelPtr->Dimms == 2)) { NBPtr->RefPtr->DDR3Voltage = VOLT1_5; PutEventLog (AGESA_WARNING, MEM_WARNING_VOLTAGE_1_35_NOT_SUPPORTED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_WARNING, NBPtr->MCTPtr); } } if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) { NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit; } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) { // Unbuffered DDR3 at 333MHz is not supported NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_ERROR, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; } }
/** * * Check and enable node interleaving on all nodes. * * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK * * @return TRUE - No fatal error occurs. * @return FALSE - Fatal error occurs. */ BOOLEAN MemMInterleaveNodes ( IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr ) { UINT8 Node; UINT8 NodeCnt; BOOLEAN RetVal; MEM_NB_BLOCK *NBPtr; NBPtr = MemMainPtr->NBPtr; NodeCnt = 0; RetVal = TRUE; if (NBPtr->RefPtr->EnableNodeIntlv) { if (!MemFeatMain.MemClr (MemMainPtr)) { PutEventLog (AGESA_WARNING, MEM_WARNING_NODE_INTERLEAVING_NOT_ENABLED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_WARNING, NBPtr->MCTPtr); return FALSE; } MemMainPtr->mmSharedPtr->NodeIntlv.IsValid = FALSE; MemMainPtr->mmSharedPtr->NodeIntlv.NodeIntlvSel = 0; for (Node = 0; Node < MemMainPtr->DieCount; Node++) { if (!NBPtr[Node].FeatPtr->CheckInterleaveNodes (&NBPtr[Node])) { break; } if (NBPtr[Node].MCTPtr->NodeMemSize != 0) { NodeCnt ++; } } if ((Node == MemMainPtr->DieCount) && (NodeCnt != 0) && ((NodeCnt & (NodeCnt - 1)) == 0)) { MemMainPtr->mmSharedPtr->NodeIntlv.NodeCnt = NodeCnt; for (Node = 0; Node < MemMainPtr->DieCount; Node++) { if (NBPtr[Node].MCTPtr->NodeMemSize != 0) { NBPtr[Node].FeatPtr->InterleaveNodes (&NBPtr[Node]); } } for (Node = 0; Node < MemMainPtr->DieCount; Node++) { NBPtr[Node].SyncAddrMapToAllNodes (&NBPtr[Node]); RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); } } else { // // If all nodes cannot be interleaved // PutEventLog (AGESA_WARNING, MEM_WARNING_NODE_INTERLEAVING_NOT_ENABLED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_WARNING, NBPtr->MCTPtr); } } return RetVal; }
/** * * This is function gets the POR speed limit for R-DDR3 C32 DDR3 * * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK * * */ VOID STATIC MemPGetPORFreqLimitRC32_3 ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT8 *DimmsPerChPtr; UINT8 MaxDimmPerCH; UINT8 FreqLimitSize; UINT16 SpeedLimit; CONST POR_SPEED_LIMIT *FreqLimitPtr; DCT_STRUCT *DCTPtr; DCTPtr = NBPtr->DCTPtr; DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID); if (DimmsPerChPtr != NULL) { MaxDimmPerCH = *DimmsPerChPtr; } else { MaxDimmPerCH = 2; } if (MaxDimmPerCH == 4) { DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; return; } else if (MaxDimmPerCH == 3) { FreqLimitPtr = C32RDdr3PSPorFreqLimit3D; FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit3D); } else if (MaxDimmPerCH == 2) { FreqLimitPtr = C32RDdr3PSPorFreqLimit2D; FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit2D); } else { FreqLimitPtr = C32RDdr3PSPorFreqLimit1D; FreqLimitSize = GET_SIZE_OF (C32RDdr3PSPorFreqLimit1D); } SpeedLimit = MemPGetPorFreqLimit (NBPtr, FreqLimitSize, FreqLimitPtr); if (SpeedLimit != 0) { if (DCTPtr->Timings.TargetSpeed > SpeedLimit) { DCTPtr->Timings.TargetSpeed = SpeedLimit; } } else { DCTPtr->Timings.DimmExclude |= DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_CRITICAL, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_CRITICAL, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; } }
uint16_t DisposePtr(uint32_t mcptr) { auto iter = PtrMap.find(mcptr); if (iter == PtrMap.end()) return SetMemError(MacOS::memWZErr); PtrMap.erase(iter); uint8_t *ptr = mcptr + Memory; mplite_free(&pool, ptr); return SetMemError(0); }
VOID STATIC MemNGetPORFreqLimitTblDrvNb ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT8 i; i = 0; while (memPlatSpecFlowArray[i] != NULL) { if ((memPlatSpecFlowArray[i])->MaxFrequency (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { break; } i++; } // Check if there is no table found across CPU families. If so, disable channels. if (memPlatSpecFlowArray[i] == NULL) { IDS_HDT_CONSOLE (MEM_FLOW, "\nDCT %d: No MaxFreq table. This channel will be disabled.\n", NBPtr->Dct); NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_ERROR, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; } }
/** * * This is function gets the POR speed limit for U-DDR3 DA * * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK * * */ VOID STATIC MemPGetPORFreqLimitUDA3 ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT16 SpeedLimit; if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) { // // Highest POR supported speed for Unbuffered dimm is 1333 // SpeedLimit = DDR1333_FREQUENCY; } else { // // Max LV DDR3 Speed is 1066 for this silicon // SpeedLimit = DDR1066_FREQUENCY; } if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedLimit) { NBPtr->DCTPtr->Timings.TargetSpeed = SpeedLimit; } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) { // Unbuffered DDR3 at 333MHz is not supported NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_ERROR, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; } }
uint16_t HandToHand(uint16_t trap) { /* * on entry: * A0 source Handle * * on exit: * A0 destination Handle * D0 Result code * */ uint32_t srcHandle = cpuGetAReg(0); Log("%04x HandToHand(%08x)\n", trap, srcHandle); auto iter = HandleMap.find(srcHandle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto const info = iter->second; uint32_t destHandle; uint32_t destPtr; uint32_t d0 = Native::NewHandle(info.size, false, destHandle, destPtr); if (d0 == 0) { std::memmove(memoryPointer(destPtr), memoryPointer(info.address), info.size); } cpuSetAReg(0, destHandle); return d0; // SetMemError called by Native::NewHandle. }
/** * * This is function gets the POR speed limit for SO-DDR3 C32 * * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK * * */ VOID STATIC MemPGetPORFreqLimitUC32_3 ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT16 MaxSpeed; // // For 2/2 or 2/3 DPCH where one is a DR, Max Speed is 1066 // if ( (NBPtr->ChannelPtr->Dimms >= 2) && ((NBPtr->ChannelPtr->DimmDrPresent & 0x07) != 0) ) { MaxSpeed = DDR1066_FREQUENCY; } else { // // Highest POR supported speed for Unbuffered dimm is 1333 // MaxSpeed = DDR1333_FREQUENCY; } if (NBPtr->DCTPtr->Timings.TargetSpeed > MaxSpeed) { NBPtr->DCTPtr->Timings.TargetSpeed = MaxSpeed; } else if (NBPtr->DCTPtr->Timings.TargetSpeed == DDR667_FREQUENCY) { // Unbuffered DDR3 at 333MHz is not supported NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_333MHZ_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); SetMemError (AGESA_ERROR, NBPtr->MCTPtr); // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; } }
uint16_t NewHandle(uint32_t size, bool clear, uint32_t &handle, uint32_t &mcptr) { uint8_t *ptr; uint32_t hh; handle = 0; mcptr = 0; if (!HandleQueue.size()) { if (!alloc_handle_block()) { return SetMemError(MacOS::memFullErr); } } hh = HandleQueue.front(); HandleQueue.pop_front(); ptr = nullptr; // todo -- size 0 should have a ptr to differentiate // from purged. // PPCLink calls NewHandle(0) but expects a valid pointer // Assertion failed: *fHandle != NULL //if (size) //{ ptr = (uint8_t *)mplite_malloc(&pool, size ? size : 1); if (!ptr) { HandleQueue.push_back(hh); return SetMemError(MacOS::memFullErr); } mcptr = ptr - Memory; if (clear) std::memset(ptr, 0, size); //} // need a handle -> ptr map? HandleMap.emplace(std::make_pair(hh, HandleInfo(mcptr, size))); memoryWriteLong(mcptr, hh); handle = hh; return SetMemError(0); }
uint16_t PtrAndHand(uint16_t trap) { // FUNCTION PtrAndHand (pntr: Ptr; hndl: Handle; size: LongInt): OSErr; /* * on entry: * A0 source Pointer * A1 dest Handle * D0 number of bytes to concatenate * * on exit: * A0 destination Handle * D0 Result code * */ uint32_t ptr = cpuGetAReg(0); uint32_t handle = cpuGetAReg(1); uint32_t size = cpuGetDReg(0); Log("%04x PtrAndHand(%08x, %08x, %08x)\n", trap, ptr, handle, size); cpuSetAReg(0, handle); uint32_t oldSize = 0; uint32_t d0; d0 = Native::GetHandleSize(handle, oldSize); if (d0) return d0; if ((uint64_t)oldSize + (uint64_t)size > UINT32_MAX) return SetMemError(MacOS::memFullErr); d0 = Native::SetHandleSize(handle, oldSize + size); if (d0) return d0; auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto const info = iter->second; std::memmove(memoryPointer(info.address + oldSize), memoryPointer(ptr), size); return SetMemError(0); }
/** * * Find the common supported voltage on all nodes, taken into account of the * user option for performance and power saving. * * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK * * @return TRUE - No fatal error occurs. * @return FALSE - Fatal error occurs. */ BOOLEAN MemMLvDdr3PerformanceEnhPre ( IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr ) { UINT8 Node; BOOLEAN RetVal; DIMM_VOLTAGE VDDIO; MEM_NB_BLOCK *NBPtr; MEM_PARAMETER_STRUCT *ParameterPtr; MEM_SHARED_DATA *mmSharedPtr; PLATFORM_POWER_POLICY PowerPolicy; NBPtr = MemMainPtr->NBPtr; mmSharedPtr = MemMainPtr->mmSharedPtr; ParameterPtr = MemMainPtr->MemPtr->ParameterListPtr; PowerPolicy = MemMainPtr->MemPtr->PlatFormConfig->PlatformProfile.PlatformPowerPolicy; IDS_OPTION_HOOK (IDS_MEMORY_POWER_POLICY, &PowerPolicy, &NBPtr->MemPtr->StdHeader); IDS_HDT_CONSOLE (MEM_FLOW, (PowerPolicy == Performance) ? "\nMaximize Performance\n" : "\nMaximize Battery Life\n"); if (ParameterPtr->DDR3Voltage != VOLT_INITIAL) { mmSharedPtr->VoltageMap = VDDIO_DETERMINED; PutEventLog (AGESA_WARNING, MEM_WARNING_INITIAL_DDR3VOLT_NONZERO, 0, 0, 0, 0, &(NBPtr[BSP_DIE].MemPtr->StdHeader)); SetMemError (AGESA_WARNING, NBPtr[BSP_DIE].MCTPtr); IDS_HDT_CONSOLE (MEM_FLOW, "Warning: Initial Value for VDDIO has been changed.\n"); RetVal = TRUE; } else { RetVal = MemMLvDdr3 (MemMainPtr); VDDIO = ParameterPtr->DDR3Voltage; if (NBPtr->IsSupported[PerformanceOnly] || ((PowerPolicy == Performance) && (mmSharedPtr->VoltageMap != 0))) { // When there is no commonly supported voltage, do not optimize performance // For cases where we can maximize performance, do the following // When VDDIO is enforced, DDR3Voltage will be overriden by specific VDDIO // So cases with DDR3Voltage left to be VOLT_UNSUPPORTED will be open to maximizing performance. ParameterPtr->DDR3Voltage = VOLT_UNSUPPORTED; } IDS_OPTION_HOOK (IDS_ENFORCE_VDDIO, &(ParameterPtr->DDR3Voltage), &NBPtr->MemPtr->StdHeader); if (ParameterPtr->DDR3Voltage != VOLT_UNSUPPORTED) { // When Voltage is already determined, do not have further process to choose maximum frequency to optimize performance mmSharedPtr->VoltageMap = VDDIO_DETERMINED; IDS_HDT_CONSOLE (MEM_FLOW, "VDDIO is determined. No further optimization will be done.\n"); } else { for (Node = 0; Node < MemMainPtr->DieCount; Node++) { NBPtr[Node].MaxFreqVDDIO[VOLT1_5_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; NBPtr[Node].MaxFreqVDDIO[VOLT1_35_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; NBPtr[Node].MaxFreqVDDIO[VOLT1_25_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; } // Reprogram the leveling result as temporal candidate ParameterPtr->DDR3Voltage = VDDIO; } } ASSERT (ParameterPtr->DDR3Voltage != VOLT_UNSUPPORTED); return RetVal; }
uint16_t ReallocHandle(uint32_t handle, uint32_t logicalSize) { auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); auto& info = iter->second; if (info.locked) return SetMemError(MacOS::memLockedErr); uint32_t mcptr = 0; if (logicalSize) { // todo -- purge & retry on failure. void *address = mplite_malloc(&pool, logicalSize); if (!address) return SetMemError(MacOS::memFullErr); mcptr = (uint8_t *)address - Memory; } // the handle is not altered in the event of an error. if (info.address) { void *address = Memory + info.address; mplite_free(&pool, address); } info.address = mcptr; info.size = logicalSize; memoryWriteLong(mcptr, handle); // lock? clear purged flag? return 0; }
uint16_t HGetState(uint16_t trap) { /* * on entry: * A0 Handle * * on exit: * D0 flag byte * */ unsigned flags = 0; uint32_t hh = cpuGetAReg(0); Log("%04x HGetState(%08x)\n", trap, hh); auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); /* * flag bits: * 0-4: reserved * 5: is a resource * 6: set if purgeable * 7: set if locked */ const auto &info = iter->second; // resouce not yet supported... // would need extra field and support in RM:: when // creating. // see HSetRBit, HClrRBit if (info.resource) flags |= (1 << 5); if (info.purgeable) flags |= (1 << 6); if (info.locked) flags |= (1 << 7); SetMemError(0); return flags; }
uint16_t TempFreeMem(void) { // FUNCTION TempFreeMem: LongInt; Log(" TempFreeMem()\n"); ToolReturn<4>(-1, mplite_freemem(&pool)); return SetMemError(0); }
uint16_t DisposeHandle(uint32_t handle) { auto iter = HandleMap.find(handle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); HandleInfo info = iter->second; HandleMap.erase(iter); if (info.address) { uint8_t *ptr = info.address + Memory; mplite_free(&pool, ptr); } HandleQueue.push_back(handle); return SetMemError(0); }
uint16_t NewPtr(uint32_t size, bool clear, uint32_t &mcptr) { // native pointers. mcptr = 0; //if (size == 0) return 0; uint8_t *ptr = nullptr; ptr = (uint8_t *)mplite_malloc(&pool, size ? size : 1); if (!ptr) { return SetMemError(MacOS::memFullErr); } if (clear) std::memset(ptr, 0, size); mcptr = ptr - Memory; PtrMap.emplace(std::make_pair(mcptr, size)); return SetMemError(0); }
uint16_t HUnlock(uint16_t trap) { /* * on entry: * A0 Handle * * on exit: * D0 Result code * */ uint32_t hh = cpuGetAReg(0); Log("%04x HUnlock(%08x)\n", trap, hh); auto iter = HandleMap.find(hh); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); iter->second.locked = false; return SetMemError(0); }
uint16_t MoveHHi(uint16_t trap) { /* * on entry: * A0: Handle to move * * on exit: * D0: Result code. * */ uint32_t theHandle = cpuGetAReg(0); Log("%04x MoveHHi(%08x)\n", trap, theHandle); // check if it's valid. auto iter = HandleMap.find(theHandle); if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); return SetMemError(0); }
uint16_t ReserveMem(uint16_t trap) { /* * on entry: * D0: cbNeeded (long word) * * on exit: * D0: Result code. * */ uint32_t cbNeeded = cpuGetDReg(0); uint32_t available; Log("%04x ReserveMem($%08x)\n", trap, cbNeeded); available = mplite_maxmem(&pool); // TODO -- if available < cbNeeded, purge handle and retry? if (available < cbNeeded) return SetMemError(MacOS::memFullErr); return SetMemError(0); }