Example #1
0
File: mm.cpp Project: iKarith/mpw
	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;
	}
Example #2
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #3
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #4
0
File: mm.cpp Project: iKarith/mpw
	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;
	}
Example #5
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #6
0
File: mm.cpp Project: iKarith/mpw
	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;
	}
Example #7
0
File: mm.cpp Project: iKarith/mpw
	/*
	 * 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
	}
Example #8
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #9
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #10
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #11
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #12
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;
  }
}
Example #13
0
/**
 *
 *  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;
}
Example #14
0
/**
 *
 *     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;
  }
}
Example #15
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #16
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;
  }
}
Example #17
0
/**
 *
 *     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;
  }
}
Example #18
0
File: mm.cpp Project: iKarith/mpw
	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.
	}
Example #19
0
/**
 *
 *     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;
  }
}
Example #20
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #21
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #22
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;
}
Example #23
0
File: mm.cpp Project: iKarith/mpw
		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;

		}
Example #24
0
File: mm.cpp Project: iKarith/mpw
	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;
	}
Example #25
0
File: mm.cpp Project: iKarith/mpw
	uint16_t TempFreeMem(void)
	{

		// FUNCTION TempFreeMem: LongInt;

		Log("     TempFreeMem()\n");

		ToolReturn<4>(-1, mplite_freemem(&pool));

		return SetMemError(0);
	}
Example #26
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #27
0
File: mm.cpp Project: iKarith/mpw
		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);
		}
Example #28
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #29
0
File: mm.cpp Project: iKarith/mpw
	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);
	}
Example #30
0
File: mm.cpp Project: iKarith/mpw
	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);
	}