| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * mnreg.c |
| * |
| * Common Northbridge register access functions |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: (Mem/NB/) |
| * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ |
| * |
| **/ |
| /***************************************************************************** |
| * |
| * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * *************************************************************************** |
| * |
| */ |
| /* |
| *---------------------------------------------------------------------------- |
| * MODULES USED |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| |
| |
| #include "AGESA.h" |
| #include "AdvancedApi.h" |
| #include "amdlib.h" |
| #include "Ids.h" |
| #include "mm.h" |
| #include "mn.h" |
| #include "merrhdl.h" |
| #include "heapManager.h" |
| #include "Filecode.h" |
| #include "GeneralServices.h" |
| CODE_GROUP (G1_PEICC) |
| RDATA_GROUP (G1_PEICC) |
| |
| #define FILECODE PROC_MEM_NB_MNREG_FILECODE |
| |
| |
| /*---------------------------------------------------------------------------- |
| * DEFINITIONS AND MACROS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------- |
| * TYPEDEFS AND STRUCTURES |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------- |
| * PROTOTYPES OF LOCAL FUNCTIONS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------- |
| * EXPORTED FUNCTIONS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function sets the current DCT to work on. |
| * Should be called before accessing a certain DCT |
| * All data structures will be updated to point to the current DCT |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] Dct - ID of the target DCT |
| * |
| */ |
| |
| VOID |
| MemNSwitchDCTNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN UINT8 Dct |
| ) |
| { |
| ASSERT (NBPtr->DctCount > Dct); |
| // |
| // Set the DctCfgSel to new DCT |
| // |
| NBPtr->FamilySpecificHook[DCTSelectSwitch] (NBPtr, &Dct); |
| NBPtr->Dct = Dct; |
| NBPtr->MCTPtr->Dct = NBPtr->Dct; |
| NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); |
| NBPtr->PsPtr = &(NBPtr->PSBlock[NBPtr->Dct]); |
| NBPtr->DctCachePtr = &(NBPtr->DctCache[NBPtr->Dct]); |
| |
| MemNSwitchChannelNb (NBPtr, NBPtr->Channel); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * This function is used by families that use a separate DctCfgSel bit to |
| * select the current DCT which will be accessed by function 2. |
| * NOTE: This function must be called BEFORE the NBPtr->Dct variable is |
| * updated. |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] *Dct - Pointer to ID of the target DCT |
| * |
| */ |
| |
| BOOLEAN |
| MemNDctCfgSelectUnb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN VOID *Dct |
| ) |
| { |
| // |
| // Sanity check the current DctCfgSel setting |
| // |
| ASSERT (NBPtr->Dct == NBPtr->GetBitField (NBPtr, BFDctCfgSel)); |
| // |
| // Set the DctCfgSel to new DCT |
| // |
| NBPtr->SetBitField (NBPtr, BFDctCfgSel, *(UINT8*)Dct); |
| |
| return TRUE; |
| } |
| |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function sets the current channel to work on. |
| * Should be called before accessing a certain channel |
| * All data structures will be updated to point to the current channel |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] Channel - ID of the target channel |
| * |
| */ |
| |
| VOID |
| MemNSwitchChannelNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN UINT8 Channel |
| ) |
| { |
| NBPtr->Channel = Channel ? 1 : 0; |
| NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function gets a bit field from PCI register |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Field name |
| * |
| * @return Bit field value |
| */ |
| |
| UINT32 |
| MemNGetBitFieldNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName |
| ) |
| { |
| UINT32 Value; |
| |
| Value = NBPtr->MemNCmnGetSetFieldNb (NBPtr, 0, FieldName, 0); |
| return Value; |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function sets a bit field from PCI register |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Field name |
| * @param[in] Field - Value to be stored in PCT register |
| * |
| */ |
| |
| VOID |
| MemNSetBitFieldNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName, |
| IN UINT32 Field |
| ) |
| { |
| NBPtr->MemNCmnGetSetFieldNb (NBPtr, 1, FieldName, Field); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * Check if bitfields of all enabled DCTs on a die have the expected value. Ignore |
| * DCTs that are disabled. |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Bit Field name |
| * @param[in] Field - Value to be checked |
| * |
| * @return TRUE - All enabled DCTs have the expected value on the bitfield. |
| * @return FALSE - Not all enabled DCTs have the expected value on the bitfield. |
| * |
| * ---------------------------------------------------------------------------- |
| */ |
| BOOLEAN |
| MemNBrdcstCheckNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName, |
| IN UINT32 Field |
| ) |
| { |
| UINT8 Dct; |
| UINT8 CurrentDCT; |
| Dct = NBPtr->Dct; |
| for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { |
| MemNSwitchDCTNb (NBPtr, CurrentDCT); |
| if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) { |
| if (MemNGetBitFieldNb (NBPtr, FieldName) != Field) { |
| MemNSwitchDCTNb (NBPtr, Dct); |
| return FALSE; |
| } |
| } |
| } |
| MemNSwitchDCTNb (NBPtr, Dct); |
| return TRUE; |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * Set bitfields of all enabled DCTs on a die to a value. Ignore |
| * DCTs that are disabled. |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Bit Field name |
| * @param[in] Field - Value to be set |
| * |
| * ---------------------------------------------------------------------------- |
| */ |
| VOID |
| MemNBrdcstSetNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName, |
| IN UINT32 Field |
| ) |
| { |
| UINT8 Dct; |
| UINT8 CurrentDCT; |
| Dct = NBPtr->Dct; |
| for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { |
| MemNSwitchDCTNb (NBPtr, CurrentDCT); |
| if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) { |
| MemNSetBitFieldNb (NBPtr, FieldName, Field); |
| } |
| } |
| MemNSwitchDCTNb (NBPtr, Dct); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * Set bitfields of all DCTs regardless of if they are being enabled or not on a |
| * die to a value. |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Bit Field name |
| * @param[in] Field - Value to be set |
| * |
| * ---------------------------------------------------------------------------- |
| */ |
| VOID |
| MemNBrdcstSetUnConditionalNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName, |
| IN UINT32 Field |
| ) |
| { |
| UINT8 Dct; |
| UINT8 CurrentDCT; |
| Dct = NBPtr->Dct; |
| for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { |
| MemNSwitchDCTNb (NBPtr, CurrentDCT); |
| MemNSetBitFieldNb (NBPtr, FieldName, Field); |
| } |
| MemNSwitchDCTNb (NBPtr, Dct); |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * This function calculates the memory channel index relative to the |
| * socket, taking the Die number, the Dct, and the channel. |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] Dct |
| * @param[in] Channel |
| * |
| */ |
| UINT8 |
| MemNGetSocketRelativeChannelNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN UINT8 Dct, |
| IN UINT8 Channel |
| ) |
| { |
| return ((NBPtr->MCTPtr->DieId * NBPtr->DctCount) + Dct); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * Poll a bitfield. If the bitfield does not get set to the target value within |
| * specified microseconds, it times out. |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] FieldName - Bit Field name |
| * @param[in] Field - Value to be set |
| * @param[in] MicroSecond - Number of microsecond to wait |
| * @param[in] IfBroadCast - Need to broadcast to both DCT or not |
| * |
| * ---------------------------------------------------------------------------- |
| */ |
| VOID |
| MemNPollBitFieldNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN BIT_FIELD_NAME FieldName, |
| IN UINT32 Field, |
| IN UINT32 MicroSecond, |
| IN BOOLEAN IfBroadCast |
| ) |
| { |
| BOOLEAN ErrorRecovery; |
| BOOLEAN IgnoreErr; |
| UINT8 ExcludeDCT; |
| UINT16 ExcludeChipSelMask; |
| UINT32 EventInfo; |
| UINT64 InitTSC; |
| UINT64 CurrentTSC; |
| UINT64 TimeOut; |
| AGESA_STATUS EventClass; |
| MEM_DATA_STRUCT *MemPtr; |
| DIE_STRUCT *MCTPtr; |
| BOOLEAN TimeoutEn; |
| |
| MemPtr = NBPtr->MemPtr; |
| MCTPtr = NBPtr->MCTPtr; |
| ExcludeDCT = EXCLUDE_ALL_DCT; |
| ExcludeChipSelMask = EXCLUDE_ALL_CHIPSEL; |
| TimeoutEn = TRUE; |
| IDS_TIMEOUT_CTL (&TimeoutEn); |
| |
| CurrentTSC = 0; |
| LibAmdMsrRead (TSC, &InitTSC, &MemPtr->StdHeader); |
| TimeOut = InitTSC + ((UINT64) MicroSecond * MemPtr->TscRate); |
| |
| while ((CurrentTSC < TimeOut) || !TimeoutEn) { |
| if (IfBroadCast) { |
| if (NBPtr->BrdcstCheck (NBPtr, FieldName, Field)) { |
| break; |
| } |
| } else { |
| if (MemNGetBitFieldNb (NBPtr, FieldName) == Field) { |
| break; |
| } |
| } |
| LibAmdMsrRead (TSC, &CurrentTSC, &MemPtr->StdHeader); |
| } |
| |
| if ((CurrentTSC >= TimeOut) && TimeoutEn) { |
| ErrorRecovery = TRUE; |
| IgnoreErr = FALSE; |
| IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, &MemPtr->StdHeader); |
| IDS_OPTION_HOOK (IDS_MEM_IGNORE_ERROR, &IgnoreErr, &MemPtr->StdHeader); |
| |
| // Default event class |
| // If different event class is needed in one entry, override it. |
| EventClass = AGESA_ERROR; |
| switch (FieldName) { |
| case BFDramEnabled: |
| EventInfo = MEM_ERROR_DRAM_ENABLED_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tDramEnabled bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFDctAccessDone: |
| EventInfo = MEM_ERROR_DCT_ACCESS_DONE_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tDctAccessDone bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFSendCtrlWord: |
| EventInfo = MEM_ERROR_SEND_CTRL_WORD_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tSendCtrlWord bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFPrefDramTrainMode: |
| EventInfo = MEM_ERROR_PREF_DRAM_TRAIN_MODE_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tPrefDramTrainMode bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFEnterSelfRef: |
| EventInfo = MEM_ERROR_ENTER_SELF_REF_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tEnterSelfRef bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFFreqChgInProg: |
| EventInfo = MEM_ERROR_FREQ_CHG_IN_PROG_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tFreqChgInProg bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFExitSelfRef: |
| EventInfo = MEM_ERROR_EXIT_SELF_REF_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tExitSelfRef bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFSendMrsCmd: |
| EventInfo = MEM_ERROR_SEND_MRS_CMD_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tSendMrsCmd bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFSendZQCmd: |
| EventInfo = MEM_ERROR_SEND_ZQ_CMD_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tSendZQCmd bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFDctExtraAccessDone: |
| EventInfo = MEM_ERROR_DCT_EXTRA_ACCESS_DONE_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tDctExtraAccessDone bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFMemClrBusy: |
| EventInfo = MEM_ERROR_MEM_CLR_BUSY_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClrBusy bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFMemCleared: |
| EventInfo = MEM_ERROR_MEM_CLEARED_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tMemCleared bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFFlushWr: |
| EventInfo = MEM_ERROR_FLUSH_WR_TIME_OUT; |
| ExcludeDCT = NBPtr->Dct; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tFlushWr bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| case BFCurNbPstate: |
| EventInfo = MEM_ERROR_NBPSTATE_TRANSITION_TIME_OUT; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\tCurNBPstate bitfield times out.\n"); |
| ASSERT (ErrorRecovery || IgnoreErr); |
| break; |
| default: |
| EventClass = 0; |
| EventInfo = 0; |
| IDS_ERROR_TRAP; |
| } |
| |
| PutEventLog (EventClass, EventInfo, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &MemPtr->StdHeader); |
| SetMemError (EventClass, MCTPtr); |
| if (!MemPtr->ErrorHandling (MCTPtr, ExcludeDCT, ExcludeChipSelMask, &MemPtr->StdHeader)) { |
| ASSERT (FALSE); |
| } |
| } |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function changes memory Pstate context |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] MemPstate - Target Memory Pstate |
| * |
| * @return TRUE |
| * ---------------------------------------------------------------------------- |
| */ |
| VOID |
| MemNChangeMemPStateContextNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN MEM_PSTATE MemPstate |
| ) |
| { |
| UINT8 PSMasterChannel; |
| UINT8 Dct; |
| |
| ASSERT ((MemPstate == 0) || (MemPstate == 1)); |
| ASSERT (NBPtr->MemPstate == ((MemNGetBitFieldNb (NBPtr, BFMemPsSel) == 0) ? MEMORY_PSTATE0 : MEMORY_PSTATE1)); |
| |
| IDS_HDT_CONSOLE (MEM_SETREG, "\nGo to Memory Pstate Conext %d\n", MemPstate); |
| Dct = NBPtr->Dct; |
| MemNSwitchDCTNb (NBPtr, 0); |
| // Figure out what is the master channel |
| PSMasterChannel = (UINT8) (MemNGetBitFieldNb (NBPtr, BFPhyPSMasterChannel) >> 8); |
| |
| // Switch to the master channel to change PStateToAccess |
| // PStateToAccess is only effective on the master channel |
| MemNSwitchDCTNb (NBPtr, PSMasterChannel); |
| MemNSetBitFieldNb (NBPtr, BFMemPsSel, MemPstate); |
| MemNSetBitFieldNb (NBPtr, BFPStateToAccess, MemPstate << 8); |
| |
| NBPtr->MemPstate = (MemPstate == 0) ? MEMORY_PSTATE0 : MEMORY_PSTATE1; |
| MemNSwitchDCTNb (NBPtr, Dct); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * This function allocates buffer for NB register table |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * @param[in] Handle - Handle for heap allocation for NBRegTable |
| * |
| * @return TRUE - Successfully allocates buffer the first time |
| * @return FALSE - Buffer already allocated or fails to allocate |
| */ |
| |
| BOOLEAN |
| MemNAllocateNBRegTableNb ( |
| IN OUT MEM_NB_BLOCK *NBPtr, |
| IN NB_REG_TAB_HANDLE Handle |
| ) |
| { |
| ALLOCATE_HEAP_PARAMS AllocHeapParams; |
| LOCATE_HEAP_PTR LocHeap; |
| |
| // If NBRegTable for this family exists, use it |
| LocHeap.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Handle, 0, 0); |
| if (HeapLocateBuffer (&LocHeap, &(NBPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) { |
| NBPtr->NBRegTable = (TSEFO *) LocHeap.BufferPtr; |
| return FALSE; |
| } |
| |
| // Allocate new buffer for NBRegTable if it has not been allocated |
| AllocHeapParams.RequestedBufferSize = sizeof (TSEFO) * BFEndOfList; |
| AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Handle, 0, 0); |
| AllocHeapParams.Persist = HEAP_SYSTEM_MEM; |
| if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &(NBPtr->MemPtr->StdHeader))) { |
| ASSERT(FALSE); // NB and Tech Block Heap allocate error |
| return FALSE; |
| } |
| NBPtr->NBRegTable = (TSEFO *)AllocHeapParams.BufferPtr; |
| return TRUE; |
| } |