diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2017-09-22 13:15:22 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-09-22 22:54:27 -0400 |
commit | a702bf170b58a8be92fb66bae6c9f0bff23a4cce (patch) | |
tree | f30303f32df971793b8048c383af6ca24d4aec00 /src/usr | |
parent | 1b0f94cf15432ae3a42fa896332e0e55993ca094 (diff) | |
download | talos-hostboot-a702bf170b58a8be92fb66bae6c9f0bff23a4cce.tar.gz talos-hostboot-a702bf170b58a8be92fb66bae6c9f0bff23a4cce.zip |
Use a VMM allocator for the giant WOFDATA lid
The WOFDATA lid is now 12MB which is too big for our default
malloc logic that requires contiguous memory. Instead we will
use a custom VMM block to page in new pages dynamically as
needed.
Change-Id: I50360812328d6811716955b7a22c396566044a87
CQ: SW402766
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46640
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/fapi2/plat_wof_access.C | 146 |
1 files changed, 145 insertions, 1 deletions
diff --git a/src/usr/fapi2/plat_wof_access.C b/src/usr/fapi2/plat_wof_access.C index 66b2fb024..6db703d5e 100644 --- a/src/usr/fapi2/plat_wof_access.C +++ b/src/usr/fapi2/plat_wof_access.C @@ -37,6 +37,8 @@ #include <util/utillidmgr.H> #include <p9_pstates_common.h> #include <initservice/initserviceif.H> +#include <sys/mm.h> +#include <errl/errlmanager.H> namespace fapi2 { @@ -50,6 +52,12 @@ const uint32_t RES_VERSION_MASK = 0xFF; const uint32_t WOF_IMAGE_VERSION = 1; const uint32_t WOF_TABLES_VERSION = 1; +#ifndef __HOSTBOOT_RUNTIME +// Remember that we have already allocated the VMM space for +// the WOFDATA lid +static void* g_wofdataVMM = nullptr; +#endif + /* WOF Tables In PNOR @@ -170,9 +178,84 @@ fapi2::ReturnCode platParseWOFTables(uint8_t* o_wofData) break; } - // Allocate space, remember to free it later + FAPI_INF("WOFDATA lid is %d bytes", l_lidImageSize); + +#ifdef __HOSTBOOT_RUNTIME + // Locally allocate space for the lid l_pWofImage = static_cast<void*>(malloc(l_lidImageSize)); +#else + // Use a special VMM block to avoid the requirement for + // contiguous memory + int l_mm_rc = 0; + if( !g_wofdataVMM ) + { + l_mm_rc = mm_alloc_block( nullptr, + reinterpret_cast<void*>(VMM_VADDR_WOFDATA_LID), + VMM_SIZE_WOFDATA_LID ); + if(l_mm_rc != 0) + { + FAPI_INF("Fail from mm_alloc_block for WOFDATA, rc=%d", l_mm_rc); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_MM_ALLOC_BLOCK_FAILED + * @userdata1 Address being allocated + * @userdata2[00:31] Size of block allocation + * @userdata2[32:63] rc from mm_alloc_block + * @devdesc Error calling mm_alloc_block for WOFDATA + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_MM_ALLOC_BLOCK_FAILED, + VMM_VADDR_WOFDATA_LID, + TWO_UINT32_TO_UINT64(VMM_SIZE_WOFDATA_LID, + l_mm_rc), + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + g_wofdataVMM = reinterpret_cast<void*>(VMM_VADDR_WOFDATA_LID); + } + + l_mm_rc = mm_set_permission( + reinterpret_cast<void*>(VMM_VADDR_WOFDATA_LID), + l_lidImageSize, + WRITABLE | ALLOCATE_FROM_ZERO ); + if(l_mm_rc != 0) + { + FAPI_INF("Fail from mm_set_permission for WOFDATA, rc=%d", l_mm_rc); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_MM_SET_PERMISSION_FAILED + * @userdata1 Address being changed + * @userdata2[00:31] Size of change + * @userdata2[32:63] rc from mm_set_permission + * @devdesc Error calling mm_set_permission for WOFDATA + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_MM_SET_PERMISSION_FAILED, + VMM_VADDR_WOFDATA_LID, + TWO_UINT32_TO_UINT64(VMM_SIZE_WOFDATA_LID, + l_mm_rc), + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Point my local pointer at the VMM space we allocated + l_pWofImage = g_wofdataVMM; + +#endif + + // Get the tables from pnor or lid l_errl = l_wofLidMgr.getLid(l_pWofImage, l_lidImageSize); if(l_errl) @@ -427,7 +510,68 @@ fapi2::ReturnCode platParseWOFTables(uint8_t* o_wofData) // Free the wof tables memory if(l_pWofImage != nullptr) { +#ifdef __HOSTBOOT_RUNTIME free(l_pWofImage); + l_pWofImage = nullptr; + +#else + errlHndl_t l_tmpErr = nullptr; + // Release the memory we may still have allocated and set the + // permissions to prevent further access to it + int l_mm_rc = mm_remove_pages(RELEASE, + l_pWofImage, + VMM_SIZE_WOFDATA_LID); + if( l_mm_rc ) + { + FAPI_INF("Fail from mm_remove_pages for WOFDATA, rc=%d", l_mm_rc); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_MM_REMOVE_PAGES_FAILED + * @userdata1 Address being removed + * @userdata2[00:31] Size of removal + * @userdata2[32:63] rc from mm_remove_pages + * @devdesc Error calling mm_remove_pages for WOFDATA + * @custdesc Firmware Error + */ + l_tmpErr = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_MM_REMOVE_PAGES_FAILED, + reinterpret_cast<uint64_t>(l_pWofImage), + TWO_UINT32_TO_UINT64(VMM_SIZE_WOFDATA_LID, + l_mm_rc), + true); //software callout + errlCommit(l_tmpErr,FAPI2_COMP_ID); + } + l_mm_rc = mm_set_permission(l_pWofImage, + VMM_SIZE_WOFDATA_LID, + NO_ACCESS | ALLOCATE_FROM_ZERO ); + if( l_mm_rc ) + { + FAPI_INF("Fail from mm_set_permission reset for WOFDATA, rc=%d", l_mm_rc); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_MM_SET_PERMISSION2_FAILED + * @userdata1 Address being changed + * @userdata2[00:31] Size of change + * @userdata2[32:63] rc from mm_set_permission + * @devdesc Error calling mm_set_permission for WOFDATA + * @custdesc Firmware Error + */ + l_tmpErr = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_MM_SET_PERMISSION2_FAILED, + reinterpret_cast<uint64_t>(l_pWofImage), + TWO_UINT32_TO_UINT64(VMM_SIZE_WOFDATA_LID, + l_mm_rc), + true); //software callout + errlCommit(l_tmpErr,FAPI2_COMP_ID); + } +#endif + } FAPI_DBG("Exiting platParseWOFTables ...."); |