diff options
author | Thi Tran <thi@us.ibm.com> | 2014-06-11 11:36:37 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-06-30 20:18:29 -0500 |
commit | 6280a104a07a5d7d78efb971b822307b2f786fe1 (patch) | |
tree | 57e0ff8fa70ecff00818a47485dbd75194b9be3f /src/usr/hwpf/hwp/start_payload | |
parent | 282ae28559bddf466d21c40ae75faaaacf1785c9 (diff) | |
download | talos-hostboot-6280a104a07a5d7d78efb971b822307b2f786fe1.tar.gz talos-hostboot-6280a104a07a5d7d78efb971b822307b2f786fe1.zip |
Load PAYLOAD from FFS partition.
Change-Id: Ib4f3b0631a9afb92fd5950b1636b8a3077684dbc
Origin: Google Shared Technology
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/11553
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/start_payload')
-rw-r--r-- | src/usr/hwpf/hwp/start_payload/start_payload.C | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C index 96cde5a1b..249d30808 100644 --- a/src/usr/hwpf/hwp/start_payload/start_payload.C +++ b/src/usr/hwpf/hwp/start_payload/start_payload.C @@ -5,7 +5,10 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] Google Inc. */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -55,6 +58,7 @@ #include <hwpf/hwp/occ/occ.H> #include <sys/mm.h> #include <devicefw/userif.H> +#include <util/misc.H> #include <initservice/isteps_trace.H> #include <hwpisteperror.H> @@ -77,6 +81,9 @@ #include <intr/interrupt.H> #include <kernel/ipc.H> // for internode data areas #include <mbox/ipc_msg_types.H> +#include <pnor/pnorif.H> +#include <sys/mm.h> +#include <algorithm> // Uncomment these files as they become available: // #include "host_start_payload/host_start_payload.H" @@ -89,7 +96,6 @@ using namespace fapi; using namespace ISTEP; using namespace ISTEP_ERROR; - /** * @brief This function will call the Initservice interface to shutdown * Hostboot. This function will call shutdown, passing in system @@ -507,6 +513,77 @@ void* call_host_start_payload( void *io_pArgs ) return l_StepError.getErrorHandle(); } +static void simics_load_payload(uint64_t addr) __attribute__((noinline)); +static void simics_load_payload(uint64_t addr) +{ + MAGIC_INSTRUCTION(MAGIC_LOAD_PAYLOAD); +} + +static errlHndl_t load_pnor_section(PNOR::SectionId i_section, + uint64_t i_physAddr) +{ + // Get the section info from PNOR. + PNOR::SectionInfo_t pnorSectionInfo; + errlHndl_t err = PNOR::getSectionInfo( i_section, + pnorSectionInfo ); + if( err != NULL ) + { + return err; + } + const uint32_t payloadSize = pnorSectionInfo.size; + + printk( "Loading PNOR section %d (%s) %d bytes @0x%lx\n", + i_section, + pnorSectionInfo.name, + payloadSize, + i_physAddr ); + + // Use simics optimization if we are running under simics which has very + // slow PNOR access. + if ( Util::isSimicsRunning() ) + { + simics_load_payload( i_physAddr ); + } + else + { + // Map in the physical memory we are loading into. + uint64_t loadAddr = reinterpret_cast<uint64_t>( + mm_block_map( reinterpret_cast<void*>( i_physAddr ), + payloadSize ) ); + + // Print out inital progress bar. +#ifdef CONFIG_CONSOLE + const int progressSteps = 80; + int progress = 0; + for ( int i = 0; i < progressSteps; ++i ) + { + printk( "." ); + } + printk( "\r" ); +#endif + + // Load the data block by block and update the progress bar. + const uint32_t BLOCK_SIZE = 4096; + for ( uint32_t i = 0; i < payloadSize; i += BLOCK_SIZE ) + { + memcpy( reinterpret_cast<void*>( loadAddr + i ), + reinterpret_cast<void*>( pnorSectionInfo.vaddr + i ), + std::min( payloadSize - i, BLOCK_SIZE ) ); +#ifdef CONFIG_CONSOLE + for ( int new_progress = (i * progressSteps) / payloadSize; + progress <= new_progress; progress++ ) + { + printk( "=" ); + } +#endif + } +#ifdef CONFIG_CONSOLE + printk( "\n" ); +#endif + } + + return NULL; +} // // Call shutdown @@ -607,6 +684,8 @@ errlHndl_t callShutdown ( uint64_t i_masterInstance, // SP Base Services not enabled if( is_sapphire_load() && (!INITSERVICE::spBaseServicesEnabled())) { + err = load_pnor_section( PNOR::PAYLOAD, payloadBase ); + if ( err ) { break; } payloadData = DEVTREE::get_flatdevtree_phys_addr(); } } |