diff options
author | Marty Gloff <mgloff@us.ibm.com> | 2015-12-17 16:18:46 -0600 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2016-03-03 22:03:29 -0500 |
commit | bcafb757808072be63d2ec0c2e61bca63bcf866e (patch) | |
tree | 1a59ace2ec084b9f7e287cd59c051d626e107daf /src/bootloader/bootloader.C | |
parent | 97f5d0db8ff37ebfd16220b368aea5f5b2da0c10 (diff) | |
download | talos-hostboot-bcafb757808072be63d2ec0c2e61bca63bcf866e.tar.gz talos-hostboot-bcafb757808072be63d2ec0c2e61bca63bcf866e.zip |
Deliver bootloader to fsp and pnor
Minimal load application -- Create the main bootloader application that
drives the load, verification, and relocation of the HBB image and that
branches execution to the beginning of the HBB memory.
Bootloader Stack Space -- Implement option of allocating stack space in main
store apart from the bootloader image so as to not use up image space and to
allow sufficient stack space.
Deliver the HBBL (HostBoot BootLoader) image out to FIPS.
Create an HBBL partition in the PNOR.
Change-Id: I659f19428a8588c4b9bea13338efd46c70caaf43
RTC:137932
Depends-on:I740f6f8a707760756a261535e62e2d0a849324f8
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/809
Tested-by: Jenkins Server
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/bootloader/bootloader.C')
-rw-r--r-- | src/bootloader/bootloader.C | 220 |
1 files changed, 191 insertions, 29 deletions
diff --git a/src/bootloader/bootloader.C b/src/bootloader/bootloader.C index 462217d76..8f63ae925 100644 --- a/src/bootloader/bootloader.C +++ b/src/bootloader/bootloader.C @@ -22,63 +22,225 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +#define __BOOT_LOADER_C + #include <stdint.h> #include <bootloader/bootloader.H> -#include <util/singleton.H> -#include <kernel/cpu.H> +#include <bootloader/bootloader_trace.H> +#include <bootloader/bl_pnorAccess.H> -#include <kernel/intmsghandler.H> // @TODO RTC:133821 might not be needed long-term +#include <lpc_const.H> +#include <pnor_utils.H> -#include <usr/pnor/ecc.H> +#include <ecc.H> #include <stdlib.h> extern uint64_t kernel_other_thread_spinlock; -extern uint32_t data_sandbox[16]; // @TODO RTC:133821 temporary bringup +extern PNOR::SectionData_t bootloader_hbbSection; namespace Bootloader{ + /** + * @brief Pointer to bootloader scratch space + * + * Pointer to location in main storage which bootloader uses as + * scratch space + */ + uint8_t *g_blScratchSpace; + + /** Apply Secure Signature Validation function. + * + * @note Currently just a stub. + */ + void applySecureSignatureValidation() + { + // (just an empty stub function for now) @TODO RTC:143902 + } + + + /** Bootloader main function to work with and start HBB. + * + * @return 0. + * + * @note Should branch to HBB and never return. + */ extern "C" int main() { - // cppBootstrap(); @TODO RTC:133821 might not be needed long-term - // cv_blScratchSpace = ??? @TODO RTC:133821 + // Initialization + bootloader_trace_index = 0; + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_START); + g_blScratchSpace = reinterpret_cast<uint8_t*>(HBBL_SCRATCH_SPACE_ADDR); - // @TODO RTC:134064 Get location of HB base code in PNOR from TOC + // Set variables needed for getting location of HB base code + // @TODO RTC:138268 Support multiple sides of PNOR in bootloader + uint64_t l_pnorStart = LPC::LPC_PHYS_BASE + LPC::LPCHC_FW_SPACE + + PNOR::LPC_SFC_MMIO_OFFSET; + uint32_t l_errCode = PNOR::NO_ERROR; + uint8_t l_tocUsed = 0; - // @TODO RTC:133821 Copy HB base code from PNOR to 0x200000 + // Get location of HB base code in PNOR from TOC + // @TODO RTC:138268 Support multiple sides of PNOR in bootloader + bl_pnorAccess::getHBBSection(l_pnorStart, + bootloader_hbbSection, + l_errCode, + l_tocUsed); + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_GETHBBSECTION_RTN ); - // Remove ECC from HB base code at 0x200000 and store result at 0x300000 - PNOR::ECC::eccStatus rc = PNOR::ECC::CLEAN; -// PNOR::ECC::removeECC(reinterpret_cast<uint8_t*>(0x200000), -// reinterpret_cast<uint8_t*>(0x300000), -// 0x100000); // @TODO RTC:133821 determine size - - if (rc != PNOR::ECC::UNCORRECTABLE) + if(PNOR::NO_ERROR == l_errCode) { -// memcpy(reinterpret_cast<void*>(0x300000), -// reinterpret_cast<void*>(0), -// 0x100000); // @TODO RTC:133821 determine size // replace with asm cache inhibited instructions - } + // get hbbFlashOffset + uint64_t l_hbbFlashOffset = bootloader_hbbSection.flashAddr; + // get hbbLength without size of ECC data + uint32_t l_hbbLength = bootloader_hbbSection.size; + // get hbbEcc + bool l_hbbEcc = + ( bootloader_hbbSection.integrity == FFS_INTEG_ECC_PROTECT); + // set hbbSbeHeaderSize @TODO RTC:137480 subject to future removal + uint64_t l_hbbSbeHeaderSize = (l_hbbEcc) + ? (0x18 * LENGTH_W_ECC) / LENGTH_WO_ECC + : 0x18; + + // Copy HB base code from PNOR to working location + handleMMIO(l_pnorStart + l_hbbFlashOffset + l_hbbSbeHeaderSize, + (l_hbbEcc) ? HBB_ECC_WORKING_ADDR : HBB_WORKING_ADDR, + (l_hbbEcc) ? (l_hbbLength * LENGTH_W_ECC)/LENGTH_WO_ECC + : l_hbbLength, + BYTESIZE); + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_WORKING_HANDLEMMIO_RTN); - // Ready to let the other CPUs go. @TODO RTC:133821 actually need to start relocated HB base code - lwsync(); - kernel_other_thread_spinlock = 1; + PNOR::ECC::eccStatus rc = PNOR::ECC::CLEAN; + if(l_hbbEcc) + { + // Remove ECC from HB base code at in working location and + // store result in new working location + rc = PNOR::ECC::removeECC( + reinterpret_cast<uint8_t*>(HBB_ECC_WORKING_ADDR | + IGNORE_HRMOR_MASK), + reinterpret_cast<uint8_t*>(HBB_WORKING_ADDR | + IGNORE_HRMOR_MASK), + l_hbbLength); + if (rc != PNOR::ECC::CLEAN) + { + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_REMOVEECC_RTN); + } + else if (rc != PNOR::ECC::CORRECTED) + { + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_REMOVEECC_CORRECTED); + } + } - data_sandbox[8] = 0x12345678; // @TODO RTC:133821 temporary bringup + if (rc != PNOR::ECC::UNCORRECTABLE) + { + // Apply secure signature validation @TODO RTC:143902 + applySecureSignatureValidation(); + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_APPLYSECSIGVAL_RTN); - MAGIC_INSTRUCTION(MAGIC_BREAK); // @TODO RTC:133821 temporary bringup + // Copy HBB image into address where it executes + uint64_t *l_src_addr = + reinterpret_cast<uint64_t*>(HBB_WORKING_ADDR | + IGNORE_HRMOR_MASK); + uint64_t *l_dest_addr = + reinterpret_cast<uint64_t*>(HBB_RUNNING_ADDR | + IGNORE_HRMOR_MASK); + for(uint32_t i = 0; + i < l_hbbLength / sizeof(uint64_t); + i++) + { + l_dest_addr[i] = l_src_addr[i]; + } + BOOTLOADER_TRACE(BTLDR_TRC_MAIN_COPY_HBB_DONE); + + // Start executing HBB + enterHBB(HBB_HRMOR, HBB_RUNNING_OFFSET); + } + else + { + BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_MAIN_REMOVEECC_FAIL); + } + } + else + { + BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_MAIN_GETHBBSECTION_FAIL); + } - while(1); // @TODO - task_end_stub(); // @TODO return 0; } + + /** Handle MMIO to copy code/data from location to another. + * + * @param[in] i_srcAddr - The source location. + * @param[in] i_destAddr - The destination location. + * @param[in] i_size - The size of the code/data. + * @param[in] i_ld_st_size - The size of each load/store operation. + * + * @return void. + */ void handleMMIO(uint64_t i_srcAddr, uint64_t i_destAddr, uint32_t i_size, MMIOLoadStoreSizes i_ld_st_size) { - // @TODO RTC:133821 + BOOTLOADER_TRACE(BTLDR_TRC_HANDLEMMIO_START); + + // Set base addresses, Ignore HRMOR setting + uint64_t l_srcAddr_base = i_srcAddr | IGNORE_HRMOR_MASK; + uint64_t l_destAddr_base = i_destAddr | IGNORE_HRMOR_MASK; + + uint32_t l_targetGPR = 0; + + for(uint32_t i = 0; + i < i_size; + i += i_ld_st_size) + { + // Set addresses + uint64_t l_srcAddr = l_srcAddr_base + i; + uint64_t l_destAddr = l_destAddr_base + i; + + if(i_ld_st_size == BYTESIZE) + { + // Cache-inhibited load byte from hypervisor state. + // lbzcix BOP1,Ref_G0,BOP2 + asm volatile("lbzcix %0, 0, %1" + : "=r" (l_targetGPR) // output, %0 + : "r" (l_srcAddr) // input, %1 + : ); // no impacts + + // Cache-inhibited store byte. + // stbcix BOP1,Ref_G0,BOP2 + asm volatile("stbcix %0,0,%1" + :: "r" (l_targetGPR) , "r" (l_destAddr)); + } + else if(i_ld_st_size == WORDSIZE) + { + // Cache-inhibited load word from hypervisor state. + // lwzcix BOP1,Ref_G0,BOP2 + asm volatile("lwzcix %0, 0, %1" + : "=r" (l_targetGPR) // output, %0 + : "r" (l_srcAddr) // input, %1 + : ); // no impacts + + // Cache-inhibited store word. + // stwcix BOP1,Ref_G0,BOP2 + asm volatile("stwcix %0,0,%1" + :: "r" (l_targetGPR) , "r" (l_destAddr)); + } + else + { + // Cache-inhibited load double word from hypervisor state. + // ldcix BOP1,Ref_G0,BOP2 + asm volatile("ldcix %0, 0, %1" + : "=r" (l_targetGPR) // output, %0 + : "r" (l_srcAddr) // input, %1 + : ); // no impacts + + // Cache-inhibited store double word. + // stdcix BOP1,Ref_G0,BOP2 + asm volatile("stdcix %0,0,%1" + :: "r" (l_targetGPR) , "r" (l_destAddr)); + } + } } } // end namespace Bootloader - |